2020-05-08 19:28:13 +02:00
|
|
|
/* cbfstool, CLI utility for CBFS file manipulation */
|
util/: Replace GPLv2 boiler plate with SPDX header
Used commands:
perl -i -p0e 's|\/\*[\s*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-only */|' $(cat filelist)
perl -i -p0e 's|This[\s*]*program[\s*]*is[\s*]*free[\s*]*software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*either[\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License,[\s*]*or[\s*]*.at[\s*]*your[\s*]*option.*[\s*]*any[\s*]*later[\s*]*version.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-or-later */|' $(cat filelist)
perl -i -p0e 's|\/\*[\s*]*.*This[\s*#]*program[\s*#]*is[\s*#]*free[\s*#]*software[;:,][\s*#]*you[\s*#]*can[\s*#]*redistribute[\s*#]*it[\s*#]*and/or[\s*#]*modify[\s*#]*it[\s*#]*under[\s*#]*the[\s*#]*terms[\s*#]*of[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*as[\s*#]*published[\s*#]*by[\s*#]*the[\s*#]*Free[\s*#]*Software[\s*#]*Foundation[;:,][\s*#]*either[\s*#]*version[\s*#]*3[\s*#]*of[\s*#]*the[\s*#]*License[;:,][\s*#]*or[\s*#]*.at[\s*#]*your[\s*#]*option.*[\s*#]*any[\s*#]*later[\s*#]*version.[\s*#]*This[\s*#]*program[\s*#]*is[\s*#]*distributed[\s*#]*in[\s*#]*the[\s*#]*hope[\s*#]*that[\s*#]*it[\s*#]*will[\s*#]*be[\s*#]*useful[;:,][\s*#]*but[\s*#]*WITHOUT[\s*#]*ANY[\s*#]*WARRANTY[;:,][\s*#]*without[\s*#]*even[\s*#]*the[\s*#]*implied[\s*#]*warranty[\s*#]*of[\s*#]*MERCHANTABILITY[\s*#]*or[\s*#]*FITNESS[\s*#]*FOR[\s*#]*A[\s*#]*PARTICULAR[\s*#]*PURPOSE.[\s*#]*See[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*for[\s*#]*more[\s*#]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-3.0-or-later */|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w]*.*is free software[:;][\#\s]*you[\#\s]*can[\#\s]*redistribute[\#\s]*it[\#\s]*and\/or[\#\s]*modify[\#\s]*it[\s\#]*under[\s \#]*the[\s\#]*terms[\s\#]*of[\s\#]*the[\s\#]*GNU[\s\#]*General[\s\#]*Public[\s\#]*License[\s\#]*as[\s\#]*published[\s\#]*by[\s\#]*the[\s\#]*Free[\s\#]*Software[\s\#]*Foundation[;,][\s\#]*version[\s\#]*2[\s\#]*of[\s\#]*the[\s\#]*License.*[\s\#]*This[\s\#]*program[\s\#]*is[\s\#]*distributed[\s\#]*in[\s\#]*the[\s\#]*hope[\s\#]*that[\s\#]*it[\s\#]*will[\#\s]*be[\#\s]*useful,[\#\s]*but[\#\s]*WITHOUT[\#\s]*ANY[\#\s]*WARRANTY;[\#\s]*without[\#\s]*even[\#\s]*the[\#\s]*implied[\#\s]*warranty[\#\s]*of[\#\s]*MERCHANTABILITY[\#\s]*or[\#\s]*FITNESS[\#\s]*FOR[\#\s]*A[\#\s]*PARTICULAR[\#\s]*PURPOSE.[\#\s]*See[\#\s]*the[\#\s]*GNU[\#\s]*General[\#\s]*Public[\#\s]*License[\#\s]*for[\#\s]*more[\#\s]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
Change-Id: I1008a63b804f355a916221ac994701d7584f60ff
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Signed-off-by: Elyes HAOUAS <ehaouas@noos.fr>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41177
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-05-08 20:48:04 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2009-03-31 13:57:36 +02:00
|
|
|
|
2009-09-14 15:29:27 +02:00
|
|
|
#include <stdio.h>
|
2011-10-21 23:24:57 +02:00
|
|
|
#include <stdlib.h>
|
2009-12-21 16:09:01 +01:00
|
|
|
#include <string.h>
|
2015-03-06 00:38:03 +01:00
|
|
|
#include <strings.h>
|
2011-10-21 23:24:57 +02:00
|
|
|
#include <ctype.h>
|
2012-10-30 00:52:36 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <getopt.h>
|
2009-09-14 15:29:27 +02:00
|
|
|
#include "common.h"
|
|
|
|
#include "cbfs.h"
|
2013-01-28 19:15:49 +01:00
|
|
|
#include "cbfs_image.h"
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
#include "cbfs_sections.h"
|
2017-12-18 22:50:22 +01:00
|
|
|
#include "elfparsing.h"
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
#include "partitioned_file.h"
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
#include "lz4/lib/xxhash.h"
|
2020-05-07 02:27:02 +02:00
|
|
|
#include <commonlib/bsd/cbfs_private.h>
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
#include <commonlib/bsd/compression.h>
|
2020-05-07 02:27:02 +02:00
|
|
|
#include <commonlib/bsd/metadata_hash.h>
|
2016-05-09 21:23:01 +02:00
|
|
|
#include <commonlib/fsp.h>
|
2017-01-17 13:01:25 +01:00
|
|
|
#include <commonlib/endian.h>
|
2018-05-29 11:18:14 +02:00
|
|
|
#include <commonlib/helpers.h>
|
2020-11-21 07:51:17 +01:00
|
|
|
#include <commonlib/region.h>
|
2020-03-14 00:43:34 +01:00
|
|
|
#include <vboot_host.h>
|
2009-03-31 13:57:36 +02:00
|
|
|
|
2009-09-22 17:58:19 +02:00
|
|
|
struct command {
|
|
|
|
const char *name;
|
2012-10-30 00:52:36 +01:00
|
|
|
const char *optstring;
|
|
|
|
int (*function) (void);
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
// Whether to populate param.image_region before invoking function
|
|
|
|
bool accesses_region;
|
2015-12-09 18:39:31 +01:00
|
|
|
// This set to true means two things:
|
|
|
|
// - in case of a command operating on a region, the region's contents
|
|
|
|
// will be written back to image_file at the end
|
|
|
|
// - write access to the file is required
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
bool modifies_region;
|
2009-09-22 17:58:19 +02:00
|
|
|
};
|
|
|
|
|
2013-01-28 07:23:49 +01:00
|
|
|
static struct param {
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
partitioned_file_t *image_file;
|
|
|
|
struct buffer *image_region;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
const char *name;
|
|
|
|
const char *filename;
|
|
|
|
const char *fmap;
|
|
|
|
const char *region_name;
|
2015-11-20 21:48:18 +01:00
|
|
|
const char *source_region;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
const char *bootblock;
|
|
|
|
const char *ignore_section;
|
2018-06-04 19:32:46 +02:00
|
|
|
const char *ucode_region;
|
2013-07-09 19:39:13 +02:00
|
|
|
uint64_t u64val;
|
2013-01-28 07:23:49 +01:00
|
|
|
uint32_t type;
|
|
|
|
uint32_t baseaddress;
|
2020-11-21 01:52:03 +01:00
|
|
|
/*
|
|
|
|
* Input can be negative. It will be transformed to offset from start of region (if
|
|
|
|
* negative) and stored in baseaddress.
|
|
|
|
*/
|
|
|
|
long long int baseaddress_input;
|
2013-01-29 02:45:12 +01:00
|
|
|
uint32_t baseaddress_assigned;
|
2013-01-28 07:23:49 +01:00
|
|
|
uint32_t loadaddress;
|
2013-01-29 02:45:12 +01:00
|
|
|
uint32_t headeroffset;
|
2020-11-21 01:52:03 +01:00
|
|
|
/*
|
|
|
|
* Input can be negative. It will be transformed to offset from start of region (if
|
|
|
|
* negative) and stored in baseaddress.
|
|
|
|
*/
|
|
|
|
long long int headeroffset_input;
|
2013-01-29 02:45:12 +01:00
|
|
|
uint32_t headeroffset_assigned;
|
2013-01-28 07:23:49 +01:00
|
|
|
uint32_t entrypoint;
|
|
|
|
uint32_t size;
|
|
|
|
uint32_t alignment;
|
2013-03-19 05:17:12 +01:00
|
|
|
uint32_t pagesize;
|
2014-11-10 22:14:24 +01:00
|
|
|
uint32_t cbfsoffset;
|
2020-11-21 01:52:03 +01:00
|
|
|
/*
|
|
|
|
* Input can be negative. It will be transformed to corresponding region offset (if
|
|
|
|
* negative) and stored in baseaddress.
|
|
|
|
*/
|
|
|
|
long long int cbfsoffset_input;
|
2014-11-10 22:14:24 +01:00
|
|
|
uint32_t cbfsoffset_assigned;
|
2014-02-03 05:37:28 +01:00
|
|
|
uint32_t arch;
|
2017-10-31 01:38:04 +01:00
|
|
|
uint32_t padding;
|
2018-05-29 11:18:14 +02:00
|
|
|
uint32_t topswap_size;
|
2016-12-12 18:38:01 +01:00
|
|
|
bool u64val_assigned;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
bool fill_partial_upward;
|
|
|
|
bool fill_partial_downward;
|
|
|
|
bool show_immutable;
|
2015-09-16 00:00:23 +02:00
|
|
|
bool stage_xip;
|
2020-05-28 22:12:02 +02:00
|
|
|
bool force_pow2_pagesize;
|
2016-01-14 13:22:37 +01:00
|
|
|
bool autogen_attr;
|
2016-01-26 22:35:34 +01:00
|
|
|
bool machine_parseable;
|
2018-08-09 11:49:52 +02:00
|
|
|
bool unprocessed;
|
2018-11-20 13:54:49 +01:00
|
|
|
bool ibb;
|
2020-03-14 00:43:34 +01:00
|
|
|
enum cbfs_compression compression;
|
2017-01-11 18:38:11 +01:00
|
|
|
int precompression;
|
2015-10-01 15:54:04 +02:00
|
|
|
enum vb2_hash_algorithm hash;
|
2018-10-11 11:01:30 +02:00
|
|
|
/* For linux payloads */
|
2013-08-27 20:22:21 +02:00
|
|
|
char *initrd;
|
|
|
|
char *cmdline;
|
2016-10-12 16:46:13 +02:00
|
|
|
int force;
|
2020-11-21 19:35:10 +01:00
|
|
|
/*
|
|
|
|
* Base and size of extended window for decoding SPI flash greater than 16MiB in host
|
|
|
|
* address space on x86 platforms. The assumptions here are:
|
|
|
|
* 1. Top 16MiB is still decoded in the fixed decode window just below 4G boundary.
|
|
|
|
* 2. Rest of the SPI flash below the top 16MiB is mapped at the top of extended
|
|
|
|
* window. Even though the platform might support a larger extended window, the SPI
|
|
|
|
* flash part used by the mainboard might not be large enough to be mapped in the entire
|
|
|
|
* window. In such cases, the mapping is assumed to be in the top part of the extended
|
|
|
|
* window with the bottom part remaining unused.
|
|
|
|
*/
|
|
|
|
uint32_t ext_win_base;
|
|
|
|
uint32_t ext_win_size;
|
2013-01-28 07:23:49 +01:00
|
|
|
} param = {
|
|
|
|
/* All variables not listed are initialized as zero. */
|
2014-02-03 05:37:28 +01:00
|
|
|
.arch = CBFS_ARCHITECTURE_UNKNOWN,
|
2015-05-08 06:00:05 +02:00
|
|
|
.compression = CBFS_COMPRESS_NONE,
|
2015-10-01 15:54:04 +02:00
|
|
|
.hash = VB2_HASH_INVALID,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
.headeroffset = ~0,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
.region_name = SECTION_NAME_PRIMARY_CBFS,
|
2016-12-06 18:55:26 +01:00
|
|
|
.u64val = -1,
|
2013-01-28 07:23:49 +01:00
|
|
|
};
|
2012-10-30 00:52:36 +01:00
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
/*
|
|
|
|
* This "metadata_hash cache" caches the value and location of the CBFS metadata
|
|
|
|
* hash embedded in the bootblock when CBFS verification is enabled. The first
|
|
|
|
* call to get_mh_cache() searches for the cache by scanning the whole bootblock
|
|
|
|
* for its 8-byte signature, later calls will just return the previously found
|
|
|
|
* information again. If the cbfs_hash.algo member in the result is
|
|
|
|
* VB2_HASH_INVALID, that means no metadata hash was found and this image does
|
|
|
|
* not use CBFS verification.
|
|
|
|
*/
|
|
|
|
struct mh_cache {
|
|
|
|
const char *region;
|
|
|
|
size_t offset;
|
|
|
|
struct vb2_hash cbfs_hash;
|
2020-03-20 05:09:35 +01:00
|
|
|
platform_fixup_func fixup;
|
2020-05-07 02:27:02 +02:00
|
|
|
bool initialized;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct mh_cache *get_mh_cache(void)
|
|
|
|
{
|
|
|
|
static struct mh_cache mhc;
|
|
|
|
|
|
|
|
if (mhc.initialized)
|
|
|
|
return &mhc;
|
|
|
|
|
|
|
|
mhc.initialized = true;
|
|
|
|
|
|
|
|
const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
|
|
|
|
if (!fmap)
|
|
|
|
goto no_metadata_hash;
|
|
|
|
|
|
|
|
/* Find the bootblock. If there is a "BOOTBLOCK" FMAP section, it's
|
|
|
|
there. If not, it's a normal file in the primary CBFS section. */
|
|
|
|
size_t offset, size;
|
|
|
|
struct buffer buffer;
|
|
|
|
if (fmap_find_area(fmap, SECTION_NAME_BOOTBLOCK)) {
|
|
|
|
if (!partitioned_file_read_region(&buffer, param.image_file,
|
|
|
|
SECTION_NAME_BOOTBLOCK))
|
|
|
|
goto no_metadata_hash;
|
|
|
|
mhc.region = SECTION_NAME_BOOTBLOCK;
|
|
|
|
offset = 0;
|
|
|
|
size = buffer.size;
|
|
|
|
} else {
|
|
|
|
struct cbfs_image cbfs;
|
|
|
|
struct cbfs_file *bootblock;
|
|
|
|
if (!partitioned_file_read_region(&buffer, param.image_file,
|
|
|
|
SECTION_NAME_PRIMARY_CBFS))
|
|
|
|
goto no_metadata_hash;
|
|
|
|
mhc.region = SECTION_NAME_PRIMARY_CBFS;
|
|
|
|
if (cbfs_image_from_buffer(&cbfs, &buffer, param.headeroffset))
|
|
|
|
goto no_metadata_hash;
|
|
|
|
bootblock = cbfs_get_entry(&cbfs, "bootblock");
|
|
|
|
if (!bootblock || ntohl(bootblock->type) != CBFS_TYPE_BOOTBLOCK)
|
|
|
|
goto no_metadata_hash;
|
|
|
|
offset = (void *)bootblock + ntohl(bootblock->offset) -
|
|
|
|
buffer_get(&cbfs.buffer);
|
|
|
|
size = ntohl(bootblock->len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find and validate the metadata hash anchor inside the bootblock and
|
|
|
|
record its exact byte offset from the start of the FMAP region. */
|
|
|
|
struct metadata_hash_anchor *anchor = memmem(buffer_get(&buffer) + offset,
|
|
|
|
size, METADATA_HASH_ANCHOR_MAGIC, sizeof(anchor->magic));
|
|
|
|
if (anchor) {
|
|
|
|
if (!vb2_digest_size(anchor->cbfs_hash.algo)) {
|
|
|
|
ERROR("Unknown CBFS metadata hash type: %d\n",
|
|
|
|
anchor->cbfs_hash.algo);
|
|
|
|
goto no_metadata_hash;
|
|
|
|
}
|
|
|
|
mhc.cbfs_hash = anchor->cbfs_hash;
|
|
|
|
mhc.offset = (void *)anchor - buffer_get(&buffer);
|
2020-03-20 05:09:35 +01:00
|
|
|
mhc.fixup = platform_fixups_probe(&buffer, mhc.offset,
|
|
|
|
mhc.region);
|
2020-05-07 02:27:02 +02:00
|
|
|
return &mhc;
|
|
|
|
}
|
|
|
|
|
|
|
|
no_metadata_hash:
|
|
|
|
mhc.cbfs_hash.algo = VB2_HASH_INVALID;
|
|
|
|
return &mhc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void update_and_info(const char *name, void *dst, void *src, size_t size)
|
|
|
|
{
|
|
|
|
if (!memcmp(dst, src, size))
|
|
|
|
return;
|
|
|
|
char *src_str = bintohex(src, size);
|
|
|
|
char *dst_str = bintohex(dst, size);
|
|
|
|
INFO("Updating %s from %s to %s\n", name, dst_str, src_str);
|
|
|
|
memcpy(dst, src, size);
|
|
|
|
free(src_str);
|
|
|
|
free(dst_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int update_anchor(struct mh_cache *mhc, uint8_t *fmap_hash)
|
|
|
|
{
|
|
|
|
struct buffer buffer;
|
|
|
|
if (!partitioned_file_read_region(&buffer, param.image_file,
|
|
|
|
mhc->region))
|
|
|
|
return -1;
|
|
|
|
struct metadata_hash_anchor *anchor = buffer_get(&buffer) + mhc->offset;
|
|
|
|
/* The metadata hash anchor should always still be where we left it. */
|
|
|
|
assert(!memcmp(anchor->magic, METADATA_HASH_ANCHOR_MAGIC,
|
|
|
|
sizeof(anchor->magic)) &&
|
|
|
|
anchor->cbfs_hash.algo == mhc->cbfs_hash.algo);
|
|
|
|
update_and_info("CBFS metadata hash", anchor->cbfs_hash.raw,
|
|
|
|
mhc->cbfs_hash.raw, vb2_digest_size(anchor->cbfs_hash.algo));
|
|
|
|
if (fmap_hash) {
|
|
|
|
update_and_info("FMAP hash",
|
|
|
|
metadata_hash_anchor_fmap_hash(anchor), fmap_hash,
|
|
|
|
vb2_digest_size(anchor->cbfs_hash.algo));
|
|
|
|
}
|
2020-03-20 05:09:35 +01:00
|
|
|
if (mhc->fixup && mhc->fixup(&buffer, mhc->offset) != 0)
|
|
|
|
return -1;
|
2020-05-07 02:27:02 +02:00
|
|
|
if (!partitioned_file_write_region(param.image_file, &buffer))
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This should be called after every time CBFS metadata might have changed. It
|
|
|
|
will recalculate and update the metadata hash in the bootblock if needed. */
|
|
|
|
static int maybe_update_metadata_hash(struct cbfs_image *cbfs)
|
|
|
|
{
|
|
|
|
if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS))
|
|
|
|
return 0; /* Metadata hash only embedded in primary CBFS. */
|
|
|
|
|
|
|
|
struct mh_cache *mhc = get_mh_cache();
|
|
|
|
if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cb_err_t err = cbfs_walk(cbfs, NULL, NULL, &mhc->cbfs_hash,
|
|
|
|
CBFS_WALK_WRITEBACK_HASH);
|
|
|
|
if (err != CB_CBFS_NOT_FOUND) {
|
|
|
|
ERROR("Unexpected cbfs_walk() error %d\n", err);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return update_anchor(mhc, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This should be called after every time the FMAP or the bootblock itself might
|
|
|
|
have changed, and will write the new FMAP hash into the metadata hash anchor
|
|
|
|
in the bootblock if required (usually when the bootblock is first added). */
|
|
|
|
static int maybe_update_fmap_hash(void)
|
|
|
|
{
|
|
|
|
if (strcmp(param.region_name, SECTION_NAME_BOOTBLOCK) &&
|
|
|
|
strcmp(param.region_name, SECTION_NAME_FMAP) &&
|
|
|
|
param.type != CBFS_TYPE_BOOTBLOCK)
|
|
|
|
return 0; /* FMAP and bootblock didn't change. */
|
|
|
|
|
|
|
|
struct mh_cache *mhc = get_mh_cache();
|
|
|
|
if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
uint8_t fmap_hash[VB2_MAX_DIGEST_SIZE];
|
|
|
|
const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
|
|
|
|
if (!fmap || vb2_digest_buffer((const void *)fmap, fmap_size(fmap),
|
|
|
|
mhc->cbfs_hash.algo, fmap_hash, sizeof(fmap_hash)))
|
|
|
|
return -1;
|
|
|
|
return update_anchor(mhc, fmap_hash);
|
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
static bool region_is_flashmap(const char *region)
|
|
|
|
{
|
|
|
|
return partitioned_file_region_check_magic(param.image_file, region,
|
|
|
|
FMAP_SIGNATURE, strlen(FMAP_SIGNATURE));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* @return Same as cbfs_is_valid_cbfs(), but for a named region. */
|
|
|
|
static bool region_is_modern_cbfs(const char *region)
|
|
|
|
{
|
|
|
|
return partitioned_file_region_check_magic(param.image_file, region,
|
|
|
|
CBFS_FILE_MAGIC, strlen(CBFS_FILE_MAGIC));
|
|
|
|
}
|
|
|
|
|
2020-11-21 07:51:17 +01:00
|
|
|
/* This describes a window from the SPI flash address space into the host address space. */
|
|
|
|
struct mmap_window {
|
|
|
|
struct region flash_space;
|
|
|
|
struct region host_space;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum mmap_window_type {
|
|
|
|
X86_DEFAULT_DECODE_WINDOW, /* Decode window just below 4G boundary */
|
2020-11-21 19:35:10 +01:00
|
|
|
X86_EXTENDED_DECODE_WINDOW, /* Extended decode window for mapping greater than 16MiB
|
|
|
|
flash */
|
2020-11-21 07:51:17 +01:00
|
|
|
MMAP_MAX_WINDOWS,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Table of all the decode windows supported by the platform. */
|
|
|
|
static struct mmap_window mmap_window_table[MMAP_MAX_WINDOWS];
|
|
|
|
|
|
|
|
static void add_mmap_window(enum mmap_window_type idx, size_t flash_offset, size_t host_offset,
|
|
|
|
size_t window_size)
|
|
|
|
{
|
|
|
|
if (idx >= MMAP_MAX_WINDOWS) {
|
|
|
|
ERROR("Incorrect mmap window index(%d)\n", idx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mmap_window_table[idx].flash_space.offset = flash_offset;
|
|
|
|
mmap_window_table[idx].host_space.offset = host_offset;
|
|
|
|
mmap_window_table[idx].flash_space.size = window_size;
|
|
|
|
mmap_window_table[idx].host_space.size = window_size;
|
|
|
|
}
|
|
|
|
|
2020-11-21 19:35:10 +01:00
|
|
|
#define DEFAULT_DECODE_WINDOW_TOP (4ULL * GiB)
|
|
|
|
#define DEFAULT_DECODE_WINDOW_MAX_SIZE (16 * MiB)
|
|
|
|
|
|
|
|
static bool create_mmap_windows(void)
|
2020-11-21 07:51:17 +01:00
|
|
|
{
|
|
|
|
static bool done;
|
|
|
|
|
|
|
|
if (done)
|
2020-11-21 19:35:10 +01:00
|
|
|
return done;
|
2020-11-21 07:51:17 +01:00
|
|
|
|
|
|
|
const size_t image_size = partitioned_file_total_size(param.image_file);
|
2020-11-21 19:35:10 +01:00
|
|
|
const size_t std_window_size = MIN(DEFAULT_DECODE_WINDOW_MAX_SIZE, image_size);
|
|
|
|
const size_t std_window_flash_offset = image_size - std_window_size;
|
2020-11-21 07:51:17 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Default decode window lives just below 4G boundary in host space and maps up to a
|
|
|
|
* maximum of 16MiB. If the window is smaller than 16MiB, the SPI flash window is mapped
|
|
|
|
* at the top of the host window just below 4G.
|
|
|
|
*/
|
2020-11-21 19:35:10 +01:00
|
|
|
add_mmap_window(X86_DEFAULT_DECODE_WINDOW, std_window_flash_offset,
|
|
|
|
DEFAULT_DECODE_WINDOW_TOP - std_window_size, std_window_size);
|
|
|
|
|
|
|
|
if (param.ext_win_size && (image_size > DEFAULT_DECODE_WINDOW_MAX_SIZE)) {
|
|
|
|
/*
|
|
|
|
* If the platform supports extended window and the SPI flash size is greater
|
|
|
|
* than 16MiB, then create a mapping for the extended window as well.
|
|
|
|
* The assumptions here are:
|
|
|
|
* 1. Top 16MiB is still decoded in the fixed decode window just below 4G
|
|
|
|
* boundary.
|
|
|
|
* 2. Rest of the SPI flash below the top 16MiB is mapped at the top of extended
|
|
|
|
* window. Even though the platform might support a larger extended window, the
|
|
|
|
* SPI flash part used by the mainboard might not be large enough to be mapped
|
|
|
|
* in the entire window. In such cases, the mapping is assumed to be in the top
|
|
|
|
* part of the extended window with the bottom part remaining unused.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* ext_win_base = 0xF8000000
|
|
|
|
* ext_win_size = 32 * MiB
|
|
|
|
* ext_win_limit = ext_win_base + ext_win_size - 1 = 0xF9FFFFFF
|
|
|
|
*
|
|
|
|
* If SPI flash is 32MiB, then top 16MiB is mapped from 0xFF000000 - 0xFFFFFFFF
|
|
|
|
* whereas the bottom 16MiB is mapped from 0xF9000000 - 0xF9FFFFFF. The extended
|
|
|
|
* window 0xF8000000 - 0xF8FFFFFF remains unused.
|
|
|
|
*/
|
|
|
|
const size_t ext_window_mapped_size = MIN(param.ext_win_size,
|
|
|
|
image_size - std_window_size);
|
|
|
|
const size_t ext_window_top = param.ext_win_base + param.ext_win_size;
|
|
|
|
add_mmap_window(X86_EXTENDED_DECODE_WINDOW,
|
|
|
|
std_window_flash_offset - ext_window_mapped_size,
|
|
|
|
ext_window_top - ext_window_mapped_size,
|
|
|
|
ext_window_mapped_size);
|
|
|
|
|
|
|
|
if (region_overlap(&mmap_window_table[X86_EXTENDED_DECODE_WINDOW].host_space,
|
|
|
|
&mmap_window_table[X86_DEFAULT_DECODE_WINDOW].host_space)) {
|
|
|
|
const struct region *ext_region;
|
|
|
|
|
|
|
|
ext_region = &mmap_window_table[X86_EXTENDED_DECODE_WINDOW].host_space;
|
|
|
|
ERROR("Extended window(base=0x%zx, limit=0x%zx) overlaps with default window!\n",
|
|
|
|
region_offset(ext_region), region_end(ext_region));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2020-11-21 07:51:17 +01:00
|
|
|
|
|
|
|
done = true;
|
2020-11-21 19:35:10 +01:00
|
|
|
return done;
|
2020-11-21 07:51:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int convert_address(const struct region *to, const struct region *from,
|
|
|
|
unsigned int addr)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Calculate the offset in the "from" region and use that offset to calculate
|
|
|
|
* corresponding address in the "to" region.
|
|
|
|
*/
|
|
|
|
size_t offset = addr - region_offset(from);
|
|
|
|
return region_offset(to) + offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum mmap_addr_type {
|
|
|
|
HOST_SPACE_ADDR,
|
|
|
|
FLASH_SPACE_ADDR,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int find_mmap_window(enum mmap_addr_type addr_type, unsigned int addr)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(mmap_window_table); i++) {
|
|
|
|
const struct region *reg;
|
|
|
|
|
|
|
|
if (addr_type == HOST_SPACE_ADDR)
|
|
|
|
reg = &mmap_window_table[i].host_space;
|
|
|
|
else
|
|
|
|
reg = &mmap_window_table[i].flash_space;
|
|
|
|
|
2021-02-13 00:57:14 +01:00
|
|
|
if (region_offset(reg) <= addr &&
|
|
|
|
((uint64_t)region_offset(reg) + (uint64_t)region_sz(reg) - 1) >= addr)
|
2020-11-21 07:51:17 +01:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int convert_host_to_flash(const struct buffer *region, unsigned int addr)
|
|
|
|
{
|
|
|
|
int idx;
|
|
|
|
const struct region *to, *from;
|
|
|
|
|
|
|
|
idx = find_mmap_window(HOST_SPACE_ADDR, addr);
|
|
|
|
if (idx == -1) {
|
|
|
|
ERROR("Host address(%x) not in any mmap window!\n", addr);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
to = &mmap_window_table[idx].flash_space;
|
|
|
|
from = &mmap_window_table[idx].host_space;
|
|
|
|
|
|
|
|
/* region->offset is subtracted because caller expects offset in the given region. */
|
|
|
|
return convert_address(to, from, addr) - region->offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int convert_flash_to_host(const struct buffer *region, unsigned int addr)
|
|
|
|
{
|
|
|
|
int idx;
|
|
|
|
const struct region *to, *from;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* region->offset is added because caller provides offset in the given region. This is
|
|
|
|
* converted to an absolute address in the SPI flash space. This is done before the
|
|
|
|
* conversion as opposed to after in convert_host_to_flash() above because the address
|
|
|
|
* is actually an offset within the region. So, it needs to be converted into an
|
|
|
|
* absolute address in the SPI flash space before converting into an address in host
|
|
|
|
* space.
|
|
|
|
*/
|
|
|
|
addr += region->offset;
|
|
|
|
idx = find_mmap_window(FLASH_SPACE_ADDR, addr);
|
|
|
|
|
|
|
|
if (idx == -1) {
|
|
|
|
ERROR("SPI flash address(%x) not in any mmap window!\n", addr);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
to = &mmap_window_table[idx].host_space;
|
|
|
|
from = &mmap_window_table[idx].flash_space;
|
|
|
|
|
|
|
|
return convert_address(to, from, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int convert_addr_space(const struct buffer *region, unsigned int addr)
|
2016-05-04 23:07:15 +02:00
|
|
|
{
|
|
|
|
assert(region);
|
|
|
|
|
2020-11-21 19:35:10 +01:00
|
|
|
assert(create_mmap_windows());
|
2016-05-04 23:07:15 +02:00
|
|
|
|
2020-11-21 07:51:17 +01:00
|
|
|
if (IS_HOST_SPACE_ADDRESS(addr))
|
|
|
|
return convert_host_to_flash(region, addr);
|
|
|
|
else
|
|
|
|
return convert_flash_to_host(region, addr);
|
2016-05-04 23:07:15 +02:00
|
|
|
}
|
|
|
|
|
2015-05-07 11:39:22 +02:00
|
|
|
/*
|
2020-11-21 01:52:03 +01:00
|
|
|
* This function takes offset value which represents the offset from one end of the region and
|
|
|
|
* converts it to offset from the other end of the region. offset is expected to be positive.
|
|
|
|
*/
|
|
|
|
static int convert_region_offset(unsigned int offset, uint32_t *region_offset)
|
2015-05-07 11:39:22 +02:00
|
|
|
{
|
2020-11-21 01:52:03 +01:00
|
|
|
size_t size;
|
2015-05-07 11:39:22 +02:00
|
|
|
|
2020-11-21 01:52:03 +01:00
|
|
|
if (param.size) {
|
|
|
|
size = param.size;
|
|
|
|
} else {
|
|
|
|
assert(param.image_region);
|
|
|
|
size = param.image_region->size;
|
2015-12-07 23:14:07 +01:00
|
|
|
}
|
|
|
|
|
2020-11-21 01:52:03 +01:00
|
|
|
if (size < offset) {
|
|
|
|
ERROR("Cannot convert region offset (size=0x%zx, offset=0x%x)\n", size, offset);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*region_offset = size - offset;
|
|
|
|
return 0;
|
2015-05-07 11:39:22 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
static int do_cbfs_locate(uint32_t *cbfs_addr, size_t data_size)
|
2015-09-16 00:00:23 +02:00
|
|
|
{
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
uint32_t metadata_size = 0;
|
|
|
|
|
2015-09-16 00:00:23 +02:00
|
|
|
if (!param.name) {
|
|
|
|
ERROR("You need to specify -n/--name.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cbfs_image image;
|
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
|
|
|
param.headeroffset))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (cbfs_get_entry(&image, param.name))
|
|
|
|
WARN("'%s' already in CBFS.\n", param.name);
|
|
|
|
|
2017-12-18 22:50:22 +01:00
|
|
|
if (!data_size) {
|
2021-12-13 19:16:44 +01:00
|
|
|
ERROR("File '%s' is empty?\n", param.name);
|
|
|
|
return 1;
|
2015-09-16 00:00:23 +02:00
|
|
|
}
|
|
|
|
|
2021-06-16 17:16:05 +02:00
|
|
|
/* Compute required page size */
|
2020-05-28 22:12:02 +02:00
|
|
|
if (param.force_pow2_pagesize) {
|
2021-06-16 17:16:05 +02:00
|
|
|
param.pagesize = 1;
|
|
|
|
while (param.pagesize < data_size)
|
|
|
|
param.pagesize <<= 1;
|
2020-05-28 22:12:02 +02:00
|
|
|
DEBUG("Page size is %d (0x%x)\n", param.pagesize, param.pagesize);
|
|
|
|
}
|
|
|
|
|
2015-09-16 00:00:23 +02:00
|
|
|
/* Include cbfs_file size along with space for with name. */
|
|
|
|
metadata_size += cbfs_calculate_file_header_size(param.name);
|
2016-01-14 13:22:37 +01:00
|
|
|
/* Adjust metadata_size if additional attributes were added */
|
|
|
|
if (param.autogen_attr) {
|
|
|
|
if (param.alignment)
|
|
|
|
metadata_size += sizeof(struct cbfs_file_attr_align);
|
|
|
|
if (param.baseaddress_assigned || param.stage_xip)
|
|
|
|
metadata_size += sizeof(struct cbfs_file_attr_position);
|
|
|
|
}
|
2020-11-19 03:00:31 +01:00
|
|
|
if (param.precompression || param.compression != CBFS_COMPRESS_NONE)
|
|
|
|
metadata_size += sizeof(struct cbfs_file_attr_compression);
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.type == CBFS_TYPE_STAGE)
|
|
|
|
metadata_size += sizeof(struct cbfs_file_attr_stageheader);
|
2015-09-16 00:00:23 +02:00
|
|
|
|
2016-01-22 19:43:01 +01:00
|
|
|
/* Take care of the hash attribute if it is used */
|
|
|
|
if (param.hash != VB2_HASH_INVALID)
|
2020-03-14 00:43:34 +01:00
|
|
|
metadata_size += cbfs_file_attr_hash_size(param.hash);
|
2016-01-22 19:43:01 +01:00
|
|
|
|
2017-12-18 22:50:22 +01:00
|
|
|
int32_t address = cbfs_locate_entry(&image, data_size, param.pagesize,
|
2015-09-16 00:00:23 +02:00
|
|
|
param.alignment, metadata_size);
|
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
if (address < 0) {
|
2021-12-13 19:16:44 +01:00
|
|
|
ERROR("'%s'(%u + %zu) can't fit in CBFS for page-size %#x, align %#x.\n",
|
|
|
|
param.name, metadata_size, data_size, param.pagesize, param.alignment);
|
2015-09-16 00:00:23 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*cbfs_addr = address;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-08-11 15:16:24 +02:00
|
|
|
typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset,
|
2015-08-25 15:53:52 +02:00
|
|
|
struct cbfs_file *header);
|
2009-03-31 13:57:36 +02:00
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
static int cbfs_add_integer_component(const char *name,
|
2013-07-09 19:39:13 +02:00
|
|
|
uint64_t u64val,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
uint32_t offset,
|
|
|
|
uint32_t headeroffset) {
|
2013-07-09 19:39:13 +02:00
|
|
|
struct cbfs_image image;
|
2015-08-25 13:48:10 +02:00
|
|
|
struct cbfs_file *header = NULL;
|
2013-07-09 19:39:13 +02:00
|
|
|
struct buffer buffer;
|
|
|
|
int i, ret = 1;
|
|
|
|
|
|
|
|
if (!name) {
|
|
|
|
ERROR("You need to specify -n/--name.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buffer_create(&buffer, 8, name) != 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
buffer.data[i] = (u64val >> i*8) & 0xff;
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region, headeroffset)) {
|
|
|
|
ERROR("Selected image region is not a CBFS.\n");
|
|
|
|
goto done;
|
2013-07-09 19:39:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cbfs_get_entry(&image, name)) {
|
|
|
|
ERROR("'%s' already in ROM image.\n", name);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2020-03-14 00:43:34 +01:00
|
|
|
header = cbfs_create_file_header(CBFS_TYPE_RAW,
|
2015-08-25 13:48:10 +02:00
|
|
|
buffer.size, name);
|
2020-05-07 02:27:02 +02:00
|
|
|
|
|
|
|
enum vb2_hash_algorithm algo = get_mh_cache()->cbfs_hash.algo;
|
|
|
|
if (algo != VB2_HASH_INVALID)
|
|
|
|
if (cbfs_add_file_hash(header, &buffer, algo)) {
|
|
|
|
ERROR("couldn't add hash for '%s'\n", name);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2018-11-20 13:54:49 +01:00
|
|
|
if (cbfs_add_entry(&image, &buffer, offset, header, 0) != 0) {
|
2015-03-06 00:38:03 +01:00
|
|
|
ERROR("Failed to add %llu into ROM image as '%s'.\n",
|
|
|
|
(long long unsigned)u64val, name);
|
2013-07-09 19:39:13 +02:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
ret = maybe_update_metadata_hash(&image);
|
2013-07-09 19:39:13 +02:00
|
|
|
|
|
|
|
done:
|
2015-08-25 13:48:10 +02:00
|
|
|
free(header);
|
2013-07-09 19:39:13 +02:00
|
|
|
buffer_delete(&buffer);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-05-29 11:18:14 +02:00
|
|
|
static int is_valid_topswap(void)
|
|
|
|
{
|
|
|
|
switch (param.topswap_size) {
|
|
|
|
case (64 * KiB):
|
|
|
|
case (128 * KiB):
|
|
|
|
case (256 * KiB):
|
|
|
|
case (512 * KiB):
|
|
|
|
case (1 * MiB):
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ERROR("Invalid topswap_size %d, topswap can be 64K|128K|256K|512K|1M\n",
|
|
|
|
param.topswap_size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fill_header_offset(void *location, uint32_t offset)
|
|
|
|
{
|
2018-10-11 11:01:30 +02:00
|
|
|
// TODO: When we have a BE target, we'll need to store this as BE
|
2018-05-29 11:18:14 +02:00
|
|
|
write_le32(location, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int update_master_header_loc_topswap(struct cbfs_image *image,
|
|
|
|
void *h_loc, uint32_t header_offset)
|
|
|
|
{
|
|
|
|
struct cbfs_file *entry;
|
|
|
|
void *ts_h_loc = h_loc;
|
|
|
|
|
|
|
|
entry = cbfs_get_entry(image, "bootblock");
|
|
|
|
if (entry == NULL) {
|
|
|
|
ERROR("Bootblock not in ROM image?!?\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the existing topswap boundary matches with
|
|
|
|
* the one provided.
|
|
|
|
*/
|
|
|
|
if (param.topswap_size != ntohl(entry->len)/2) {
|
|
|
|
ERROR("Top swap boundary does not match\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ts_h_loc -= param.topswap_size;
|
|
|
|
fill_header_offset(ts_h_loc, header_offset);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-09-10 15:28:27 +02:00
|
|
|
static int cbfs_add_master_header(void)
|
|
|
|
{
|
|
|
|
const char * const name = "cbfs master header";
|
|
|
|
struct cbfs_image image;
|
|
|
|
struct cbfs_file *header = NULL;
|
|
|
|
struct buffer buffer;
|
|
|
|
int ret = 1;
|
2016-01-04 20:56:00 +01:00
|
|
|
size_t offset;
|
|
|
|
size_t size;
|
2018-05-29 11:18:14 +02:00
|
|
|
void *h_loc;
|
2015-09-10 15:28:27 +02:00
|
|
|
|
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
|
|
|
param.headeroffset)) {
|
|
|
|
ERROR("Selected image region is not a CBFS.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cbfs_get_entry(&image, name)) {
|
|
|
|
ERROR("'%s' already in ROM image.\n", name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buffer_create(&buffer, sizeof(struct cbfs_header), name) != 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
struct cbfs_header *h = (struct cbfs_header *)buffer.data;
|
|
|
|
h->magic = htonl(CBFS_HEADER_MAGIC);
|
|
|
|
h->version = htonl(CBFS_HEADER_VERSION);
|
|
|
|
/* The 4 bytes are left out for two reasons:
|
|
|
|
* 1. the cbfs master header pointer resides there
|
|
|
|
* 2. some cbfs implementations assume that an image that resides
|
|
|
|
* below 4GB has a bootblock and get confused when the end of the
|
|
|
|
* image is at 4GB == 0.
|
|
|
|
*/
|
|
|
|
h->bootblocksize = htonl(4);
|
2020-03-14 00:43:34 +01:00
|
|
|
h->align = htonl(CBFS_ALIGNMENT);
|
2016-01-04 20:56:00 +01:00
|
|
|
/* The offset and romsize fields within the master header are absolute
|
|
|
|
* values within the boot media. As such, romsize needs to relfect
|
|
|
|
* the end 'offset' for a CBFS. To achieve that the current buffer
|
|
|
|
* representing the CBFS region's size is added to the offset of
|
|
|
|
* the region within a larger image.
|
2015-09-10 15:28:27 +02:00
|
|
|
*/
|
2016-01-04 20:56:00 +01:00
|
|
|
offset = buffer_get(param.image_region) -
|
|
|
|
buffer_get_original_backing(param.image_region);
|
|
|
|
size = buffer_size(param.image_region);
|
|
|
|
h->romsize = htonl(size + offset);
|
|
|
|
h->offset = htonl(offset);
|
2015-09-10 15:28:27 +02:00
|
|
|
h->architecture = htonl(CBFS_ARCHITECTURE_UNKNOWN);
|
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
/* Never add a hash attribute to the master header. */
|
2020-03-14 00:43:34 +01:00
|
|
|
header = cbfs_create_file_header(CBFS_TYPE_CBFSHEADER,
|
2015-09-10 15:28:27 +02:00
|
|
|
buffer_size(&buffer), name);
|
2018-11-20 13:54:49 +01:00
|
|
|
if (cbfs_add_entry(&image, &buffer, 0, header, 0) != 0) {
|
2015-09-10 15:28:27 +02:00
|
|
|
ERROR("Failed to add cbfs master header into ROM image.\n");
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cbfs_file *entry;
|
|
|
|
if ((entry = cbfs_get_entry(&image, name)) == NULL) {
|
|
|
|
ERROR("'%s' not in ROM image?!?\n", name);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t header_offset = CBFS_SUBHEADER(entry) -
|
|
|
|
buffer_get(&image.buffer);
|
|
|
|
header_offset = -(buffer_size(&image.buffer) - header_offset);
|
|
|
|
|
2018-05-29 11:18:14 +02:00
|
|
|
h_loc = (void *)(buffer_get(&image.buffer) +
|
|
|
|
buffer_size(&image.buffer) - 4);
|
|
|
|
fill_header_offset(h_loc, header_offset);
|
|
|
|
/*
|
2018-10-11 11:01:30 +02:00
|
|
|
* If top swap present, update the header
|
2018-05-29 11:18:14 +02:00
|
|
|
* location in secondary bootblock
|
|
|
|
*/
|
|
|
|
if (param.topswap_size) {
|
|
|
|
if (update_master_header_loc_topswap(&image, h_loc,
|
|
|
|
header_offset))
|
|
|
|
return 1;
|
|
|
|
}
|
2015-09-10 15:28:27 +02:00
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
ret = maybe_update_metadata_hash(&image);
|
2015-09-10 15:28:27 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
free(header);
|
|
|
|
buffer_delete(&buffer);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-05-29 11:18:14 +02:00
|
|
|
static int add_topswap_bootblock(struct buffer *buffer, uint32_t *offset)
|
|
|
|
{
|
|
|
|
size_t bb_buf_size = buffer_size(buffer);
|
|
|
|
|
|
|
|
if (bb_buf_size > param.topswap_size) {
|
|
|
|
ERROR("Bootblock bigger than the topswap boundary\n");
|
|
|
|
ERROR("size = %zd, ts = %d\n", bb_buf_size,
|
|
|
|
param.topswap_size);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2018-10-11 11:01:30 +02:00
|
|
|
* Allocate topswap_size*2 bytes for bootblock to
|
2018-05-29 11:18:14 +02:00
|
|
|
* accommodate the second bootblock.
|
|
|
|
*/
|
|
|
|
struct buffer new_bootblock, bb1, bb2;
|
|
|
|
if (buffer_create(&new_bootblock, 2 * param.topswap_size,
|
|
|
|
buffer->name))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
buffer_splice(&bb1, &new_bootblock, param.topswap_size - bb_buf_size,
|
|
|
|
bb_buf_size);
|
|
|
|
buffer_splice(&bb2, &new_bootblock,
|
|
|
|
buffer_size(&new_bootblock) - bb_buf_size,
|
|
|
|
bb_buf_size);
|
|
|
|
|
2018-10-11 11:01:30 +02:00
|
|
|
/* Copy to first bootblock */
|
2018-05-29 11:18:14 +02:00
|
|
|
memcpy(buffer_get(&bb1), buffer_get(buffer), bb_buf_size);
|
2018-10-11 11:01:30 +02:00
|
|
|
/* Copy to second bootblock */
|
2018-05-29 11:18:14 +02:00
|
|
|
memcpy(buffer_get(&bb2), buffer_get(buffer), bb_buf_size);
|
|
|
|
|
|
|
|
buffer_delete(buffer);
|
|
|
|
buffer_clone(buffer, &new_bootblock);
|
|
|
|
|
2018-10-11 11:01:30 +02:00
|
|
|
/* Update the location (offset) of bootblock in the region */
|
2020-11-21 01:52:03 +01:00
|
|
|
return convert_region_offset(buffer_size(buffer), offset);
|
2018-05-29 11:18:14 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
static int cbfs_add_component(const char *filename,
|
2013-01-29 03:24:00 +01:00
|
|
|
const char *name,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
uint32_t headeroffset,
|
2015-03-04 00:55:03 +01:00
|
|
|
convert_buffer_t convert)
|
|
|
|
{
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
/*
|
|
|
|
* The steps used to determine the final placement offset in CBFS, in order:
|
|
|
|
*
|
2021-12-09 22:20:59 +01:00
|
|
|
* 1. If --base-address was passed, that value is used. If it was passed in the host
|
|
|
|
* address space, convert it to flash address space. (After that, |*offset| is always
|
|
|
|
* in the flash address space.)
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
*
|
|
|
|
* 2. The convert() function may write a location back to |offset|, usually by calling
|
|
|
|
* do_cbfs_locate(). In this case, it needs to ensure that the location found can fit
|
|
|
|
* the CBFS file in its final form (after any compression and conversion).
|
|
|
|
*
|
|
|
|
* 3. If --align was passed and the offset is still undecided at this point,
|
|
|
|
* do_cbfs_locate() is called to find an appropriately aligned location.
|
|
|
|
*
|
|
|
|
* 4. If |offset| is still 0 at the end, cbfs_add_entry() will find the first available
|
|
|
|
* location that fits.
|
|
|
|
*/
|
2020-11-19 03:00:31 +01:00
|
|
|
uint32_t offset = param.baseaddress_assigned ? param.baseaddress : 0;
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
size_t len_align = 0;
|
2020-11-19 03:00:31 +01:00
|
|
|
|
|
|
|
if (param.alignment && param.baseaddress_assigned) {
|
|
|
|
ERROR("Cannot specify both alignment and base address\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2018-11-20 13:54:49 +01:00
|
|
|
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.stage_xip && param.compression != CBFS_COMPRESS_NONE) {
|
|
|
|
ERROR("Cannot specify compression for XIP.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-29 03:24:00 +01:00
|
|
|
if (!filename) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify -f/--filename.\n");
|
2009-09-22 17:58:19 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-29 03:24:00 +01:00
|
|
|
if (!name) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify -n/--name.\n");
|
2009-09-22 17:58:19 +02:00
|
|
|
return 1;
|
2009-03-31 13:57:36 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.type == 0) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify a valid -t/--type.\n");
|
2012-10-30 00:52:36 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2009-09-22 17:58:19 +02:00
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
struct cbfs_image image;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region, headeroffset))
|
2013-11-13 23:34:57 +01:00
|
|
|
return 1;
|
|
|
|
|
2015-08-11 14:35:39 +02:00
|
|
|
if (cbfs_get_entry(&image, name)) {
|
|
|
|
ERROR("'%s' already in ROM image.\n", name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
struct buffer buffer;
|
2013-01-29 03:24:00 +01:00
|
|
|
if (buffer_from_file(&buffer, filename) != 0) {
|
|
|
|
ERROR("Could not load file '%s'.\n", filename);
|
2012-10-30 00:52:36 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-08-25 13:48:10 +02:00
|
|
|
struct cbfs_file *header =
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
cbfs_create_file_header(param.type, buffer.size, name);
|
2015-08-11 15:10:33 +02:00
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
/* Bootblock and CBFS header should never have file hashes. When adding
|
|
|
|
the bootblock it is important that we *don't* look up the metadata
|
|
|
|
hash yet (before it is added) or we'll cache an outdated result. */
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.type != CBFS_TYPE_BOOTBLOCK && param.type != CBFS_TYPE_CBFSHEADER) {
|
2020-05-07 02:27:02 +02:00
|
|
|
enum vb2_hash_algorithm mh_algo = get_mh_cache()->cbfs_hash.algo;
|
|
|
|
if (mh_algo != VB2_HASH_INVALID && param.hash != mh_algo) {
|
|
|
|
if (param.hash == VB2_HASH_INVALID) {
|
|
|
|
param.hash = mh_algo;
|
|
|
|
} else {
|
|
|
|
ERROR("Cannot specify hash %s that's different from metadata hash algorithm %s\n",
|
|
|
|
vb2_get_hash_algorithm_name(param.hash),
|
|
|
|
vb2_get_hash_algorithm_name(mh_algo));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
2020-11-19 03:00:31 +01:00
|
|
|
}
|
2009-09-22 17:58:19 +02:00
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
/*
|
|
|
|
* Check if Intel CPU topswap is specified this will require a
|
|
|
|
* second bootblock to be added.
|
|
|
|
*/
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.type == CBFS_TYPE_BOOTBLOCK && param.topswap_size)
|
2020-11-19 03:00:31 +01:00
|
|
|
if (add_topswap_bootblock(&buffer, &offset))
|
|
|
|
goto error;
|
|
|
|
|
2021-12-09 22:20:59 +01:00
|
|
|
/* With --base-address we allow host space addresses -- if so, convert it here. */
|
|
|
|
if (IS_HOST_SPACE_ADDRESS(offset))
|
|
|
|
offset = convert_addr_space(param.image_region, offset);
|
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
if (convert && convert(&buffer, &offset, header) != 0) {
|
|
|
|
ERROR("Failed to parse file '%s'.\n", filename);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
/* This needs to run after convert() to take compression into account. */
|
|
|
|
if (!offset && param.alignment)
|
2021-12-13 19:16:44 +01:00
|
|
|
if (do_cbfs_locate(&offset, buffer_size(&buffer)))
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* This needs to run after convert() to hash the actual final file data. */
|
2020-11-19 03:00:31 +01:00
|
|
|
if (param.hash != VB2_HASH_INVALID &&
|
|
|
|
cbfs_add_file_hash(header, &buffer, param.hash) == -1) {
|
|
|
|
ERROR("couldn't add hash for '%s'\n", name);
|
|
|
|
goto error;
|
2020-05-07 02:27:02 +02:00
|
|
|
}
|
2015-10-01 15:54:04 +02:00
|
|
|
|
2016-01-14 13:22:37 +01:00
|
|
|
if (param.autogen_attr) {
|
|
|
|
/* Add position attribute if assigned */
|
|
|
|
if (param.baseaddress_assigned || param.stage_xip) {
|
|
|
|
struct cbfs_file_attr_position *attrs =
|
|
|
|
(struct cbfs_file_attr_position *)
|
|
|
|
cbfs_add_file_attr(header,
|
|
|
|
CBFS_FILE_ATTR_TAG_POSITION,
|
|
|
|
sizeof(struct cbfs_file_attr_position));
|
|
|
|
if (attrs == NULL)
|
2020-11-19 03:00:31 +01:00
|
|
|
goto error;
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
attrs->position = htonl(offset);
|
2016-01-14 13:22:37 +01:00
|
|
|
}
|
|
|
|
/* Add alignment attribute if used */
|
|
|
|
if (param.alignment) {
|
|
|
|
struct cbfs_file_attr_align *attrs =
|
|
|
|
(struct cbfs_file_attr_align *)
|
|
|
|
cbfs_add_file_attr(header,
|
|
|
|
CBFS_FILE_ATTR_TAG_ALIGNMENT,
|
|
|
|
sizeof(struct cbfs_file_attr_align));
|
|
|
|
if (attrs == NULL)
|
2020-11-19 03:00:31 +01:00
|
|
|
goto error;
|
2016-01-14 13:22:37 +01:00
|
|
|
attrs->alignment = htonl(param.alignment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-20 13:54:49 +01:00
|
|
|
if (param.ibb) {
|
|
|
|
/* Mark as Initial Boot Block */
|
|
|
|
struct cbfs_file_attribute *attrs = cbfs_add_file_attr(header,
|
|
|
|
CBFS_FILE_ATTR_TAG_IBB,
|
|
|
|
sizeof(struct cbfs_file_attribute));
|
|
|
|
if (attrs == NULL)
|
2020-11-19 03:00:31 +01:00
|
|
|
goto error;
|
2018-11-20 13:54:49 +01:00
|
|
|
/* For Intel TXT minimum align is 16 */
|
|
|
|
len_align = 16;
|
|
|
|
}
|
|
|
|
|
2017-10-31 01:38:04 +01:00
|
|
|
if (param.padding) {
|
|
|
|
const uint32_t hs = sizeof(struct cbfs_file_attribute);
|
2020-11-21 01:12:40 +01:00
|
|
|
uint32_t size = ALIGN_UP(MAX(hs, param.padding),
|
|
|
|
CBFS_ATTRIBUTE_ALIGN);
|
2017-10-31 01:38:04 +01:00
|
|
|
INFO("Padding %d bytes\n", size);
|
|
|
|
struct cbfs_file_attribute *attr =
|
|
|
|
(struct cbfs_file_attribute *)cbfs_add_file_attr(
|
|
|
|
header, CBFS_FILE_ATTR_TAG_PADDING,
|
|
|
|
size);
|
|
|
|
if (attr == NULL)
|
2020-11-19 03:00:31 +01:00
|
|
|
goto error;
|
2017-10-31 01:38:04 +01:00
|
|
|
}
|
|
|
|
|
2018-11-20 13:54:49 +01:00
|
|
|
if (cbfs_add_entry(&image, &buffer, offset, header, len_align) != 0) {
|
2013-01-29 03:24:00 +01:00
|
|
|
ERROR("Failed to add '%s' into ROM image.\n", filename);
|
2020-05-07 02:27:02 +02:00
|
|
|
goto error;
|
2013-01-29 03:24:00 +01:00
|
|
|
}
|
|
|
|
|
2015-08-25 13:48:10 +02:00
|
|
|
free(header);
|
2013-01-29 03:24:00 +01:00
|
|
|
buffer_delete(&buffer);
|
2020-05-07 02:27:02 +02:00
|
|
|
|
|
|
|
return maybe_update_metadata_hash(&image) || maybe_update_fmap_hash();
|
|
|
|
|
|
|
|
error:
|
|
|
|
free(header);
|
|
|
|
buffer_delete(&buffer);
|
|
|
|
return 1;
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
static int cbfstool_convert_raw(struct buffer *buffer,
|
|
|
|
unused uint32_t *offset, struct cbfs_file *header)
|
|
|
|
{
|
|
|
|
char *compressed;
|
2017-01-11 18:38:11 +01:00
|
|
|
int decompressed_size, compressed_size;
|
|
|
|
comp_func_ptr compress;
|
|
|
|
|
|
|
|
decompressed_size = buffer->size;
|
|
|
|
if (param.precompression) {
|
2017-01-17 13:01:25 +01:00
|
|
|
param.compression = read_le32(buffer->data);
|
|
|
|
decompressed_size = read_le32(buffer->data + sizeof(uint32_t));
|
2017-01-11 18:38:11 +01:00
|
|
|
compressed_size = buffer->size - 8;
|
|
|
|
compressed = malloc(compressed_size);
|
|
|
|
if (!compressed)
|
|
|
|
return -1;
|
|
|
|
memcpy(compressed, buffer->data + 8, compressed_size);
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
} else {
|
2020-10-24 04:19:32 +02:00
|
|
|
if (param.compression == CBFS_COMPRESS_NONE)
|
|
|
|
goto out;
|
|
|
|
|
2017-01-11 18:38:11 +01:00
|
|
|
compress = compression_function(param.compression);
|
|
|
|
if (!compress)
|
|
|
|
return -1;
|
|
|
|
compressed = calloc(buffer->size, 1);
|
|
|
|
if (!compressed)
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
return -1;
|
|
|
|
|
2017-01-11 18:38:11 +01:00
|
|
|
if (compress(buffer->data, buffer->size,
|
|
|
|
compressed, &compressed_size)) {
|
|
|
|
WARN("Compression failed - disabled\n");
|
|
|
|
free(compressed);
|
2020-10-24 04:19:32 +02:00
|
|
|
goto out;
|
2017-01-11 18:38:11 +01:00
|
|
|
}
|
|
|
|
}
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
|
2017-01-11 18:38:11 +01:00
|
|
|
struct cbfs_file_attr_compression *attrs =
|
|
|
|
(struct cbfs_file_attr_compression *)
|
|
|
|
cbfs_add_file_attr(header,
|
|
|
|
CBFS_FILE_ATTR_TAG_COMPRESSION,
|
|
|
|
sizeof(struct cbfs_file_attr_compression));
|
|
|
|
if (attrs == NULL) {
|
|
|
|
free(compressed);
|
|
|
|
return -1;
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
}
|
2017-01-11 18:38:11 +01:00
|
|
|
attrs->compression = htonl(param.compression);
|
|
|
|
attrs->decompressed_size = htonl(decompressed_size);
|
|
|
|
|
|
|
|
free(buffer->data);
|
|
|
|
buffer->data = compressed;
|
|
|
|
buffer->size = compressed_size;
|
|
|
|
|
2020-10-24 04:19:32 +02:00
|
|
|
out:
|
2017-01-11 18:38:11 +01:00
|
|
|
header->len = htonl(buffer->size);
|
cbfstool: allow compression at file header level
Currently, compression is only allowed at subheader level (e.g. cbfs_stage,
cbfs_payload_segment). This change adds compression field to each file's
header so that any cbfs file can be compressed.
With the necessary additions in coreboot and libpayload, the following sample
code can load a compressed file:
const char *name = "foo.bmp";
struct cbfs_file *file = cbfs_get_file(media, name);
void *dst = malloc(ntohl(file->uncompressed_size));
dst = cbfs_get_file_content(media, name, type, file, dst);
cbfs_stage and cbfs_payload_segment continue to support compression at
subheader level because stages and payloads have to be decompressed to the load
address, which is stored in the subheader. For these, file level compression
should be turned off.
Change-Id: I9a00ec99dfc68ffb2771bb4a3cc5ba6ba8a326f4
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2015-07-10 00:07:45 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-02 00:02:45 +02:00
|
|
|
static int cbfstool_convert_fsp(struct buffer *buffer,
|
|
|
|
uint32_t *offset, struct cbfs_file *header)
|
|
|
|
{
|
|
|
|
uint32_t address;
|
|
|
|
struct buffer fsp;
|
|
|
|
|
2016-05-09 20:53:34 +02:00
|
|
|
/*
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
* There are 4 different cases here:
|
|
|
|
*
|
|
|
|
* 1. --xip and --base-address: we need to place the binary at the given base address
|
2021-12-09 22:20:59 +01:00
|
|
|
* in the CBFS image and relocate it to that address. *offset was already filled in,
|
|
|
|
* but we need to convert it to the host address space for relocation.
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
*
|
|
|
|
* 2. --xip but no --base-address: we implicitly force a 4K minimum alignment so that
|
|
|
|
* relocation can occur. Call do_cbfs_locate() here to find an appropriate *offset.
|
2021-12-09 22:20:59 +01:00
|
|
|
* This also needs to be converted to the host address space for relocation.
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
*
|
|
|
|
* 3. No --xip but a --base-address: special case where --base-address does not have its
|
|
|
|
* normal meaning, instead we use it as the relocation target address. We explicitly
|
|
|
|
* reset *offset to 0 so that the file will be placed wherever it fits in CBFS.
|
|
|
|
*
|
|
|
|
* 4. No --xip and no --base-address: this means that the FSP was pre-linked and should
|
|
|
|
* not be relocated. Just chain directly to convert_raw() for compression.
|
2016-05-09 20:53:34 +02:00
|
|
|
*/
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
|
2016-05-09 20:53:34 +02:00
|
|
|
if (param.stage_xip) {
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (!param.baseaddress_assigned) {
|
|
|
|
param.alignment = 4*1024;
|
2021-12-13 19:16:44 +01:00
|
|
|
if (do_cbfs_locate(offset, buffer_size(buffer)))
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2021-12-09 22:20:59 +01:00
|
|
|
assert(!IS_HOST_SPACE_ADDRESS(*offset));
|
|
|
|
address = convert_addr_space(param.image_region, *offset);
|
2016-05-09 20:53:34 +02:00
|
|
|
} else {
|
2016-05-16 22:18:45 +02:00
|
|
|
if (param.baseaddress_assigned == 0) {
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
INFO("Honoring pre-linked FSP module, no relocation.\n");
|
|
|
|
return cbfstool_convert_raw(buffer, offset, header);
|
2016-05-16 22:18:45 +02:00
|
|
|
} else {
|
|
|
|
address = param.baseaddress;
|
2016-05-09 20:53:34 +02:00
|
|
|
*offset = 0;
|
2020-06-10 06:20:27 +02:00
|
|
|
}
|
2016-05-09 20:53:34 +02:00
|
|
|
}
|
2015-10-02 00:02:45 +02:00
|
|
|
|
|
|
|
/* Create a copy of the buffer to attempt relocation. */
|
|
|
|
if (buffer_create(&fsp, buffer_size(buffer), "fsp"))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
memcpy(buffer_get(&fsp), buffer_get(buffer), buffer_size(buffer));
|
|
|
|
|
|
|
|
/* Replace the buffer contents w/ the relocated ones on success. */
|
2016-05-09 21:23:01 +02:00
|
|
|
if (fsp_component_relocate(address, buffer_get(&fsp), buffer_size(&fsp))
|
|
|
|
> 0) {
|
2015-10-02 00:02:45 +02:00
|
|
|
buffer_delete(buffer);
|
|
|
|
buffer_clone(buffer, &fsp);
|
|
|
|
} else {
|
|
|
|
buffer_delete(&fsp);
|
2016-05-09 21:23:01 +02:00
|
|
|
WARN("Invalid FSP variant.\n");
|
2015-10-02 00:02:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Let the raw path handle all the cbfs metadata logic. */
|
|
|
|
return cbfstool_convert_raw(buffer, offset, header);
|
|
|
|
}
|
|
|
|
|
2015-08-11 15:16:24 +02:00
|
|
|
static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset,
|
2015-08-25 15:53:52 +02:00
|
|
|
struct cbfs_file *header)
|
2014-02-03 05:37:28 +01:00
|
|
|
{
|
2013-01-29 08:22:11 +01:00
|
|
|
struct buffer output;
|
2020-11-19 03:00:31 +01:00
|
|
|
size_t data_size;
|
2014-02-03 05:37:28 +01:00
|
|
|
int ret;
|
2015-09-16 00:00:23 +02:00
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
if (elf_program_file_size(buffer, &data_size) < 0) {
|
|
|
|
ERROR("Could not obtain ELF size\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2015-09-16 00:00:23 +02:00
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
/*
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
* We need a final location for XIP parsing, so we need to call do_cbfs_locate() early
|
|
|
|
* here. That is okay because XIP stages may not be compressed, so their size cannot
|
|
|
|
* change anymore at a later point.
|
2020-11-19 03:00:31 +01:00
|
|
|
*/
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.stage_xip &&
|
|
|
|
do_cbfs_locate(offset, data_size)) {
|
2020-11-19 03:00:31 +01:00
|
|
|
ERROR("Could not find location for stage.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2015-09-16 00:00:23 +02:00
|
|
|
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
struct cbfs_file_attr_stageheader *stageheader = (void *)
|
|
|
|
cbfs_add_file_attr(header, CBFS_FILE_ATTR_TAG_STAGEHEADER,
|
|
|
|
sizeof(struct cbfs_file_attr_stageheader));
|
|
|
|
if (!stageheader)
|
|
|
|
return -1;
|
|
|
|
|
2020-11-19 03:00:31 +01:00
|
|
|
if (param.stage_xip) {
|
2021-12-09 22:20:59 +01:00
|
|
|
uint32_t host_space_address = convert_addr_space(param.image_region, *offset);
|
|
|
|
assert(IS_HOST_SPACE_ADDRESS(host_space_address));
|
|
|
|
ret = parse_elf_to_xip_stage(buffer, &output, host_space_address,
|
|
|
|
param.ignore_section, stageheader);
|
2021-01-13 00:21:03 +01:00
|
|
|
} else {
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
ret = parse_elf_to_stage(buffer, &output, param.ignore_section,
|
|
|
|
stageheader);
|
2021-01-13 00:21:03 +01:00
|
|
|
}
|
2014-02-03 05:37:28 +01:00
|
|
|
if (ret != 0)
|
2013-01-29 08:22:11 +01:00
|
|
|
return -1;
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
|
|
|
|
/* Store a hash of original uncompressed stage to compare later. */
|
|
|
|
size_t decmp_size = buffer_size(&output);
|
|
|
|
uint32_t decmp_hash = XXH32(buffer_get(&output), decmp_size, 0);
|
|
|
|
|
|
|
|
/* Chain to base conversion routine to handle compression. */
|
|
|
|
ret = cbfstool_convert_raw(&output, offset, header);
|
|
|
|
if (ret != 0)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* Special care must be taken for LZ4-compressed stages that the BSS is
|
|
|
|
large enough to provide scratch space for in-place decompression. */
|
|
|
|
if (!param.precompression && param.compression == CBFS_COMPRESS_LZ4) {
|
|
|
|
size_t memlen = ntohl(stageheader->memlen);
|
|
|
|
size_t compressed_size = buffer_size(&output);
|
|
|
|
uint8_t *compare_buffer = malloc(memlen);
|
|
|
|
uint8_t *start = compare_buffer + memlen - compressed_size;
|
|
|
|
if (!compare_buffer) {
|
|
|
|
ERROR("Out of memory\n");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
memcpy(start, buffer_get(&output), compressed_size);
|
|
|
|
ret = ulz4fn(start, compressed_size, compare_buffer, memlen);
|
|
|
|
if (ret == 0) {
|
|
|
|
ERROR("Not enough scratch space to decompress LZ4 in-place -- increase BSS size or disable compression!\n");
|
|
|
|
free(compare_buffer);
|
|
|
|
goto fail;
|
|
|
|
} else if (ret != (int)decmp_size ||
|
|
|
|
decmp_hash != XXH32(compare_buffer, decmp_size, 0)) {
|
|
|
|
ERROR("LZ4 compression BUG! Report to mailing list.\n");
|
|
|
|
free(compare_buffer);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
free(compare_buffer);
|
|
|
|
}
|
|
|
|
|
2013-01-29 08:22:11 +01:00
|
|
|
buffer_delete(buffer);
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
buffer_clone(buffer, &output);
|
2013-01-29 08:22:11 +01:00
|
|
|
return 0;
|
cbfs: Move stage header into a CBFS attribute
The CBFS stage header is part of the file data (not the header) from
CBFS's point of view, which is problematic for verification: in pre-RAM
environments, there's usually not enough scratch space in CBFS_CACHE to
load the full stage into memory, so it must be directly loaded into its
final destination. However, that destination is decided from reading the
stage header. There's no way we can verify the stage header without
loading the whole file and we can't load the file without trusting the
information in the stage header.
To solve this problem, this patch changes the CBFS stage format to move
the stage header out of the file contents and into a separate CBFS
attribute. Attributes are part of the metadata, so they have already
been verified before the file is loaded.
Since CBFS stages are generally only meant to be used by coreboot itself
and the coreboot build system builds cbfstool and all stages together in
one go, maintaining backwards-compatibility should not be necessary. An
older version of coreboot will build the old version of cbfstool and a
newer version of coreboot will build the new version of cbfstool before
using it to add stages to the final image, thus cbfstool and coreboot's
stage loader should stay in sync. This only causes problems when someone
stashes away a copy of cbfstool somewhere and later uses it to try to
extract stages from a coreboot image built from a different revision...
a debugging use-case that is hopefully rare enough that affected users
can manually deal with finding a matching version of cbfstool.
The SELF (payload) format, on the other hand, is designed to be used for
binaries outside of coreboot that may use independent build systems and
are more likely to be added with a potentially stale copy of cbfstool,
so it would be more problematic to make a similar change for SELFs. It
is not necessary for verification either, since they're usually only
used in post-RAM environments and selfload() already maps SELFs to
CBFS_CACHE before loading them to their final destination anyway (so
they can be hashed at that time).
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I8471ad7494b07599e24e82b81e507fcafbad808a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46484
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2020-10-16 02:37:57 +02:00
|
|
|
|
|
|
|
fail:
|
|
|
|
buffer_delete(&output);
|
|
|
|
return -1;
|
2013-01-29 08:22:11 +01:00
|
|
|
}
|
|
|
|
|
2015-03-04 00:55:03 +01:00
|
|
|
static int cbfstool_convert_mkpayload(struct buffer *buffer,
|
2015-08-25 15:53:52 +02:00
|
|
|
unused uint32_t *offset, struct cbfs_file *header)
|
2015-03-04 00:55:03 +01:00
|
|
|
{
|
2013-01-29 08:22:11 +01:00
|
|
|
struct buffer output;
|
2013-02-05 00:39:13 +01:00
|
|
|
int ret;
|
2018-10-11 11:01:30 +02:00
|
|
|
/* Per default, try and see if payload is an ELF binary */
|
2015-05-08 06:00:05 +02:00
|
|
|
ret = parse_elf_to_payload(buffer, &output, param.compression);
|
2013-02-05 00:39:13 +01:00
|
|
|
|
2018-04-26 09:35:13 +02:00
|
|
|
/* If it's not an ELF, see if it's a FIT */
|
|
|
|
if (ret != 0) {
|
|
|
|
ret = parse_fit_to_payload(buffer, &output, param.compression);
|
|
|
|
if (ret == 0)
|
2020-03-14 00:43:34 +01:00
|
|
|
header->type = htonl(CBFS_TYPE_FIT);
|
2018-04-26 09:35:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If it's not an FIT, see if it's a UEFI FV */
|
2013-02-05 00:39:13 +01:00
|
|
|
if (ret != 0)
|
2015-05-08 06:00:05 +02:00
|
|
|
ret = parse_fv_to_payload(buffer, &output, param.compression);
|
2013-02-05 00:39:13 +01:00
|
|
|
|
2013-08-27 20:22:21 +02:00
|
|
|
/* If it's neither ELF nor UEFI Fv, try bzImage */
|
|
|
|
if (ret != 0)
|
|
|
|
ret = parse_bzImage_to_payload(buffer, &output,
|
2015-05-08 06:00:05 +02:00
|
|
|
param.initrd, param.cmdline, param.compression);
|
2013-08-27 20:22:21 +02:00
|
|
|
|
2013-02-05 00:39:13 +01:00
|
|
|
/* Not a supported payload type */
|
|
|
|
if (ret != 0) {
|
|
|
|
ERROR("Not a supported payload type (ELF / FV).\n");
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
buffer_delete(buffer);
|
2013-01-29 08:22:11 +01:00
|
|
|
return -1;
|
2013-02-05 00:39:13 +01:00
|
|
|
}
|
|
|
|
|
2013-01-29 08:22:11 +01:00
|
|
|
buffer_delete(buffer);
|
2018-10-11 11:01:30 +02:00
|
|
|
// Direct assign, no dupe.
|
2013-01-29 08:22:11 +01:00
|
|
|
memcpy(buffer, &output, sizeof(*buffer));
|
2015-08-25 20:17:14 +02:00
|
|
|
header->len = htonl(output.size);
|
2013-01-29 08:22:11 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cbfstool_convert_mkflatpayload(struct buffer *buffer,
|
2015-08-25 15:53:52 +02:00
|
|
|
unused uint32_t *offset, struct cbfs_file *header)
|
2015-03-04 00:55:03 +01:00
|
|
|
{
|
2013-01-29 08:22:11 +01:00
|
|
|
struct buffer output;
|
|
|
|
if (parse_flat_binary_to_payload(buffer, &output,
|
|
|
|
param.loadaddress,
|
|
|
|
param.entrypoint,
|
2015-05-08 06:00:05 +02:00
|
|
|
param.compression) != 0) {
|
2013-01-29 08:22:11 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
buffer_delete(buffer);
|
2018-10-11 11:01:30 +02:00
|
|
|
// Direct assign, no dupe.
|
2013-01-29 08:22:11 +01:00
|
|
|
memcpy(buffer, &output, sizeof(*buffer));
|
2015-08-25 20:17:14 +02:00
|
|
|
header->len = htonl(output.size);
|
2013-01-29 08:22:11 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-29 03:24:00 +01:00
|
|
|
static int cbfs_add(void)
|
|
|
|
{
|
2020-11-19 03:00:31 +01:00
|
|
|
convert_buffer_t convert = cbfstool_convert_raw;
|
2015-10-02 00:02:45 +02:00
|
|
|
|
2020-03-14 00:43:34 +01:00
|
|
|
if (param.type == CBFS_TYPE_FSP) {
|
2015-10-02 00:02:45 +02:00
|
|
|
convert = cbfstool_convert_fsp;
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
} else if (param.type == CBFS_TYPE_STAGE) {
|
|
|
|
ERROR("stages can only be added with cbfstool add-stage\n");
|
|
|
|
return 1;
|
2016-05-09 20:53:34 +02:00
|
|
|
} else if (param.stage_xip) {
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
ERROR("cbfstool add supports xip only for FSP component type\n");
|
2016-05-09 20:53:34 +02:00
|
|
|
return 1;
|
2015-10-02 00:02:45 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return cbfs_add_component(param.filename,
|
2013-01-29 03:24:00 +01:00
|
|
|
param.name,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
param.headeroffset,
|
2015-10-02 00:02:45 +02:00
|
|
|
convert);
|
2013-01-29 03:24:00 +01:00
|
|
|
}
|
|
|
|
|
2013-01-29 08:22:11 +01:00
|
|
|
static int cbfs_add_stage(void)
|
2009-09-22 17:58:19 +02:00
|
|
|
{
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
if (param.stage_xip && param.baseaddress_assigned) {
|
|
|
|
ERROR("Cannot specify base address for XIP.\n");
|
|
|
|
return 1;
|
2015-09-16 00:00:23 +02:00
|
|
|
}
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
param.type = CBFS_TYPE_STAGE;
|
2015-09-16 00:00:23 +02:00
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return cbfs_add_component(param.filename,
|
2013-01-29 08:22:11 +01:00
|
|
|
param.name,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
param.headeroffset,
|
2013-01-29 08:22:11 +01:00
|
|
|
cbfstool_convert_mkstage);
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
2013-01-29 08:22:11 +01:00
|
|
|
static int cbfs_add_payload(void)
|
2009-09-22 17:58:19 +02:00
|
|
|
{
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
param.type = CBFS_TYPE_SELF;
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return cbfs_add_component(param.filename,
|
2013-01-29 08:22:11 +01:00
|
|
|
param.name,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
param.headeroffset,
|
2013-01-29 08:22:11 +01:00
|
|
|
cbfstool_convert_mkpayload);
|
2009-03-31 13:57:36 +02:00
|
|
|
}
|
2009-09-22 17:58:19 +02:00
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static int cbfs_add_flat_binary(void)
|
2012-10-23 01:04:13 +02:00
|
|
|
{
|
2013-01-28 07:23:49 +01:00
|
|
|
if (param.loadaddress == 0) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify a valid "
|
2012-10-30 00:52:36 +01:00
|
|
|
"-l/--load-address.\n");
|
|
|
|
return 1;
|
2012-10-23 01:04:13 +02:00
|
|
|
}
|
2013-01-28 07:23:49 +01:00
|
|
|
if (param.entrypoint == 0) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify a valid "
|
2012-10-30 00:52:36 +01:00
|
|
|
"-e/--entry-point.\n");
|
|
|
|
return 1;
|
2012-10-23 01:04:13 +02:00
|
|
|
}
|
cbfstool: Fix offset calculation for aligned files
The placement calculation logic in cbfs_add_component() has become quite
a mess, and this patch can only fix that to a limited degree. The
interaction between all the different pathways of how the `offset`
variable can be set and at what point exactly the final placement offset
is decided can get quite convoluted. In particular, one existing problem
is that the offset for a file added with the --align flag is decided
before the convert() function is called, which may change the form (and
thereby the size) of the file again after its location was found --
resulting in a location that ends up being too small, or being unable to
find a location for a file that should fit. This used to be okay under
the assumption that forced alignment should really only be necessary for
use cases like XIP where the file is directly "used" straight from its
location on flash in some way, and those cases can never be compressed
-- however, recent AMD platforms have started using the --align flag to
meet the requirements of their SPI DMA controller and broken this
assumption.
This patch fixes that particular problem and hopefully eliminates a bit
of the convolution by moving the offset decision point in the --align
case after the convert() step. This is safe when the steps in-between
(add_topswap_bootblock() and convert() itself) do not rely on the
location having already been decided by --align before that point. For
the topswap case this is easy, because in practice we always call it
with --base-address (and as far as I can tell that's the only way it was
ever meant to work?) -- so codify that assumption in the function. For
convert() this mostly means that the implementations that do touch the
offset variable (mkstage and FSP) need to ensure they take care of the
alignment themselves. The FSP case is particularly complex so I tried to
rewrite the code in a slightly more straight-forward way and clearly
document the supported cases, which should hopefully make it easier to
see that the offset variable is handled correctly in all of them. For
mkstage the best solution seems to be to only have it touch the offset
variable in the XIP case (where we know compression must be disabled, so
we can rely on it not changing the file size later), and have the extra
space for the stage header directly taken care of by do_cbfs_locate() so
that can happen after convert().
NOTE: This is changing the behavior of `cbfstool add -t fsp` when
neither --base-address nor --xip are passed (e.g. FSP-S). Previously,
cbfstool would implicitly force an alignment of 4K. As far as I can tell
from the comments, this is unnecessary because this binary is loaded
into RAM and CBFS placement does not matter, so I assume this is an
oversight caused by accidentally reusing code that was only meant for
the XIP case.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: Ia49a585988f7a74944a6630b77b3ebd79b3a9897
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59877
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
2021-12-03 23:46:53 +01:00
|
|
|
param.type = CBFS_TYPE_SELF;
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return cbfs_add_component(param.filename,
|
2013-01-29 08:22:11 +01:00
|
|
|
param.name,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
param.headeroffset,
|
2013-01-29 08:22:11 +01:00
|
|
|
cbfstool_convert_mkflatpayload);
|
2012-10-23 01:04:13 +02:00
|
|
|
}
|
|
|
|
|
2013-07-09 19:39:13 +02:00
|
|
|
static int cbfs_add_integer(void)
|
|
|
|
{
|
2016-12-12 18:38:01 +01:00
|
|
|
if (!param.u64val_assigned) {
|
|
|
|
ERROR("You need to specify a value to write.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return cbfs_add_integer_component(param.name,
|
2013-07-09 19:39:13 +02:00
|
|
|
param.u64val,
|
cbfstool: allow user to explicitly specify header location
There potentially could be multiple CBFS instances present in the
firmware image. cbfstool should be able to operate on any of them, not
just the first one present.
To accomplish that, allow all CBFS commands to accept the -H parameter
(which specifies the exact CBFS header location in the image).
If this parameter is specified, the image is not searched for the CBFS
header, only the specified location is checked for validity, If the
location is valid, it is considered to be the CBFS header, if not -
the tool exits with an error status.
Note, that default behavior of the tool does not change.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run the following experiments:
- examined an image with three CBFS instances, was able to print all
of them.
- built a rambi coreboot image and tried the following (cbfstool output abbreviated):
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ \od -tx4 -Ax /build/rambi/firmware/coreboot.rom | tail -2
7ffff0 fff67de9 000000ff fff6dfe9 fffff650
800000
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff650
coreboot.rom: 8192 kB, bootblocksize 2448, romsize 8388608, offset 0x700000
alignment: 64 bytes, architecture: x86
Name Offset Type Size
cmos_layout.bin 0x700000 cmos_layout 1164
...
(empty) 0x7ec600 null 77848
$ ./util/cbfstool/cbfstool /build/rambi/firmware/coreboot.rom print -H 0x7ff654
E: /build/rambi/firmware/coreboot.rom does not have CBFS master header.
E: Could not load ROM image '/build/rambi/firmware/coreboot.rom'.
$
Change-Id: I64cbdc79096f3c7a113762b641305542af7bbd60
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 86b88222df6eed25bb176d653305e2e57e18b73a
Original-Change-Id: I486092e222c96c65868ae7d41a9e8976ffcc93c4
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/237485
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/9741
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 00:10:12 +01:00
|
|
|
param.baseaddress,
|
|
|
|
param.headeroffset);
|
2013-07-09 19:39:13 +02:00
|
|
|
}
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static int cbfs_remove(void)
|
2012-01-27 09:33:47 +01:00
|
|
|
{
|
2013-01-28 07:23:49 +01:00
|
|
|
if (!param.name) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify -n/--name.\n");
|
2012-01-27 09:33:47 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
struct cbfs_image image;
|
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.headeroffset))
|
2012-01-27 09:33:47 +01:00
|
|
|
return 1;
|
|
|
|
|
2013-01-28 19:38:40 +01:00
|
|
|
if (cbfs_remove_entry(&image, param.name) != 0) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("Removing file '%s' failed.\n",
|
2013-01-28 19:38:40 +01:00
|
|
|
param.name);
|
2012-01-27 09:33:47 +01:00
|
|
|
return 1;
|
2012-10-30 00:52:36 +01:00
|
|
|
}
|
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
return maybe_update_metadata_hash(&image);
|
2012-01-27 09:33:47 +01:00
|
|
|
}
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static int cbfs_create(void)
|
2009-09-22 17:58:19 +02:00
|
|
|
{
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
struct cbfs_image image;
|
|
|
|
memset(&image, 0, sizeof(image));
|
|
|
|
buffer_clone(&image.buffer, param.image_region);
|
|
|
|
|
|
|
|
if (param.fmap) {
|
|
|
|
if (param.arch != CBFS_ARCHITECTURE_UNKNOWN || param.size ||
|
|
|
|
param.baseaddress_assigned ||
|
|
|
|
param.headeroffset_assigned ||
|
|
|
|
param.cbfsoffset_assigned ||
|
|
|
|
param.bootblock) {
|
2015-07-14 22:18:23 +02:00
|
|
|
ERROR("Since -M was provided, -m, -s, -b, -o, -H, and -B should be omitted\n");
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cbfs_image_create(&image, image.buffer.size);
|
|
|
|
}
|
|
|
|
|
2014-02-03 05:37:28 +01:00
|
|
|
if (param.arch == CBFS_ARCHITECTURE_UNKNOWN) {
|
2013-03-29 00:46:07 +01:00
|
|
|
ERROR("You need to specify -m/--machine arch.\n");
|
2012-11-16 23:48:22 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
struct buffer bootblock;
|
2014-11-10 22:14:24 +01:00
|
|
|
if (!param.bootblock) {
|
|
|
|
DEBUG("-B not given, creating image without bootblock.\n");
|
2016-12-14 16:11:58 +01:00
|
|
|
if (buffer_create(&bootblock, 0, "(dummy)") != 0)
|
|
|
|
return 1;
|
2014-11-10 22:14:24 +01:00
|
|
|
} else if (buffer_from_file(&bootblock, param.bootblock)) {
|
2013-01-29 02:45:12 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-11-10 22:14:24 +01:00
|
|
|
if (!param.alignment)
|
2015-07-14 22:18:23 +02:00
|
|
|
param.alignment = CBFS_ALIGNMENT;
|
2014-11-10 22:14:24 +01:00
|
|
|
|
|
|
|
// Set default offsets. x86, as usual, needs to be a special snowflake.
|
2013-01-29 02:45:12 +01:00
|
|
|
if (!param.baseaddress_assigned) {
|
2014-11-10 22:14:24 +01:00
|
|
|
if (param.arch == CBFS_ARCHITECTURE_X86) {
|
|
|
|
// Make sure there's at least enough room for rel_offset
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.baseaddress = param.size -
|
|
|
|
MAX(bootblock.size, sizeof(int32_t));
|
2014-11-10 22:14:24 +01:00
|
|
|
DEBUG("x86 -> bootblock lies at end of ROM (%#x).\n",
|
|
|
|
param.baseaddress);
|
|
|
|
} else {
|
|
|
|
param.baseaddress = 0;
|
|
|
|
DEBUG("bootblock starts at address 0x0.\n");
|
|
|
|
}
|
2013-01-29 02:45:12 +01:00
|
|
|
}
|
|
|
|
if (!param.headeroffset_assigned) {
|
2014-11-10 22:14:24 +01:00
|
|
|
if (param.arch == CBFS_ARCHITECTURE_X86) {
|
|
|
|
param.headeroffset = param.baseaddress -
|
|
|
|
sizeof(struct cbfs_header);
|
|
|
|
DEBUG("x86 -> CBFS header before bootblock (%#x).\n",
|
|
|
|
param.headeroffset);
|
|
|
|
} else {
|
|
|
|
param.headeroffset = align_up(param.baseaddress +
|
|
|
|
bootblock.size, sizeof(uint32_t));
|
|
|
|
DEBUG("CBFS header placed behind bootblock (%#x).\n",
|
|
|
|
param.headeroffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!param.cbfsoffset_assigned) {
|
|
|
|
if (param.arch == CBFS_ARCHITECTURE_X86) {
|
|
|
|
param.cbfsoffset = 0;
|
|
|
|
DEBUG("x86 -> CBFS entries start at address 0x0.\n");
|
|
|
|
} else {
|
|
|
|
param.cbfsoffset = align_up(param.headeroffset +
|
|
|
|
sizeof(struct cbfs_header),
|
2015-07-14 22:18:23 +02:00
|
|
|
CBFS_ALIGNMENT);
|
2014-11-10 22:14:24 +01:00
|
|
|
DEBUG("CBFS entries start beind master header (%#x).\n",
|
|
|
|
param.cbfsoffset);
|
2013-01-29 02:45:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
int ret = cbfs_legacy_image_create(&image,
|
|
|
|
param.arch,
|
2015-07-14 22:18:23 +02:00
|
|
|
CBFS_ALIGNMENT,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
&bootblock,
|
|
|
|
param.baseaddress,
|
|
|
|
param.headeroffset,
|
|
|
|
param.cbfsoffset);
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
buffer_delete(&bootblock);
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
return ret;
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
static int cbfs_layout(void)
|
|
|
|
{
|
|
|
|
const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
|
|
|
|
if (!fmap) {
|
|
|
|
LOG("This is a legacy image composed entirely of a single CBFS.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("This image contains the following sections that can be %s with this tool:\n",
|
|
|
|
param.show_immutable ? "accessed" : "manipulated");
|
|
|
|
puts("");
|
2015-05-15 08:14:09 +02:00
|
|
|
for (unsigned i = 0; i < fmap->nareas; ++i) {
|
|
|
|
const struct fmap_area *current = fmap->areas + i;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
|
|
|
|
bool readonly = partitioned_file_fmap_count(param.image_file,
|
|
|
|
partitioned_file_fmap_select_children_of, current) ||
|
|
|
|
region_is_flashmap((const char *)current->name);
|
|
|
|
if (!param.show_immutable && readonly)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
printf("'%s'", current->name);
|
|
|
|
|
|
|
|
// Detect consecutive sections that describe the same region and
|
|
|
|
// show them as aliases. This cannot find equivalent entries
|
|
|
|
// that aren't adjacent; however, fmaptool doesn't generate
|
|
|
|
// FMAPs with such sections, so this convenience feature works
|
|
|
|
// for all but the strangest manually created FMAP binaries.
|
|
|
|
// TODO: This could be done by parsing the FMAP into some kind
|
|
|
|
// of tree that had duplicate lists in addition to child lists,
|
|
|
|
// which would allow covering that weird, unlikely case as well.
|
|
|
|
unsigned lookahead;
|
2015-05-15 08:14:09 +02:00
|
|
|
for (lookahead = 1; i + lookahead < fmap->nareas;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
++lookahead) {
|
|
|
|
const struct fmap_area *consecutive =
|
2015-05-15 08:14:09 +02:00
|
|
|
fmap->areas + i + lookahead;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (consecutive->offset != current->offset ||
|
|
|
|
consecutive->size != current->size)
|
|
|
|
break;
|
|
|
|
printf(", '%s'", consecutive->name);
|
|
|
|
}
|
|
|
|
if (lookahead > 1)
|
|
|
|
fputs(" are aliases for the same region", stdout);
|
|
|
|
|
|
|
|
const char *qualifier = "";
|
|
|
|
if (readonly)
|
|
|
|
qualifier = "read-only, ";
|
|
|
|
else if (region_is_modern_cbfs((const char *)current->name))
|
|
|
|
qualifier = "CBFS, ";
|
2019-06-18 22:02:13 +02:00
|
|
|
else if (current->flags & FMAP_AREA_PRESERVE)
|
|
|
|
qualifier = "preserve, ";
|
2018-04-26 09:26:38 +02:00
|
|
|
printf(" (%ssize %u, offset %u)\n", qualifier, current->size,
|
|
|
|
current->offset);
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
|
2015-05-15 08:14:09 +02:00
|
|
|
i += lookahead - 1;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
}
|
|
|
|
puts("");
|
|
|
|
|
|
|
|
if (param.show_immutable) {
|
|
|
|
puts("It is at least possible to perform the read action on every section listed above.");
|
|
|
|
} else {
|
|
|
|
puts("It is possible to perform either the write action or the CBFS add/remove actions on every section listed above.");
|
|
|
|
puts("To see the image's read-only sections as well, rerun with the -w option.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static int cbfs_print(void)
|
2009-09-22 17:58:19 +02:00
|
|
|
{
|
2013-01-28 19:15:49 +01:00
|
|
|
struct cbfs_image image;
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.headeroffset))
|
2009-09-22 17:58:19 +02:00
|
|
|
return 1;
|
2020-04-28 04:31:03 +02:00
|
|
|
if (param.machine_parseable) {
|
|
|
|
if (verbose)
|
|
|
|
printf("[FMAP REGION]\t%s\n", param.region_name);
|
|
|
|
cbfs_print_parseable_directory(&image);
|
|
|
|
} else {
|
2018-06-05 15:11:01 +02:00
|
|
|
printf("FMAP REGION: %s\n", param.region_name);
|
2020-04-28 04:31:03 +02:00
|
|
|
cbfs_print_directory(&image);
|
2018-06-05 15:11:01 +02:00
|
|
|
}
|
2020-04-28 04:31:03 +02:00
|
|
|
|
2020-05-07 02:27:02 +02:00
|
|
|
if (verbose) {
|
|
|
|
struct mh_cache *mhc = get_mh_cache();
|
|
|
|
if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
struct vb2_hash real_hash = { .algo = mhc->cbfs_hash.algo };
|
|
|
|
cb_err_t err = cbfs_walk(&image, NULL, NULL, &real_hash,
|
|
|
|
CBFS_WALK_WRITEBACK_HASH);
|
|
|
|
if (err != CB_CBFS_NOT_FOUND) {
|
|
|
|
ERROR("Unexpected cbfs_walk() error %d\n", err);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
char *hash_str = bintohex(real_hash.raw,
|
|
|
|
vb2_digest_size(real_hash.algo));
|
|
|
|
printf("[METADATA HASH]\t%s:%s",
|
|
|
|
vb2_get_hash_algorithm_name(real_hash.algo), hash_str);
|
|
|
|
if (!strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) {
|
|
|
|
if (!memcmp(mhc->cbfs_hash.raw, real_hash.raw,
|
|
|
|
vb2_digest_size(real_hash.algo)))
|
|
|
|
printf(":valid");
|
|
|
|
else
|
|
|
|
printf(":invalid");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
free(hash_str);
|
|
|
|
}
|
|
|
|
|
2020-04-28 04:31:03 +02:00
|
|
|
return 0;
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static int cbfs_extract(void)
|
2011-01-13 10:09:21 +01:00
|
|
|
{
|
2013-01-28 07:23:49 +01:00
|
|
|
if (!param.filename) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify -f/--filename.\n");
|
2012-10-30 00:52:36 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-28 07:23:49 +01:00
|
|
|
if (!param.name) {
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("You need to specify -n/--name.\n");
|
2011-01-13 10:09:21 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
struct cbfs_image image;
|
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.headeroffset))
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return 1;
|
2011-01-13 10:09:21 +01:00
|
|
|
|
2015-10-27 19:17:52 +01:00
|
|
|
return cbfs_export_entry(&image, param.name, param.filename,
|
2018-08-09 11:49:52 +02:00
|
|
|
param.arch, !param.unprocessed);
|
2011-01-13 10:09:21 +01:00
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
static int cbfs_write(void)
|
|
|
|
{
|
|
|
|
if (!param.filename) {
|
|
|
|
ERROR("You need to specify a valid input -f/--file.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!partitioned_file_is_partitioned(param.image_file)) {
|
|
|
|
ERROR("This operation isn't valid on legacy images having CBFS master headers\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-10-12 16:46:13 +02:00
|
|
|
if (!param.force && region_is_modern_cbfs(param.region_name)) {
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
ERROR("Target image region '%s' is a CBFS and must be manipulated using add and remove\n",
|
|
|
|
param.region_name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct buffer new_content;
|
|
|
|
if (buffer_from_file(&new_content, param.filename))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (buffer_check_magic(&new_content, FMAP_SIGNATURE,
|
|
|
|
strlen(FMAP_SIGNATURE))) {
|
|
|
|
ERROR("File '%s' appears to be an FMAP and cannot be added to an existing image\n",
|
|
|
|
param.filename);
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
}
|
2016-10-12 16:46:13 +02:00
|
|
|
if (!param.force && buffer_check_magic(&new_content, CBFS_FILE_MAGIC,
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
strlen(CBFS_FILE_MAGIC))) {
|
|
|
|
ERROR("File '%s' appears to be a CBFS and cannot be inserted into a raw region\n",
|
|
|
|
param.filename);
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned offset = 0;
|
|
|
|
if (param.fill_partial_upward && param.fill_partial_downward) {
|
|
|
|
ERROR("You may only specify one of -u and -d.\n");
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
} else if (!param.fill_partial_upward && !param.fill_partial_downward) {
|
|
|
|
if (new_content.size != param.image_region->size) {
|
|
|
|
ERROR("File to add is %zu bytes and would not fill %zu-byte target region (did you mean to pass either -u or -d?)\n",
|
|
|
|
new_content.size, param.image_region->size);
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (new_content.size > param.image_region->size) {
|
|
|
|
ERROR("File to add is %zu bytes and would overflow %zu-byte target region\n",
|
|
|
|
new_content.size, param.image_region->size);
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
}
|
2016-12-06 18:55:26 +01:00
|
|
|
if (param.u64val == (uint64_t)-1) {
|
|
|
|
WARN("Written area will abut %s of target region: any unused space will keep its current contents\n",
|
|
|
|
param.fill_partial_upward ? "bottom" : "top");
|
|
|
|
} else if (param.u64val > 0xff) {
|
|
|
|
ERROR("given fill value (%x) is larger than a byte\n", (unsigned)(param.u64val & 0xff));
|
|
|
|
buffer_delete(&new_content);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
memset(buffer_get(param.image_region),
|
|
|
|
param.u64val & 0xff,
|
|
|
|
buffer_size(param.image_region));
|
|
|
|
}
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (param.fill_partial_downward)
|
|
|
|
offset = param.image_region->size - new_content.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(param.image_region->data + offset, new_content.data,
|
|
|
|
new_content.size);
|
|
|
|
buffer_delete(&new_content);
|
2020-05-07 02:27:02 +02:00
|
|
|
|
|
|
|
return maybe_update_fmap_hash();
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int cbfs_read(void)
|
|
|
|
{
|
|
|
|
if (!param.filename) {
|
|
|
|
ERROR("You need to specify a valid output -f/--file.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!partitioned_file_is_partitioned(param.image_file)) {
|
|
|
|
ERROR("This operation isn't valid on legacy images having CBFS master headers\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return buffer_write_file(param.image_region, param.filename);
|
|
|
|
}
|
|
|
|
|
cbfstool: add a command to duplicate a cbfs instance
The new command allows to create a file where the original CBFS image
is duplicated at a different offset.
The required options of the new command are -D, the offset where the
copy CBFS header is placed, and -s, the size of the new CBFS copy.
When a CBFS is copied, the bootblock area of the source CBFS is
ignored, as well as empty and deleted files in the source CBFS. The
size of the destination CBFS is calculated as the rombase size of the
source CBFS less the bootblock size.
The copy instance can be created in the image only above the original,
which rules out the use of this new command for x86 images. If
necessary, this limitation could be addressed later.
As with other cbfstool commands, unless explicitly specified the
lowest CBFS instance in the image is considered the source. If
necessary, the user can specify the source CBFS using the -H option.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run multiple cbfstool commands on a storm image:
$ cd /tmp
$ cp /build/storm/firmware/image.serial.bin storm.bin
$ cbfstool storm.bin print
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
$ cbfstool storm.bin copy -D 0x420000
E: You need to specify -s/--size.
$ cbfstool storm.bin copy -D 0x420000 -s 0x70000
$ cbfstool storm.bin print
W: Multiple (2) CBFS headers found, using the first one.
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
cbfstool storm.bin print -H 0x420000
storm.bin: 8192 kB, bootblocksize 0, romsize 4784128, offset 0x420040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x420040 raw 416
ddr.mbn 0x420240 raw 25836
rpm.mbn 0x426780 raw 78576
tz.mbn 0x439ac0 raw 85360
fallback/verstage 0x44e880 stage 41620
fallback/romstage 0x458b80 stage 19556
fallback/ramstage 0x45d840 stage 25579
config 0x463c80 raw 2878
fallback/payload 0x464800 payload 64811
u-boot.dtb 0x474580 (unknown) 2993
(empty) 0x475180 null 110168
$ cbfstool storm.bin remove -n config -H 0x420000
$ cbfstool storm.bin copy -H 0x420000 -D 0x620000 -s 0x70000
$ cbfstool storm.bin print -H 0x620000
storm.bin: 8192 kB, bootblocksize 0, romsize 6881280, offset 0x620040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x620040 raw 416
ddr.mbn 0x620240 raw 25836
rpm.mbn 0x626780 raw 78576
tz.mbn 0x639ac0 raw 85360
fallback/verstage 0x64e880 stage 41620
fallback/romstage 0x658b80 stage 19556
fallback/ramstage 0x65d840 stage 25579
fallback/payload 0x663c80 payload 64811
u-boot.dtb 0x673a00 (unknown) 2993
(empty) 0x674600 null 113112
$ cbfstool /build/storm/firmware/image.serial.bin extract -n fallback/payload -f payload1
[..]
$ cbfstool storm.bin extract -H 0x620000 -n fallback/payload -f payload2
[..]
$ diff payload1 payload2
Change-Id: Ieb9205848aec361bb870de0d284dff06c597564f
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: b8d3c1b09a47ca24d2d2effc6de0e89d1b0a8903
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Change-Id: I227e607ccf7a9a8e2a1f3c6bbc506b8d29a35b1b
Original-Reviewed-on: https://chromium-review.googlesource.com/237561
Reviewed-on: http://review.coreboot.org/9742
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 04:26:54 +01:00
|
|
|
static int cbfs_copy(void)
|
|
|
|
{
|
2015-11-20 19:22:50 +01:00
|
|
|
struct cbfs_image src_image;
|
2015-11-20 21:48:18 +01:00
|
|
|
struct buffer src_buf;
|
cbfstool: add a command to duplicate a cbfs instance
The new command allows to create a file where the original CBFS image
is duplicated at a different offset.
The required options of the new command are -D, the offset where the
copy CBFS header is placed, and -s, the size of the new CBFS copy.
When a CBFS is copied, the bootblock area of the source CBFS is
ignored, as well as empty and deleted files in the source CBFS. The
size of the destination CBFS is calculated as the rombase size of the
source CBFS less the bootblock size.
The copy instance can be created in the image only above the original,
which rules out the use of this new command for x86 images. If
necessary, this limitation could be addressed later.
As with other cbfstool commands, unless explicitly specified the
lowest CBFS instance in the image is considered the source. If
necessary, the user can specify the source CBFS using the -H option.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run multiple cbfstool commands on a storm image:
$ cd /tmp
$ cp /build/storm/firmware/image.serial.bin storm.bin
$ cbfstool storm.bin print
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
$ cbfstool storm.bin copy -D 0x420000
E: You need to specify -s/--size.
$ cbfstool storm.bin copy -D 0x420000 -s 0x70000
$ cbfstool storm.bin print
W: Multiple (2) CBFS headers found, using the first one.
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
cbfstool storm.bin print -H 0x420000
storm.bin: 8192 kB, bootblocksize 0, romsize 4784128, offset 0x420040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x420040 raw 416
ddr.mbn 0x420240 raw 25836
rpm.mbn 0x426780 raw 78576
tz.mbn 0x439ac0 raw 85360
fallback/verstage 0x44e880 stage 41620
fallback/romstage 0x458b80 stage 19556
fallback/ramstage 0x45d840 stage 25579
config 0x463c80 raw 2878
fallback/payload 0x464800 payload 64811
u-boot.dtb 0x474580 (unknown) 2993
(empty) 0x475180 null 110168
$ cbfstool storm.bin remove -n config -H 0x420000
$ cbfstool storm.bin copy -H 0x420000 -D 0x620000 -s 0x70000
$ cbfstool storm.bin print -H 0x620000
storm.bin: 8192 kB, bootblocksize 0, romsize 6881280, offset 0x620040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x620040 raw 416
ddr.mbn 0x620240 raw 25836
rpm.mbn 0x626780 raw 78576
tz.mbn 0x639ac0 raw 85360
fallback/verstage 0x64e880 stage 41620
fallback/romstage 0x658b80 stage 19556
fallback/ramstage 0x65d840 stage 25579
fallback/payload 0x663c80 payload 64811
u-boot.dtb 0x673a00 (unknown) 2993
(empty) 0x674600 null 113112
$ cbfstool /build/storm/firmware/image.serial.bin extract -n fallback/payload -f payload1
[..]
$ cbfstool storm.bin extract -H 0x620000 -n fallback/payload -f payload2
[..]
$ diff payload1 payload2
Change-Id: Ieb9205848aec361bb870de0d284dff06c597564f
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: b8d3c1b09a47ca24d2d2effc6de0e89d1b0a8903
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Change-Id: I227e607ccf7a9a8e2a1f3c6bbc506b8d29a35b1b
Original-Reviewed-on: https://chromium-review.googlesource.com/237561
Reviewed-on: http://review.coreboot.org/9742
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 04:26:54 +01:00
|
|
|
|
2015-11-20 21:48:18 +01:00
|
|
|
if (!param.source_region) {
|
|
|
|
ERROR("You need to specify -R/--source-region.\n");
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
return 1;
|
2015-11-20 21:48:18 +01:00
|
|
|
}
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
|
2015-11-20 21:48:18 +01:00
|
|
|
/* Obtain the source region and convert it to a cbfs_image. */
|
|
|
|
if (!partitioned_file_read_region(&src_buf, param.image_file,
|
|
|
|
param.source_region)) {
|
|
|
|
ERROR("Region not found in image: %s\n", param.source_region);
|
cbfstool: add a command to duplicate a cbfs instance
The new command allows to create a file where the original CBFS image
is duplicated at a different offset.
The required options of the new command are -D, the offset where the
copy CBFS header is placed, and -s, the size of the new CBFS copy.
When a CBFS is copied, the bootblock area of the source CBFS is
ignored, as well as empty and deleted files in the source CBFS. The
size of the destination CBFS is calculated as the rombase size of the
source CBFS less the bootblock size.
The copy instance can be created in the image only above the original,
which rules out the use of this new command for x86 images. If
necessary, this limitation could be addressed later.
As with other cbfstool commands, unless explicitly specified the
lowest CBFS instance in the image is considered the source. If
necessary, the user can specify the source CBFS using the -H option.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run multiple cbfstool commands on a storm image:
$ cd /tmp
$ cp /build/storm/firmware/image.serial.bin storm.bin
$ cbfstool storm.bin print
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
$ cbfstool storm.bin copy -D 0x420000
E: You need to specify -s/--size.
$ cbfstool storm.bin copy -D 0x420000 -s 0x70000
$ cbfstool storm.bin print
W: Multiple (2) CBFS headers found, using the first one.
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
cbfstool storm.bin print -H 0x420000
storm.bin: 8192 kB, bootblocksize 0, romsize 4784128, offset 0x420040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x420040 raw 416
ddr.mbn 0x420240 raw 25836
rpm.mbn 0x426780 raw 78576
tz.mbn 0x439ac0 raw 85360
fallback/verstage 0x44e880 stage 41620
fallback/romstage 0x458b80 stage 19556
fallback/ramstage 0x45d840 stage 25579
config 0x463c80 raw 2878
fallback/payload 0x464800 payload 64811
u-boot.dtb 0x474580 (unknown) 2993
(empty) 0x475180 null 110168
$ cbfstool storm.bin remove -n config -H 0x420000
$ cbfstool storm.bin copy -H 0x420000 -D 0x620000 -s 0x70000
$ cbfstool storm.bin print -H 0x620000
storm.bin: 8192 kB, bootblocksize 0, romsize 6881280, offset 0x620040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x620040 raw 416
ddr.mbn 0x620240 raw 25836
rpm.mbn 0x626780 raw 78576
tz.mbn 0x639ac0 raw 85360
fallback/verstage 0x64e880 stage 41620
fallback/romstage 0x658b80 stage 19556
fallback/ramstage 0x65d840 stage 25579
fallback/payload 0x663c80 payload 64811
u-boot.dtb 0x673a00 (unknown) 2993
(empty) 0x674600 null 113112
$ cbfstool /build/storm/firmware/image.serial.bin extract -n fallback/payload -f payload1
[..]
$ cbfstool storm.bin extract -H 0x620000 -n fallback/payload -f payload2
[..]
$ diff payload1 payload2
Change-Id: Ieb9205848aec361bb870de0d284dff06c597564f
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: b8d3c1b09a47ca24d2d2effc6de0e89d1b0a8903
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Change-Id: I227e607ccf7a9a8e2a1f3c6bbc506b8d29a35b1b
Original-Reviewed-on: https://chromium-review.googlesource.com/237561
Reviewed-on: http://review.coreboot.org/9742
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 04:26:54 +01:00
|
|
|
return 1;
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
}
|
cbfstool: add a command to duplicate a cbfs instance
The new command allows to create a file where the original CBFS image
is duplicated at a different offset.
The required options of the new command are -D, the offset where the
copy CBFS header is placed, and -s, the size of the new CBFS copy.
When a CBFS is copied, the bootblock area of the source CBFS is
ignored, as well as empty and deleted files in the source CBFS. The
size of the destination CBFS is calculated as the rombase size of the
source CBFS less the bootblock size.
The copy instance can be created in the image only above the original,
which rules out the use of this new command for x86 images. If
necessary, this limitation could be addressed later.
As with other cbfstool commands, unless explicitly specified the
lowest CBFS instance in the image is considered the source. If
necessary, the user can specify the source CBFS using the -H option.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run multiple cbfstool commands on a storm image:
$ cd /tmp
$ cp /build/storm/firmware/image.serial.bin storm.bin
$ cbfstool storm.bin print
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
$ cbfstool storm.bin copy -D 0x420000
E: You need to specify -s/--size.
$ cbfstool storm.bin copy -D 0x420000 -s 0x70000
$ cbfstool storm.bin print
W: Multiple (2) CBFS headers found, using the first one.
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
cbfstool storm.bin print -H 0x420000
storm.bin: 8192 kB, bootblocksize 0, romsize 4784128, offset 0x420040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x420040 raw 416
ddr.mbn 0x420240 raw 25836
rpm.mbn 0x426780 raw 78576
tz.mbn 0x439ac0 raw 85360
fallback/verstage 0x44e880 stage 41620
fallback/romstage 0x458b80 stage 19556
fallback/ramstage 0x45d840 stage 25579
config 0x463c80 raw 2878
fallback/payload 0x464800 payload 64811
u-boot.dtb 0x474580 (unknown) 2993
(empty) 0x475180 null 110168
$ cbfstool storm.bin remove -n config -H 0x420000
$ cbfstool storm.bin copy -H 0x420000 -D 0x620000 -s 0x70000
$ cbfstool storm.bin print -H 0x620000
storm.bin: 8192 kB, bootblocksize 0, romsize 6881280, offset 0x620040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x620040 raw 416
ddr.mbn 0x620240 raw 25836
rpm.mbn 0x626780 raw 78576
tz.mbn 0x639ac0 raw 85360
fallback/verstage 0x64e880 stage 41620
fallback/romstage 0x658b80 stage 19556
fallback/ramstage 0x65d840 stage 25579
fallback/payload 0x663c80 payload 64811
u-boot.dtb 0x673a00 (unknown) 2993
(empty) 0x674600 null 113112
$ cbfstool /build/storm/firmware/image.serial.bin extract -n fallback/payload -f payload1
[..]
$ cbfstool storm.bin extract -H 0x620000 -n fallback/payload -f payload2
[..]
$ diff payload1 payload2
Change-Id: Ieb9205848aec361bb870de0d284dff06c597564f
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: b8d3c1b09a47ca24d2d2effc6de0e89d1b0a8903
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Change-Id: I227e607ccf7a9a8e2a1f3c6bbc506b8d29a35b1b
Original-Reviewed-on: https://chromium-review.googlesource.com/237561
Reviewed-on: http://review.coreboot.org/9742
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 04:26:54 +01:00
|
|
|
|
2015-11-20 21:48:18 +01:00
|
|
|
if (cbfs_image_from_buffer(&src_image, &src_buf, param.headeroffset))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return cbfs_copy_instance(&src_image, param.image_region);
|
cbfstool: add a command to duplicate a cbfs instance
The new command allows to create a file where the original CBFS image
is duplicated at a different offset.
The required options of the new command are -D, the offset where the
copy CBFS header is placed, and -s, the size of the new CBFS copy.
When a CBFS is copied, the bootblock area of the source CBFS is
ignored, as well as empty and deleted files in the source CBFS. The
size of the destination CBFS is calculated as the rombase size of the
source CBFS less the bootblock size.
The copy instance can be created in the image only above the original,
which rules out the use of this new command for x86 images. If
necessary, this limitation could be addressed later.
As with other cbfstool commands, unless explicitly specified the
lowest CBFS instance in the image is considered the source. If
necessary, the user can specify the source CBFS using the -H option.
BRANCH=storm
BUG=chrome-os-partner:34161, chromium:445938
TEST=run multiple cbfstool commands on a storm image:
$ cd /tmp
$ cp /build/storm/firmware/image.serial.bin storm.bin
$ cbfstool storm.bin print
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
$ cbfstool storm.bin copy -D 0x420000
E: You need to specify -s/--size.
$ cbfstool storm.bin copy -D 0x420000 -s 0x70000
$ cbfstool storm.bin print
W: Multiple (2) CBFS headers found, using the first one.
storm.bin: 8192 kB, bootblocksize 34472, romsize 458752, offset 0x8700
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x8700 raw 416
ddr.mbn 0x8900 raw 25836
rpm.mbn 0xee40 raw 78576
tz.mbn 0x22180 raw 85360
fallback/verstage 0x36f40 stage 41620
fallback/romstage 0x41240 stage 19556
fallback/ramstage 0x45f00 stage 25579
config 0x4c340 raw 2878
fallback/payload 0x4cec0 payload 64811
u-boot.dtb 0x5cc40 (unknown) 2993
(empty) 0x5d840 null 75608
cbfstool storm.bin print -H 0x420000
storm.bin: 8192 kB, bootblocksize 0, romsize 4784128, offset 0x420040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x420040 raw 416
ddr.mbn 0x420240 raw 25836
rpm.mbn 0x426780 raw 78576
tz.mbn 0x439ac0 raw 85360
fallback/verstage 0x44e880 stage 41620
fallback/romstage 0x458b80 stage 19556
fallback/ramstage 0x45d840 stage 25579
config 0x463c80 raw 2878
fallback/payload 0x464800 payload 64811
u-boot.dtb 0x474580 (unknown) 2993
(empty) 0x475180 null 110168
$ cbfstool storm.bin remove -n config -H 0x420000
$ cbfstool storm.bin copy -H 0x420000 -D 0x620000 -s 0x70000
$ cbfstool storm.bin print -H 0x620000
storm.bin: 8192 kB, bootblocksize 0, romsize 6881280, offset 0x620040
alignment: 64 bytes, architecture: arm
Name Offset Type Size
cdt.mbn 0x620040 raw 416
ddr.mbn 0x620240 raw 25836
rpm.mbn 0x626780 raw 78576
tz.mbn 0x639ac0 raw 85360
fallback/verstage 0x64e880 stage 41620
fallback/romstage 0x658b80 stage 19556
fallback/ramstage 0x65d840 stage 25579
fallback/payload 0x663c80 payload 64811
u-boot.dtb 0x673a00 (unknown) 2993
(empty) 0x674600 null 113112
$ cbfstool /build/storm/firmware/image.serial.bin extract -n fallback/payload -f payload1
[..]
$ cbfstool storm.bin extract -H 0x620000 -n fallback/payload -f payload2
[..]
$ diff payload1 payload2
Change-Id: Ieb9205848aec361bb870de0d284dff06c597564f
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: b8d3c1b09a47ca24d2d2effc6de0e89d1b0a8903
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Change-Id: I227e607ccf7a9a8e2a1f3c6bbc506b8d29a35b1b
Original-Reviewed-on: https://chromium-review.googlesource.com/237561
Reviewed-on: http://review.coreboot.org/9742
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-12-24 04:26:54 +01:00
|
|
|
}
|
|
|
|
|
2016-01-27 00:08:56 +01:00
|
|
|
static int cbfs_compact(void)
|
|
|
|
{
|
|
|
|
struct cbfs_image image;
|
|
|
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
|
|
|
param.headeroffset))
|
|
|
|
return 1;
|
|
|
|
WARN("Compacting a CBFS doesn't honor alignment or fixed addresses!\n");
|
|
|
|
return cbfs_compact_instance(&image);
|
|
|
|
}
|
|
|
|
|
2017-09-19 14:39:58 +02:00
|
|
|
static int cbfs_expand(void)
|
|
|
|
{
|
|
|
|
struct buffer src_buf;
|
|
|
|
|
|
|
|
/* Obtain the source region. */
|
|
|
|
if (!partitioned_file_read_region(&src_buf, param.image_file,
|
|
|
|
param.region_name)) {
|
|
|
|
ERROR("Region not found in image: %s\n", param.source_region);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cbfs_expand_to_region(param.image_region);
|
|
|
|
}
|
|
|
|
|
2017-09-20 11:59:18 +02:00
|
|
|
static int cbfs_truncate(void)
|
|
|
|
{
|
|
|
|
struct buffer src_buf;
|
|
|
|
|
|
|
|
/* Obtain the source region. */
|
|
|
|
if (!partitioned_file_read_region(&src_buf, param.image_file,
|
|
|
|
param.region_name)) {
|
|
|
|
ERROR("Region not found in image: %s\n", param.source_region);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t size;
|
|
|
|
int result = cbfs_truncate_space(param.image_region, &size);
|
|
|
|
printf("0x%x\n", size);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-10-21 23:24:57 +02:00
|
|
|
static const struct command commands[] = {
|
2018-05-29 11:18:14 +02:00
|
|
|
{"add", "H:r:f:n:t:c:b:a:p:yvA:j:gh?", cbfs_add, true, true},
|
2017-10-31 01:38:04 +01:00
|
|
|
{"add-flat-binary", "H:r:f:n:l:e:c:b:p:vA:gh?", cbfs_add_flat_binary,
|
2016-01-14 13:22:37 +01:00
|
|
|
true, true},
|
2021-06-29 21:26:41 +02:00
|
|
|
{"add-payload", "H:r:f:n:c:b:a:C:I:p:vA:gh?", cbfs_add_payload,
|
2016-01-14 13:22:37 +01:00
|
|
|
true, true},
|
2020-05-28 22:12:02 +02:00
|
|
|
{"add-stage", "a:H:r:f:n:t:c:b:P:QS:p:yvA:gh?", cbfs_add_stage,
|
2016-01-14 13:22:37 +01:00
|
|
|
true, true},
|
|
|
|
{"add-int", "H:r:i:n:b:vgh?", cbfs_add_integer, true, true},
|
2018-05-29 11:18:14 +02:00
|
|
|
{"add-master-header", "H:r:vh?j:", cbfs_add_master_header, true, true},
|
2016-01-27 00:08:56 +01:00
|
|
|
{"compact", "r:h?", cbfs_compact, true, true},
|
2015-11-20 21:48:18 +01:00
|
|
|
{"copy", "r:R:h?", cbfs_copy, true, true},
|
2015-07-14 22:18:23 +02:00
|
|
|
{"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true},
|
2018-08-09 11:49:52 +02:00
|
|
|
{"extract", "H:r:m:n:f:Uvh?", cbfs_extract, true, false},
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
{"layout", "wvh?", cbfs_layout, false, false},
|
2016-01-26 22:35:34 +01:00
|
|
|
{"print", "H:r:vkh?", cbfs_print, true, false},
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
{"read", "r:f:vh?", cbfs_read, true, false},
|
|
|
|
{"remove", "H:r:n:vh?", cbfs_remove, true, true},
|
2016-12-06 18:55:26 +01:00
|
|
|
{"write", "r:f:i:Fudvh?", cbfs_write, true, true},
|
2017-09-19 14:39:58 +02:00
|
|
|
{"expand", "r:h?", cbfs_expand, true, true},
|
2017-09-20 11:59:18 +02:00
|
|
|
{"truncate", "r:h?", cbfs_truncate, true, true},
|
2012-10-30 00:52:36 +01:00
|
|
|
};
|
|
|
|
|
2018-11-20 13:54:49 +01:00
|
|
|
enum {
|
|
|
|
/* begin after ASCII characters */
|
2020-04-14 09:14:44 +02:00
|
|
|
LONGOPT_START = 256,
|
|
|
|
LONGOPT_IBB = LONGOPT_START,
|
2020-11-21 19:35:10 +01:00
|
|
|
LONGOPT_EXT_WIN_BASE,
|
|
|
|
LONGOPT_EXT_WIN_SIZE,
|
2020-04-14 09:14:44 +02:00
|
|
|
LONGOPT_END,
|
2018-11-20 13:54:49 +01:00
|
|
|
};
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static struct option long_options[] = {
|
2014-12-24 00:59:57 +01:00
|
|
|
{"alignment", required_argument, 0, 'a' },
|
2014-11-10 22:14:24 +01:00
|
|
|
{"base-address", required_argument, 0, 'b' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"bootblock", required_argument, 0, 'B' },
|
|
|
|
{"cmdline", required_argument, 0, 'C' },
|
|
|
|
{"compression", required_argument, 0, 'c' },
|
2018-05-29 11:18:14 +02:00
|
|
|
{"topswap-size", required_argument, 0, 'j' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"empty-fits", required_argument, 0, 'x' },
|
2014-11-10 22:14:24 +01:00
|
|
|
{"entry-point", required_argument, 0, 'e' },
|
|
|
|
{"file", required_argument, 0, 'f' },
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
{"fill-downward", no_argument, 0, 'd' },
|
|
|
|
{"fill-upward", no_argument, 0, 'u' },
|
|
|
|
{"flashmap", required_argument, 0, 'M' },
|
|
|
|
{"fmap-regions", required_argument, 0, 'r' },
|
2016-10-12 16:46:13 +02:00
|
|
|
{"force", no_argument, 0, 'F' },
|
2015-11-20 21:48:18 +01:00
|
|
|
{"source-region", required_argument, 0, 'R' },
|
2015-10-01 15:54:04 +02:00
|
|
|
{"hash-algorithm",required_argument, 0, 'A' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"header-offset", required_argument, 0, 'H' },
|
|
|
|
{"help", no_argument, 0, 'h' },
|
|
|
|
{"ignore-sec", required_argument, 0, 'S' },
|
|
|
|
{"initrd", required_argument, 0, 'I' },
|
2014-11-10 22:14:24 +01:00
|
|
|
{"int", required_argument, 0, 'i' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"load-address", required_argument, 0, 'l' },
|
2014-11-10 22:14:24 +01:00
|
|
|
{"machine", required_argument, 0, 'm' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"name", required_argument, 0, 'n' },
|
|
|
|
{"offset", required_argument, 0, 'o' },
|
2017-10-31 01:38:04 +01:00
|
|
|
{"padding", required_argument, 0, 'p' },
|
2020-05-28 22:12:02 +02:00
|
|
|
{"pow2page", no_argument, 0, 'Q' },
|
2018-06-04 19:32:46 +02:00
|
|
|
{"ucode-region", required_argument, 0, 'q' },
|
2014-12-24 00:59:57 +01:00
|
|
|
{"size", required_argument, 0, 's' },
|
|
|
|
{"type", required_argument, 0, 't' },
|
2014-11-10 22:14:24 +01:00
|
|
|
{"verbose", no_argument, 0, 'v' },
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
{"with-readonly", no_argument, 0, 'w' },
|
2015-09-16 00:00:23 +02:00
|
|
|
{"xip", no_argument, 0, 'y' },
|
2016-01-14 13:22:37 +01:00
|
|
|
{"gen-attribute", no_argument, 0, 'g' },
|
2016-01-26 22:35:34 +01:00
|
|
|
{"mach-parseable",no_argument, 0, 'k' },
|
2018-08-09 11:49:52 +02:00
|
|
|
{"unprocessed", no_argument, 0, 'U' },
|
2018-11-20 13:54:49 +01:00
|
|
|
{"ibb", no_argument, 0, LONGOPT_IBB },
|
2020-11-21 19:35:10 +01:00
|
|
|
{"ext-win-base", required_argument, 0, LONGOPT_EXT_WIN_BASE },
|
|
|
|
{"ext-win-size", required_argument, 0, LONGOPT_EXT_WIN_SIZE },
|
2014-11-10 22:14:24 +01:00
|
|
|
{NULL, 0, 0, 0 }
|
2009-09-22 17:58:19 +02:00
|
|
|
};
|
|
|
|
|
2020-11-21 01:52:03 +01:00
|
|
|
static int get_region_offset(long long int offset, uint32_t *region_offset)
|
|
|
|
{
|
|
|
|
/* If offset is not negative, no transformation required. */
|
|
|
|
if (offset >= 0) {
|
|
|
|
*region_offset = offset;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate offset from start of region. */
|
|
|
|
return convert_region_offset(-offset, region_offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int calculate_region_offsets(void)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (param.baseaddress_assigned)
|
|
|
|
ret |= get_region_offset(param.baseaddress_input, ¶m.baseaddress);
|
|
|
|
if (param.headeroffset_assigned)
|
|
|
|
ret |= get_region_offset(param.headeroffset_input, ¶m.headeroffset);
|
|
|
|
if (param.cbfsoffset_assigned)
|
|
|
|
ret |= get_region_offset(param.cbfsoffset_input, ¶m.cbfsoffset);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
static int dispatch_command(struct command command)
|
|
|
|
{
|
|
|
|
if (command.accesses_region) {
|
|
|
|
assert(param.image_file);
|
|
|
|
|
|
|
|
if (partitioned_file_is_partitioned(param.image_file)) {
|
2016-12-16 14:51:53 +01:00
|
|
|
INFO("Performing operation on '%s' region...\n",
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.region_name);
|
|
|
|
}
|
|
|
|
if (!partitioned_file_read_region(param.image_region,
|
|
|
|
param.image_file, param.region_name)) {
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (command.modifies_region) {
|
|
|
|
// We (intentionally) don't support overwriting the FMAP
|
|
|
|
// section. If you find yourself wanting to do this,
|
|
|
|
// consider creating a new image rather than performing
|
|
|
|
// whatever hacky transformation you were planning.
|
|
|
|
if (region_is_flashmap(param.region_name)) {
|
|
|
|
ERROR("Image region '%s' is read-only because it contains the FMAP.\n",
|
|
|
|
param.region_name);
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
// We don't allow writing raw data to regions that
|
|
|
|
// contain nested regions, since doing so would
|
|
|
|
// overwrite all such subregions.
|
|
|
|
if (partitioned_file_region_contains_nested(
|
|
|
|
param.image_file, param.region_name)) {
|
|
|
|
ERROR("Image region '%s' is read-only because it contains nested regions.\n",
|
|
|
|
param.region_name);
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2020-11-21 01:52:03 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Once image region is read, input offsets can be adjusted accordingly if the
|
|
|
|
* inputs are provided as negative integers i.e. offsets from end of region.
|
|
|
|
*/
|
|
|
|
if (calculate_region_offsets())
|
|
|
|
return 1;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (command.function()) {
|
|
|
|
if (partitioned_file_is_partitioned(param.image_file)) {
|
|
|
|
ERROR("Failed while operating on '%s' region!\n",
|
|
|
|
param.region_name);
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-30 00:52:36 +01:00
|
|
|
static void usage(char *name)
|
2009-09-22 17:58:19 +02:00
|
|
|
{
|
|
|
|
printf
|
2010-04-24 23:24:06 +02:00
|
|
|
("cbfstool: Management utility for CBFS formatted ROM images\n\n"
|
2012-10-30 00:52:36 +01:00
|
|
|
"USAGE:\n" " %s [-h]\n"
|
2013-01-28 07:39:43 +01:00
|
|
|
" %s FILE COMMAND [-v] [PARAMETERS]...\n\n" "OPTIONs:\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" -H header_offset Do not search for header; use this offset*\n"
|
2015-05-07 11:39:22 +02:00
|
|
|
" -T Output top-aligned memory address\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" -u Accept short data; fill upward/from bottom\n"
|
|
|
|
" -d Accept short data; fill downward/from top\n"
|
2016-10-12 16:46:13 +02:00
|
|
|
" -F Force action\n"
|
2016-10-13 18:24:10 +02:00
|
|
|
" -g Generate position and alignment arguments\n"
|
2018-08-09 11:49:52 +02:00
|
|
|
" -U Unprocessed; don't decompress or make ELF\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" -v Provide verbose output\n"
|
|
|
|
" -h Display this help message\n\n"
|
2020-11-21 19:35:10 +01:00
|
|
|
" --ext-win-base Base of extended decode window in host address\n"
|
|
|
|
" space(x86 only)\n"
|
|
|
|
" --ext-win-size Size of extended decode window in host address\n"
|
|
|
|
" space(x86 only)\n"
|
2009-09-22 17:58:19 +02:00
|
|
|
"COMMANDs:\n"
|
2015-10-01 15:54:04 +02:00
|
|
|
" add [-r image,regions] -f FILE -n NAME -t TYPE [-A hash] \\\n"
|
2016-05-09 20:53:34 +02:00
|
|
|
" [-c compression] [-b base-address | -a alignment] \\\n"
|
2018-05-29 11:18:14 +02:00
|
|
|
" [-p padding size] [-y|--xip if TYPE is FSP] \\\n"
|
2020-11-21 19:35:10 +01:00
|
|
|
" [-j topswap-size] (Intel CPUs only) [--ibb] \\\n"
|
|
|
|
" [--ext-win-base win-base --ext-win-size win-size] "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Add a component\n"
|
2018-05-29 11:18:14 +02:00
|
|
|
" "
|
|
|
|
" -j valid size: 0x10000 0x20000 0x40000 0x80000 0x100000 \n"
|
2015-10-01 15:54:04 +02:00
|
|
|
" add-payload [-r image,regions] -f FILE -n NAME [-A hash] \\\n"
|
2015-12-04 19:27:11 +01:00
|
|
|
" [-c compression] [-b base-address] \\\n"
|
|
|
|
" (linux specific: [-C cmdline] [-I initrd]) "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Add a payload to the ROM\n"
|
2015-10-01 15:54:04 +02:00
|
|
|
" add-stage [-r image,regions] -f FILE -n NAME [-A hash] \\\n"
|
2015-12-04 19:27:11 +01:00
|
|
|
" [-c compression] [-b base] [-S section-to-ignore] \\\n"
|
2021-06-16 17:16:05 +02:00
|
|
|
" [-a alignment] [-Q|--pow2page] \\\n"
|
2020-11-21 19:35:10 +01:00
|
|
|
" [-y|--xip] [--ibb] \\\n"
|
|
|
|
" [--ext-win-base win-base --ext-win-size win-size] "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Add a stage to the ROM\n"
|
2015-12-04 19:27:11 +01:00
|
|
|
" add-flat-binary [-r image,regions] -f FILE -n NAME \\\n"
|
|
|
|
" [-A hash] -l load-address -e entry-point \\\n"
|
|
|
|
" [-c compression] [-b base] "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Add a 32bit flat mode binary\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" add-int [-r image,regions] -i INTEGER -n NAME [-b base] "
|
2013-07-09 19:39:13 +02:00
|
|
|
"Add a raw 64-bit integer value\n"
|
2018-05-29 11:18:14 +02:00
|
|
|
" add-master-header [-r image,regions] \\ \n"
|
|
|
|
" [-j topswap-size] (Intel CPUs only) "
|
2015-09-10 15:28:27 +02:00
|
|
|
"Add a legacy CBFS master header\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" remove [-r image,regions] -n NAME "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Remove a component\n"
|
2016-01-27 00:08:56 +01:00
|
|
|
" compact -r image,regions "
|
|
|
|
"Defragment CBFS image.\n"
|
2015-11-20 21:48:18 +01:00
|
|
|
" copy -r image,regions -R source-region "
|
|
|
|
"Create a copy (duplicate) cbfs instance in fmap\n"
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
" create -m ARCH -s size [-b bootblock offset] \\\n"
|
2015-08-26 10:40:00 +02:00
|
|
|
" [-o CBFS offset] [-H header offset] [-B bootblock] "
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
"Create a legacy ROM file with CBFS master header*\n"
|
|
|
|
" create -M flashmap [-r list,of,regions,containing,cbfses] "
|
|
|
|
"Create a new-style partitioned firmware image\n"
|
|
|
|
" layout [-w] "
|
|
|
|
"List mutable (or, with -w, readable) image regions\n"
|
2020-05-07 02:27:02 +02:00
|
|
|
" print [-r image,regions] [-k] "
|
2012-10-30 00:52:36 +01:00
|
|
|
"Show the contents of the ROM\n"
|
2018-08-09 11:49:52 +02:00
|
|
|
" extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U] "
|
|
|
|
"Extracts a file from ROM\n"
|
2016-12-06 18:55:26 +01:00
|
|
|
" write [-F] -r image,regions -f file [-u | -d] [-i int] "
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
"Write file into same-size [or larger] raw region\n"
|
|
|
|
" read [-r fmap-region] -f file "
|
|
|
|
"Extract raw region contents into binary file\n"
|
2017-09-20 11:59:18 +02:00
|
|
|
" truncate [-r fmap-region] "
|
|
|
|
"Truncate CBFS and print new size on stdout\n"
|
2017-09-19 14:39:58 +02:00
|
|
|
" expand [-r fmap-region] "
|
|
|
|
"Expand CBFS to span entire region\n"
|
2015-03-06 00:38:03 +01:00
|
|
|
"OFFSETs:\n"
|
2015-05-07 11:39:22 +02:00
|
|
|
" Numbers accompanying -b, -H, and -o switches* may be provided\n"
|
|
|
|
" in two possible formats: if their value is greater than\n"
|
2015-03-06 00:38:03 +01:00
|
|
|
" 0x80000000, they are interpreted as a top-aligned x86 memory\n"
|
|
|
|
" address; otherwise, they are treated as an offset into flash.\n"
|
2018-04-08 15:05:09 +02:00
|
|
|
"ARCHes:\n", name, name
|
2012-10-30 00:52:36 +01:00
|
|
|
);
|
2018-04-08 15:05:09 +02:00
|
|
|
print_supported_architectures();
|
|
|
|
|
|
|
|
printf("TYPEs:\n");
|
2010-04-24 23:24:06 +02:00
|
|
|
print_supported_filetypes();
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
printf(
|
|
|
|
"\n* Note that these actions and switches are only valid when\n"
|
|
|
|
" working with legacy images whose structure is described\n"
|
|
|
|
" primarily by a CBFS master header. New-style images, in\n"
|
|
|
|
" contrast, exclusively make use of an FMAP to describe their\n"
|
|
|
|
" layout: this must minimally contain an '%s' section\n"
|
|
|
|
" specifying the location of this FMAP itself and a '%s'\n"
|
|
|
|
" section describing the primary CBFS. It should also be noted\n"
|
|
|
|
" that, when working with such images, the -F and -r switches\n"
|
2021-12-13 19:28:29 +01:00
|
|
|
" default to '%s' for convenience, and the -b switch becomes\n"
|
2015-05-07 11:39:22 +02:00
|
|
|
" relative to the selected CBFS region's lowest address.\n"
|
|
|
|
" The one exception to this rule is the top-aligned address,\n"
|
|
|
|
" which is always relative to the end of the entire image\n"
|
|
|
|
" rather than relative to the local region; this is true for\n"
|
|
|
|
" for both input (sufficiently large) and output (-T) data.\n",
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
SECTION_NAME_FMAP, SECTION_NAME_PRIMARY_CBFS,
|
|
|
|
SECTION_NAME_PRIMARY_CBFS
|
|
|
|
);
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
2020-04-14 09:14:44 +02:00
|
|
|
static bool valid_opt(size_t i, int c)
|
|
|
|
{
|
|
|
|
/* Check if it is one of the optstrings supported by the command. */
|
|
|
|
if (strchr(commands[i].optstring, c))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if it is one of the non-ASCII characters. Currently, the
|
|
|
|
* non-ASCII characters are only checked against the valid list
|
|
|
|
* irrespective of the command.
|
|
|
|
*/
|
|
|
|
if (c >= LONGOPT_START && c < LONGOPT_END)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-09-22 17:58:19 +02:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2012-07-17 21:17:15 +02:00
|
|
|
size_t i;
|
2012-10-30 00:52:36 +01:00
|
|
|
int c;
|
2009-09-22 17:58:19 +02:00
|
|
|
|
|
|
|
if (argc < 3) {
|
2012-10-30 00:52:36 +01:00
|
|
|
usage(argv[0]);
|
2009-09-22 17:58:19 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
char *image_name = argv[1];
|
2009-09-22 17:58:19 +02:00
|
|
|
char *cmd = argv[2];
|
2012-10-30 00:52:36 +01:00
|
|
|
optind += 2;
|
2009-09-22 17:58:19 +02:00
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
|
|
|
if (strcmp(cmd, commands[i].name) != 0)
|
|
|
|
continue;
|
2012-10-30 00:52:36 +01:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
char *suffix = NULL;
|
|
|
|
int option_index = 0;
|
|
|
|
|
|
|
|
c = getopt_long(argc, argv, commands[i].optstring,
|
|
|
|
long_options, &option_index);
|
2016-08-01 23:18:29 +02:00
|
|
|
if (c == -1) {
|
|
|
|
if (optind < argc) {
|
|
|
|
ERROR("%s: excessive argument -- '%s'"
|
|
|
|
"\n", argv[0], argv[optind]);
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
2016-08-01 23:18:29 +02:00
|
|
|
}
|
2012-10-30 00:52:36 +01:00
|
|
|
|
2018-10-11 11:01:30 +02:00
|
|
|
/* Filter out illegal long options */
|
2020-04-14 09:14:44 +02:00
|
|
|
if (!valid_opt(i, c)) {
|
|
|
|
ERROR("%s: invalid option -- '%d'\n",
|
2013-01-28 07:39:43 +01:00
|
|
|
argv[0], c);
|
2012-10-30 00:52:36 +01:00
|
|
|
c = '?';
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(c) {
|
|
|
|
case 'n':
|
2013-01-28 07:23:49 +01:00
|
|
|
param.name = optarg;
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if (intfiletype(optarg) != ((uint64_t) - 1))
|
2013-01-28 07:23:49 +01:00
|
|
|
param.type = intfiletype(optarg);
|
2012-10-30 00:52:36 +01:00
|
|
|
else
|
2013-01-28 07:23:49 +01:00
|
|
|
param.type = strtoul(optarg, NULL, 0);
|
|
|
|
if (param.type == 0)
|
2013-01-28 07:39:43 +01:00
|
|
|
WARN("Unknown type '%s' ignored\n",
|
2012-10-30 00:52:36 +01:00
|
|
|
optarg);
|
|
|
|
break;
|
2015-05-08 06:00:05 +02:00
|
|
|
case 'c': {
|
2017-01-11 18:38:11 +01:00
|
|
|
if (strcmp(optarg, "precompression") == 0) {
|
|
|
|
param.precompression = 1;
|
|
|
|
break;
|
|
|
|
}
|
2015-05-08 06:00:05 +02:00
|
|
|
int algo = cbfs_parse_comp_algo(optarg);
|
|
|
|
if (algo >= 0)
|
|
|
|
param.compression = algo;
|
2012-10-30 00:52:36 +01:00
|
|
|
else
|
2015-05-08 06:00:05 +02:00
|
|
|
WARN("Unknown compression '%s' ignored.\n",
|
|
|
|
optarg);
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
2015-05-08 06:00:05 +02:00
|
|
|
}
|
2015-10-01 15:54:04 +02:00
|
|
|
case 'A': {
|
2020-03-14 00:43:34 +01:00
|
|
|
if (!vb2_lookup_hash_alg(optarg, ¶m.hash)) {
|
2015-10-01 15:54:04 +02:00
|
|
|
ERROR("Unknown hash algorithm '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
case 'M':
|
|
|
|
param.fmap = optarg;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
param.region_name = optarg;
|
|
|
|
break;
|
2015-11-20 21:48:18 +01:00
|
|
|
case 'R':
|
|
|
|
param.source_region = optarg;
|
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'b':
|
2020-11-21 01:52:03 +01:00
|
|
|
param.baseaddress_input = strtoll(optarg, &suffix, 0);
|
2016-08-01 21:37:42 +02:00
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid base address '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2013-01-29 02:45:12 +01:00
|
|
|
// baseaddress may be zero on non-x86, so we
|
|
|
|
// need an explicit "baseaddress_assigned".
|
|
|
|
param.baseaddress_assigned = 1;
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
|
|
|
case 'l':
|
2016-08-01 21:37:42 +02:00
|
|
|
param.loadaddress = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid load address '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
|
|
|
case 'e':
|
2016-08-01 21:37:42 +02:00
|
|
|
param.entrypoint = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid entry point '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
|
|
|
case 's':
|
2013-01-28 07:23:49 +01:00
|
|
|
param.size = strtoul(optarg, &suffix, 0);
|
2016-08-01 21:37:42 +02:00
|
|
|
if (!*optarg) {
|
|
|
|
ERROR("Empty size specified.\n");
|
|
|
|
return 1;
|
2012-10-30 00:52:36 +01:00
|
|
|
}
|
2016-08-01 21:37:42 +02:00
|
|
|
switch (tolower((int)suffix[0])) {
|
|
|
|
case 'k':
|
|
|
|
param.size *= 1024;
|
|
|
|
break;
|
|
|
|
case 'm':
|
2013-01-28 07:23:49 +01:00
|
|
|
param.size *= 1024 * 1024;
|
2016-08-01 21:37:42 +02:00
|
|
|
break;
|
|
|
|
case '\0':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ERROR("Invalid suffix for size '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
2012-10-30 00:52:36 +01:00
|
|
|
}
|
2014-08-09 17:44:39 +02:00
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'B':
|
2013-01-28 07:23:49 +01:00
|
|
|
param.bootblock = optarg;
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
2013-01-29 02:45:12 +01:00
|
|
|
case 'H':
|
2020-11-21 01:52:03 +01:00
|
|
|
param.headeroffset_input = strtoll(optarg, &suffix, 0);
|
2016-08-01 21:37:42 +02:00
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid header offset '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2013-01-29 02:45:12 +01:00
|
|
|
param.headeroffset_assigned = 1;
|
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'a':
|
2016-08-01 21:37:42 +02:00
|
|
|
param.alignment = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid alignment '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
2017-10-31 01:38:04 +01:00
|
|
|
case 'p':
|
|
|
|
param.padding = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid pad size '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
2020-05-28 22:12:02 +02:00
|
|
|
case 'Q':
|
|
|
|
param.force_pow2_pagesize = 1;
|
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'o':
|
2020-11-21 01:52:03 +01:00
|
|
|
param.cbfsoffset_input = strtoll(optarg, &suffix, 0);
|
2016-08-01 21:37:42 +02:00
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid cbfs offset '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2014-11-10 22:14:24 +01:00
|
|
|
param.cbfsoffset_assigned = 1;
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
|
|
|
case 'f':
|
2013-01-28 07:23:49 +01:00
|
|
|
param.filename = optarg;
|
2012-10-30 00:52:36 +01:00
|
|
|
break;
|
2016-10-12 16:46:13 +02:00
|
|
|
case 'F':
|
|
|
|
param.force = 1;
|
|
|
|
break;
|
2013-07-09 19:39:13 +02:00
|
|
|
case 'i':
|
2016-08-01 21:37:42 +02:00
|
|
|
param.u64val = strtoull(optarg, &suffix, 0);
|
2016-12-12 18:38:01 +01:00
|
|
|
param.u64val_assigned = 1;
|
2016-08-01 21:37:42 +02:00
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid int parameter '%s'.\n",
|
|
|
|
optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
2013-07-09 19:39:13 +02:00
|
|
|
break;
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
case 'u':
|
|
|
|
param.fill_partial_upward = true;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
param.fill_partial_downward = true;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
param.show_immutable = true;
|
2013-01-28 20:46:02 +01:00
|
|
|
break;
|
2018-05-29 11:18:14 +02:00
|
|
|
case 'j':
|
|
|
|
param.topswap_size = strtol(optarg, NULL, 0);
|
|
|
|
if (!is_valid_topswap())
|
|
|
|
return 1;
|
|
|
|
break;
|
2018-06-04 19:32:46 +02:00
|
|
|
case 'q':
|
|
|
|
param.ucode_region = optarg;
|
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'v':
|
|
|
|
verbose++;
|
|
|
|
break;
|
2012-11-16 23:48:22 +01:00
|
|
|
case 'm':
|
2014-02-03 05:37:28 +01:00
|
|
|
param.arch = string_to_arch(optarg);
|
2012-11-16 23:48:22 +01:00
|
|
|
break;
|
2013-08-27 20:22:21 +02:00
|
|
|
case 'I':
|
|
|
|
param.initrd = optarg;
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
param.cmdline = optarg;
|
|
|
|
break;
|
2014-10-30 19:44:20 +01:00
|
|
|
case 'S':
|
|
|
|
param.ignore_section = optarg;
|
|
|
|
break;
|
2015-09-16 00:00:23 +02:00
|
|
|
case 'y':
|
|
|
|
param.stage_xip = true;
|
|
|
|
break;
|
2016-01-14 13:22:37 +01:00
|
|
|
case 'g':
|
|
|
|
param.autogen_attr = true;
|
|
|
|
break;
|
2016-01-26 22:35:34 +01:00
|
|
|
case 'k':
|
|
|
|
param.machine_parseable = true;
|
|
|
|
break;
|
2018-08-09 11:49:52 +02:00
|
|
|
case 'U':
|
|
|
|
param.unprocessed = true;
|
|
|
|
break;
|
2018-11-20 13:54:49 +01:00
|
|
|
case LONGOPT_IBB:
|
|
|
|
param.ibb = true;
|
|
|
|
break;
|
2020-11-21 19:35:10 +01:00
|
|
|
case LONGOPT_EXT_WIN_BASE:
|
|
|
|
param.ext_win_base = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid ext window base '%s'.\n", optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LONGOPT_EXT_WIN_SIZE:
|
|
|
|
param.ext_win_size = strtoul(optarg, &suffix, 0);
|
|
|
|
if (!*optarg || (suffix && *suffix)) {
|
|
|
|
ERROR("Invalid ext window size '%s'.\n", optarg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
2012-10-30 00:52:36 +01:00
|
|
|
case 'h':
|
|
|
|
case '?':
|
|
|
|
usage(argv[0]);
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
if (commands[i].function == cbfs_create) {
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (param.fmap) {
|
|
|
|
struct buffer flashmap;
|
|
|
|
if (buffer_from_file(&flashmap, param.fmap))
|
|
|
|
return 1;
|
|
|
|
param.image_file = partitioned_file_create(
|
|
|
|
image_name, &flashmap);
|
|
|
|
buffer_delete(&flashmap);
|
|
|
|
} else if (param.size) {
|
|
|
|
param.image_file = partitioned_file_create_flat(
|
|
|
|
image_name, param.size);
|
|
|
|
} else {
|
|
|
|
ERROR("You need to specify a valid -M/--flashmap or -s/--size.\n");
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
2015-12-09 18:39:31 +01:00
|
|
|
bool write_access = commands[i].modifies_region;
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
param.image_file =
|
2015-12-09 18:39:31 +01:00
|
|
|
partitioned_file_reopen(image_name,
|
|
|
|
write_access);
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
}
|
|
|
|
if (!param.image_file)
|
|
|
|
return 1;
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
unsigned num_regions = 1;
|
|
|
|
for (const char *list = strchr(param.region_name, ','); list;
|
|
|
|
list = strchr(list + 1, ','))
|
|
|
|
++num_regions;
|
|
|
|
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
// If the action needs to read an image region, as indicated by
|
|
|
|
// having accesses_region set in its command struct, that
|
|
|
|
// region's buffer struct will be stored here and the client
|
|
|
|
// will receive a pointer to it via param.image_region. It
|
|
|
|
// need not write the buffer back to the image file itself,
|
|
|
|
// since this behavior can be requested via its modifies_region
|
|
|
|
// field. Additionally, it should never free the region buffer,
|
|
|
|
// as that is performed automatically once it completes.
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
struct buffer image_regions[num_regions];
|
|
|
|
memset(image_regions, 0, sizeof(image_regions));
|
|
|
|
|
|
|
|
bool seen_primary_cbfs = false;
|
|
|
|
char region_name_scratch[strlen(param.region_name) + 1];
|
|
|
|
strcpy(region_name_scratch, param.region_name);
|
|
|
|
param.region_name = strtok(region_name_scratch, ",");
|
|
|
|
for (unsigned region = 0; region < num_regions; ++region) {
|
|
|
|
if (!param.region_name) {
|
|
|
|
ERROR("Encountered illegal degenerate region name in -r list\n");
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
partitioned_file_close(param.image_file);
|
|
|
|
return 1;
|
|
|
|
}
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)
|
|
|
|
== 0)
|
|
|
|
seen_primary_cbfs = true;
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
param.image_region = image_regions + region;
|
|
|
|
if (dispatch_command(commands[i])) {
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
partitioned_file_close(param.image_file);
|
|
|
|
return 1;
|
|
|
|
}
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
|
|
|
|
param.region_name = strtok(NULL, ",");
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
}
|
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (commands[i].function == cbfs_create && !seen_primary_cbfs) {
|
|
|
|
ERROR("The creation -r list must include the mandatory '%s' section.\n",
|
|
|
|
SECTION_NAME_PRIMARY_CBFS);
|
|
|
|
ERROR("The image will be left unmodified.\n");
|
|
|
|
partitioned_file_close(param.image_file);
|
|
|
|
return 1;
|
|
|
|
}
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
if (commands[i].modifies_region) {
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
assert(param.image_file);
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
for (unsigned region = 0; region < num_regions;
|
|
|
|
++region) {
|
|
|
|
|
|
|
|
if (!partitioned_file_write_region(
|
|
|
|
param.image_file,
|
|
|
|
image_regions + region)) {
|
|
|
|
partitioned_file_close(
|
|
|
|
param.image_file);
|
|
|
|
return 1;
|
|
|
|
}
|
cbfstool: Restructure around support for reading/writing portions of files
The buffer API that cbfstool uses to read and write files only directly supports
one-shot operations on whole files. This adds an intermediate partitioned_file
module that sits on top of the buffer system and has an awareness of FMAP
entries. It provides an easy way to get a buffer for an individual region of a
larger image file based on FMAP section name, as well as incrementally write
those smaller buffers back to the backing file at the appropriate offset. The
module has two distinct modes of operation:
- For new images whose layout is described exclusively by an FMAP section, all
the aforementioned functionality will be available.
- For images in the current format, where the CBFS master header serves as the
root of knowledge of the image's size and layout, the module falls back to a
legacy operation mode, where it only allows manipulation of the entire image
as one unit, but exposes this support through the same interface by mapping
the region named SECTION_NAME_PRIMARY_CBFS ("COREBOOT") to the whole file.
The tool is presently only ported onto the new module running in legacy mode:
higher-level support for true "partitioned" images will be forthcoming. However,
as part of this change, the crusty cbfs_image_from_file() and
cbfs_image_write_file() abstractions are removed and replaced with a single
cbfs_image function, cbfs_image_from_buffer(), as well as centralized image
reading/writing directly in cbfstool's main() function. This reduces the
boilerplate required to implement each new action, makes the create action much
more similar to the others, and will make implementing additional actions and
adding in support for the new format much easier.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom images with and without this patch
and diff their hexdumps. Ensure that no differences occur at different locations
from the diffs between subsequent builds of an identical source tree. Then flash
a full new build onto nyan_big and watch it boot normally.
BRANCH=None
Change-Id: I25578c7b223bc8434c3074cb0dd8894534f8c500
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 7e1c96a48e7a27fc6b90289d35e6e169d5e7ad20
Original-Change-Id: Ia4a1a4c48df42b9ec2d6b9471b3a10eb7b24bb39
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265581
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10134
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-25 21:40:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
partitioned_file_close(param.image_file);
|
cbfstool: New image format w/ required FMAP and w/o CBFS master header
These new-style firmware images use the FMAP of the root of knowledge
about their layout, which allows them to have sections containing raw
data whose offset and size can easily be determined at runtime or when
modifying or flashing the image. Furthermore, they can even have
multiple CBFSes, each of which occupies a different FMAP region. It is
assumed that the first entry of each CBFS, including the primary one,
will be located right at the start of its region. This means that the
bootblock needs to be moved into its own FMAP region, but makes the
CBFS master header obsolete because, with the exception of the version
and alignment, all its fields are redundant once its CBFS has an entry
in the FMAP. The version code will be addressed in a future commit
before the new format comes into use, while the alignment will just be
defined to 64 bytes in both cbfstool and coreboot itself, since
there's almost no reason to ever change it in practice. The version
code field and all necessary coreboot changes will come separately.
BUG=chromium:470407
TEST=Build panther and nyan_big coreboot.rom and image.bin images with
and without this patch, diff their hexdumps, and note that no
locations differ except for those that do between subsequent builds of
the same codebase. Try working with new-style images: use fmaptool to
produce an FMAP section from an fmd file having raw sections and
multiple CBFSes, pass the resulting file to cbfstool create -M -F,
then try printing its layout and CBFSes' contents, add and remove CBFS
files, and read and write raw sections.
BRANCH=None
Change-Id: I7dd2578d2143d0cedd652fdba5b22221fcc2184a
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 8a670322297f83135b929a5b20ff2bd0e7d2abd3
Original-Change-Id: Ib86fb50edc66632f4e6f717909bbe4efb6c874e5
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/265863
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10135
Tested-by: build bot (Jenkins)
2015-03-18 20:36:27 +01:00
|
|
|
return 0;
|
2009-09-22 17:58:19 +02:00
|
|
|
}
|
|
|
|
|
2013-01-28 07:39:43 +01:00
|
|
|
ERROR("Unknown command '%s'.\n", cmd);
|
2012-10-30 00:52:36 +01:00
|
|
|
usage(argv[0]);
|
2009-09-22 17:58:19 +02:00
|
|
|
return 1;
|
|
|
|
}
|