cbfstool: Use buffer over offset/size pair for cbfs_copy_instance
This allows adding support for FMAP based cbfstool copy more easily. BUG=chromium:445938 Change-Id: I72e7bc4da7d27853e324400f76f86136e3d8726e Signed-off-by: Patrick Georgi <pgeorgi@google.com> Reviewed-on: https://review.coreboot.org/12787 Tested-by: build bot (Jenkins)
This commit is contained in:
parent
cbb6c75061
commit
214e4af102
|
@ -387,8 +387,7 @@ int cbfs_image_from_buffer(struct cbfs_image *out, struct buffer *in,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cbfs_copy_instance(struct cbfs_image *image, size_t copy_offset,
|
int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst)
|
||||||
size_t copy_size)
|
|
||||||
{
|
{
|
||||||
assert(image);
|
assert(image);
|
||||||
if (!cbfs_is_legacy_cbfs(image))
|
if (!cbfs_is_legacy_cbfs(image))
|
||||||
|
@ -399,37 +398,23 @@ int cbfs_copy_instance(struct cbfs_image *image, size_t copy_offset,
|
||||||
size_t align, entry_offset;
|
size_t align, entry_offset;
|
||||||
ssize_t last_entry_size;
|
ssize_t last_entry_size;
|
||||||
|
|
||||||
size_t cbfs_offset, cbfs_end;
|
size_t copy_end = buffer_size(dst);
|
||||||
size_t copy_end = copy_offset + copy_size;
|
|
||||||
|
|
||||||
align = image->header.align;
|
align = image->header.align;
|
||||||
|
|
||||||
cbfs_offset = image->header.offset;
|
|
||||||
cbfs_end = image->header.romsize;
|
|
||||||
|
|
||||||
if (copy_end > image->buffer.size) {
|
|
||||||
ERROR("Copy offset out of range: [%zx:%zx)\n",
|
|
||||||
copy_offset, copy_end);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Range check requested copy region with source cbfs. */
|
|
||||||
if ((copy_offset >= cbfs_offset && copy_offset < cbfs_end) ||
|
|
||||||
(copy_end >= cbfs_offset && copy_end <= cbfs_end)) {
|
|
||||||
ERROR("New image would overlap old one.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This will work, let's create a copy. */
|
/* This will work, let's create a copy. */
|
||||||
copy_header = (struct cbfs_header *)(image->buffer.data + copy_offset);
|
copy_header = (struct cbfs_header *)buffer_get(dst);
|
||||||
cbfs_put_header(copy_header, &image->header);
|
cbfs_put_header(copy_header, &image->header);
|
||||||
|
|
||||||
copy_header->bootblocksize = 0;
|
copy_header->bootblocksize = 0;
|
||||||
/* Romsize is a misnomer. It's the absolute limit of cbfs content.*/
|
/* FIXME: romsize and offset have a full-flash interpretation even
|
||||||
copy_header->romsize = htonl(copy_end);
|
* though they don't need to and should be region-relative (where
|
||||||
entry_offset = align_up(copy_offset + sizeof(*copy_header), align);
|
* region is sufficiently specified by the master header pointer.
|
||||||
copy_header->offset = htonl(entry_offset);
|
* But that's for a later change. */
|
||||||
dst_entry = (struct cbfs_file *)(image->buffer.data + entry_offset);
|
copy_header->romsize = htonl(dst->offset + buffer_size(dst));
|
||||||
|
entry_offset = align_up(sizeof(*copy_header), align);
|
||||||
|
copy_header->offset = htonl(dst->offset + entry_offset);
|
||||||
|
dst_entry = (struct cbfs_file *)(buffer_get(dst) + entry_offset);
|
||||||
|
|
||||||
/* Copy non-empty files */
|
/* Copy non-empty files */
|
||||||
for (src_entry = cbfs_find_first_entry(image);
|
for (src_entry = cbfs_find_first_entry(image);
|
||||||
|
@ -446,7 +431,7 @@ int cbfs_copy_instance(struct cbfs_image *image, size_t copy_offset,
|
||||||
dst_entry = (struct cbfs_file *)(
|
dst_entry = (struct cbfs_file *)(
|
||||||
(uintptr_t)dst_entry + align_up(entry_size, align));
|
(uintptr_t)dst_entry + align_up(entry_size, align));
|
||||||
|
|
||||||
if ((size_t)((char *)dst_entry - image->buffer.data) >=
|
if ((size_t)((void *)dst_entry - buffer_get(dst)) >=
|
||||||
copy_end) {
|
copy_end) {
|
||||||
ERROR("Ran out of room in copy region.\n");
|
ERROR("Ran out of room in copy region.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -454,7 +439,7 @@ int cbfs_copy_instance(struct cbfs_image *image, size_t copy_offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last entry size is all the room above it. */
|
/* Last entry size is all the room above it. */
|
||||||
last_entry_size = copy_end - ((char *)dst_entry - image->buffer.data)
|
last_entry_size = copy_end - ((void *)dst_entry - buffer_get(dst))
|
||||||
- cbfs_calculate_file_header_size("");
|
- cbfs_calculate_file_header_size("");
|
||||||
|
|
||||||
if (last_entry_size < 0)
|
if (last_entry_size < 0)
|
||||||
|
|
|
@ -74,8 +74,7 @@ int cbfs_image_from_buffer(struct cbfs_image *out, struct buffer *in,
|
||||||
|
|
||||||
/* Create a duplicate CBFS image. Returns 0 on success, otherwise non-zero.
|
/* Create a duplicate CBFS image. Returns 0 on success, otherwise non-zero.
|
||||||
* Will not succeed on new-style images without a master header. */
|
* Will not succeed on new-style images without a master header. */
|
||||||
int cbfs_copy_instance(struct cbfs_image *image, size_t copy_offset,
|
int cbfs_copy_instance(struct cbfs_image *image, struct buffer *dst);
|
||||||
size_t copy_size);
|
|
||||||
|
|
||||||
/* Releases the CBFS image. Returns 0 on success, otherwise non-zero. */
|
/* Releases the CBFS image. Returns 0 on success, otherwise non-zero. */
|
||||||
int cbfs_image_delete(struct cbfs_image *image);
|
int cbfs_image_delete(struct cbfs_image *image);
|
||||||
|
|
|
@ -917,6 +917,16 @@ static int cbfs_update_fit(void)
|
||||||
|
|
||||||
static int cbfs_copy(void)
|
static int cbfs_copy(void)
|
||||||
{
|
{
|
||||||
|
/* always a valid source region */
|
||||||
|
struct cbfs_image src_image;
|
||||||
|
|
||||||
|
if (cbfs_image_from_buffer(&src_image, param.image_region,
|
||||||
|
param.headeroffset))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
struct buffer dst_buffer;
|
||||||
|
|
||||||
|
if (cbfs_is_legacy_cbfs(&src_image)) {
|
||||||
if (!param.copyoffset_assigned) {
|
if (!param.copyoffset_assigned) {
|
||||||
ERROR("You need to specify -D/--copy-offset.\n");
|
ERROR("You need to specify -D/--copy-offset.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -927,17 +937,14 @@ static int cbfs_copy(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cbfs_image image;
|
buffer_splice(&dst_buffer, param.image_region,
|
||||||
if (cbfs_image_from_buffer(&image, param.image_region,
|
param.copyoffset, param.size);
|
||||||
param.headeroffset))
|
} else {
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!cbfs_is_legacy_cbfs(&image)) {
|
|
||||||
ERROR("This operation is only valid on legacy images having CBFS master headers\n");
|
ERROR("This operation is only valid on legacy images having CBFS master headers\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cbfs_copy_instance(&image, param.copyoffset, param.size);
|
return cbfs_copy_instance(&src_image, &dst_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct command commands[] = {
|
static const struct command commands[] = {
|
||||||
|
|
Loading…
Reference in New Issue