CBFS: Automate ROM image layout and remove hardcoded offsets
Non-x86 boards currently need to hardcode the position of their CBFS master header in a Kconfig. This is very brittle because it is usually put in between the bootblock and the first CBFS entry, without any checks to guarantee that it won't overlap either of those. It is not fun to debug random failures that move and disappear with tiny alignment changes because someone decided to write "ORBC1112" over some part of your data section (in a way that is not visible in the symbolized .elf binaries, only in the final image). This patch seeks to prevent those issues and reduce the need for manual configuration by making the image layout a completely automated part of cbfstool. Since automated placement of the CBFS header means we can no longer hardcode its position into coreboot, this patch takes the existing x86 solution of placing a pointer to the header at the very end of the CBFS-managed section of the ROM and generalizes it to all architectures. This is now even possible with the read-only/read-write split in ChromeOS, since coreboot knows how large that section is from the CBFS_SIZE Kconfig (which is by default equal to ROM_SIZE, but can be changed on systems that place other data next to coreboot/CBFS in ROM). Also adds a feature to cbfstool that makes the -B (bootblock file name) argument on image creation optional, since we have recently found valid use cases for CBFS images that are not the first boot medium of the device (instead opened by an earlier bootloader that can already interpret CBFS) and therefore don't really need a bootblock. BRANCH=None BUG=None TEST=Built and booted on Veyron_Pinky, Nyan_Blaze and Falco. Change-Id: Ib715bb8db258e602991b34f994750a2d3e2d5adf Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: e9879c0fbd57f105254c54bacb3e592acdcad35c Original-Change-Id: Ifcc755326832755cfbccd6f0a12104cba28a20af Original-Signed-off-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/229975 Reviewed-on: http://review.coreboot.org/9620 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
committed by
Patrick Georgi
parent
f780c40f40
commit
efcee767de
@@ -31,9 +31,7 @@ subdirs-y += armv4/ armv7/
|
||||
###############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
|
||||
CBFSTOOL_PRE1_OPTS = -m arm -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) \
|
||||
-H $(CONFIG_CBFS_HEADER_ROM_OFFSET) \
|
||||
-o $(CONFIG_CBFS_ROM_OFFSET) -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE1_OPTS = -m arm -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE_OPTS = -b 0
|
||||
endif
|
||||
|
||||
|
@@ -34,9 +34,7 @@ subdirs-y += armv8/
|
||||
################################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
|
||||
CBFSTOOL_PRE1_OPTS = -m arm64 -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) \
|
||||
-H $(CONFIG_CBFS_HEADER_ROM_OFFSET) \
|
||||
-o $(CONFIG_CBFS_ROM_OFFSET) -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE1_OPTS = -m arm64 -s $(CONFIG_CBFS_SIZE)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ARM64),y)
|
||||
|
@@ -24,9 +24,7 @@
|
||||
###############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPS),y)
|
||||
CBFSTOOL_PRE1_OPTS = -m mips -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) \
|
||||
-H $(CONFIG_CBFS_HEADER_ROM_OFFSET) \
|
||||
-o $(CONFIG_CBFS_ROM_OFFSET) -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE1_OPTS = -m mips -s $(CONFIG_CBFS_SIZE)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
|
@@ -72,7 +72,7 @@ $(objcbfs)/romstage.debug: $$(romstage-objs)
|
||||
romstage-c-ccopts += $(riscv_flags)
|
||||
romstage-S-ccopts += $(riscv_asm_flags)
|
||||
|
||||
CBFSTOOL_PRE1_OPTS = -v -m riscv -b $(CONFIG_BOOTBLOCK_ROM_OFFSET) -H $(CONFIG_CBFS_HEADER_ROM_OFFSET) -o $(CONFIG_CBFS_ROM_OFFSET) -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE1_OPTS = -v -m riscv -s $(CONFIG_CBFS_SIZE)
|
||||
CBFSTOOL_PRE_OPTS = -v
|
||||
|
||||
endif
|
||||
|
@@ -15,22 +15,6 @@ config CPU_SPECIFIC_OPTIONS
|
||||
select BOOTBLOCK_CONSOLE
|
||||
select CPU_HAS_BOOTBLOCK_INIT
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x00
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex
|
||||
default 0x10
|
||||
|
||||
# This is the maximum size bootblock that the BROM will load. If the bootblock
|
||||
# gets larger, this will generate a build failure, rather than a silent
|
||||
# "coreboot won't run" failure.
|
||||
# Normally, we would place romstage at 0x5fe0, but we place it a little lower to
|
||||
# satisfy the 64 byte alignment.
|
||||
config CBFS_ROM_OFFSET
|
||||
default 0x5fc0
|
||||
|
||||
## TODO Change this to some better address not overlapping bootblock when
|
||||
## cbfstool supports creating header in arbitrary location.
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
|
@@ -25,8 +25,3 @@ config CPU_MIPS
|
||||
select ARCH_VERSTAGE_MIPS
|
||||
select ARCH_ROMSTAGE_MIPS
|
||||
select ARCH_RAMSTAGE_MIPS
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
depends on CPU_MIPS
|
||||
default 0x00
|
||||
|
@@ -10,17 +10,3 @@ config CPU_TI_AM335X
|
||||
select GENERIC_UDELAY
|
||||
bool
|
||||
default n
|
||||
|
||||
if CPU_TI_AM335X
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
# Calculated by BL1 + max bootblock size.
|
||||
default 0x4c00
|
||||
|
||||
## TODO Change this to some better address not overlapping bootblock when
|
||||
## cbfstool supports creating header in arbitrary location.
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x40
|
||||
|
||||
endif
|
||||
|
@@ -86,10 +86,9 @@
|
||||
#define CBFS_HEADER_VERSION2 0x31313132
|
||||
#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2
|
||||
|
||||
/** this is the master cbfs header - it need to be located somewhere available
|
||||
to bootblock (to load romstage). Where it actually lives is up to coreboot.
|
||||
On x86, a pointer to this header will live at 0xFFFFFFFC.
|
||||
For other platforms, you need to define CONFIG_CBFS_HEADER_ROM_OFFSET */
|
||||
/* this is the master cbfs header - it must be located somewhere available
|
||||
* to bootblock (to load romstage). The last 4 bytes in the image contain its
|
||||
* relative offset from the end of the image (as a 32-bit signed integer). */
|
||||
|
||||
struct cbfs_header {
|
||||
uint32_t magic;
|
||||
|
@@ -34,10 +34,6 @@
|
||||
* CBFS_CORE_WITH_LZMA (must be #define)
|
||||
* if defined, ulzma() must exist for decompression of data streams
|
||||
*
|
||||
* CBFS_HEADER_ROM_ADDRESS
|
||||
* ROM address (offset) of CBFS header. Underlying CBFS media may interpret
|
||||
* it in other way so we call this "address".
|
||||
*
|
||||
* ERROR(x...)
|
||||
* print an error message x (in printf format)
|
||||
*
|
||||
@@ -58,6 +54,7 @@
|
||||
* on failure */
|
||||
const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
|
||||
{
|
||||
size_t offset;
|
||||
const struct cbfs_header *header;
|
||||
struct cbfs_media default_media;
|
||||
|
||||
@@ -68,22 +65,34 @@ const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
|
||||
return CBFS_HEADER_INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
media->open(media);
|
||||
DEBUG("CBFS_HEADER_ROM_ADDRESS: 0x%x/0x%x\n", CBFS_HEADER_ROM_ADDRESS,
|
||||
CONFIG_ROM_SIZE);
|
||||
header = media->map(media, CBFS_HEADER_ROM_ADDRESS, sizeof(*header));
|
||||
|
||||
/* TODO: allow negative offsets from the end of the CBFS image at media
|
||||
* layer (like libpayload) so we can combine these two cases. */
|
||||
if (IS_ENABLED(CONFIG_ARCH_X86)) {
|
||||
offset = *(int32_t *)(uintptr_t)0xfffffffc;
|
||||
header = media->map(media, offset, sizeof(*header));
|
||||
} else {
|
||||
int32_t rel_offset;
|
||||
if (!media->read(media, &rel_offset, CONFIG_CBFS_SIZE -
|
||||
sizeof(int32_t), sizeof(int32_t))) {
|
||||
ERROR("Could not read CBFS master header offset!\n");
|
||||
return CBFS_HEADER_INVALID_ADDRESS;
|
||||
}
|
||||
offset = CONFIG_CBFS_SIZE + rel_offset;
|
||||
header = media->map(media, offset, sizeof(*header));
|
||||
}
|
||||
DEBUG("CBFS header offset: 0x%zx/0x%x\n", offset, CONFIG_ROM_SIZE);
|
||||
media->close(media);
|
||||
|
||||
if (header == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
|
||||
ERROR("Failed to load CBFS header from 0x%x\n",
|
||||
CBFS_HEADER_ROM_ADDRESS);
|
||||
ERROR("Failed to load CBFS header from 0x%zx\n", offset);
|
||||
return CBFS_HEADER_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
|
||||
ERROR("Could not find valid CBFS master header at %x: "
|
||||
"%x vs %x.\n", CBFS_HEADER_ROM_ADDRESS, CBFS_HEADER_MAGIC,
|
||||
ERROR("Could not find valid CBFS master header at %#zx: "
|
||||
"magic %#.8x vs %#.8x.\n", offset, CBFS_HEADER_MAGIC,
|
||||
ntohl(header->magic));
|
||||
if (header->magic == 0xffffffff) {
|
||||
ERROR("Maybe ROM is not mapped properly?\n");
|
||||
|
@@ -42,11 +42,4 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CBFS_HEADER_ROM_OFFSET) && (CONFIG_CBFS_HEADER_ROM_OFFSET)
|
||||
# define CBFS_HEADER_ROM_ADDRESS (CONFIG_CBFS_HEADER_ROM_OFFSET)
|
||||
#else
|
||||
// Indirect address: only works on 32bit top-aligned systems.
|
||||
# define CBFS_HEADER_ROM_ADDRESS (*(uint32_t *)0xfffffffc)
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_CBFS_CORE */
|
||||
|
@@ -53,16 +53,4 @@ config DRAM_SIZE_MB
|
||||
int
|
||||
default 1024
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex
|
||||
default 0x0100000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex
|
||||
default 0x0110000
|
||||
|
||||
endif # BOARD_EMULATION_QEMU_ARMV7
|
||||
|
@@ -54,18 +54,6 @@ config DRAM_SIZE_MB
|
||||
# 0x0011_0000: CBFS data
|
||||
# 0x0100_0000: reserved for ramstage
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex
|
||||
default 0x10000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex
|
||||
default 0x10040
|
||||
|
||||
config RAMTOP
|
||||
hex
|
||||
default 0x1000000
|
||||
|
@@ -35,13 +35,4 @@ config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
default "soc/imgtec/pistachio/bootblock.c"
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex
|
||||
default 0x8100
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
# Effectively the maximum size of the bootblock
|
||||
hex
|
||||
default 0x8000
|
||||
|
||||
endif
|
||||
|
@@ -37,16 +37,4 @@ config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
default "soc/marvell/bg4cd/bootblock.c"
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex
|
||||
default 0x0008000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex
|
||||
default 0x0018000
|
||||
|
||||
endif
|
||||
|
@@ -24,18 +24,6 @@ config BOOTBLOCK_CPU_INIT
|
||||
bootblock must load microcode or copy data from ROM before
|
||||
searching for the bootblock.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x18000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex "offset of CBFS data in ROM"
|
||||
default 0x18080
|
||||
|
||||
config TEGRA124_MODEL_TD570D
|
||||
bool "TD570D"
|
||||
|
||||
|
@@ -42,22 +42,10 @@ config BOOTBLOCK_CPU_INIT
|
||||
bootblock must load microcode or copy data from ROM before
|
||||
searching for the bootblock.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config MAX_CPUS
|
||||
int
|
||||
default 2
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x40000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex "offset of CBFS data in ROM"
|
||||
default 0x40080
|
||||
|
||||
config MTS_DIRECTORY
|
||||
string "Directory where MTS microcode files are located"
|
||||
default "3rdparty/cpu/nvidia/tegra132/current/prod"
|
||||
|
@@ -21,18 +21,6 @@ config CBFS_SIZE
|
||||
coreboot blob elsewhere in the system. Make sure this config option
|
||||
is fine tuned in the board config file.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x1b4000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex "offset of CBFS data in ROM"
|
||||
default 0x1b4080
|
||||
|
||||
config MBN_ENCAPSULATION
|
||||
depends on USE_BLOBS
|
||||
bool "bootblock encapsulation for ipq8064"
|
||||
|
@@ -37,22 +37,4 @@ config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
default "soc/rockchip/rk3288/bootblock.c"
|
||||
|
||||
# ROM image layout.
|
||||
#
|
||||
# 0x00000 Combined bootblock and ID Block
|
||||
# 0x08000 Master CBFS header.
|
||||
# 0x18000 Free for CBFS data.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0x0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex
|
||||
default 0x0010000
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
hex
|
||||
default 0x0010100
|
||||
|
||||
endif
|
||||
|
@@ -9,28 +9,3 @@ config CPU_SAMSUNG_EXYNOS5250
|
||||
select HAVE_UART_SPECIAL
|
||||
bool
|
||||
default n
|
||||
|
||||
if CPU_SAMSUNG_EXYNOS5250
|
||||
|
||||
# ROM image layout.
|
||||
#
|
||||
# 0x0000: vendor-provided BL1 (8k).
|
||||
# 0x2000: bootblock
|
||||
# 0x9FFC-0xA000: BL2 checksum
|
||||
# 0xA000-0xA080: reserved for CBFS master header.
|
||||
# 0xA080: Free for CBFS data.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x9F80
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
# Calculated by BOOTBLOCK_ROM_OFFSET + max bootblock size.
|
||||
hex "offset of CBFS data in ROM"
|
||||
default 0x0A080
|
||||
|
||||
endif
|
||||
|
@@ -10,28 +10,3 @@ config CPU_SAMSUNG_EXYNOS5420
|
||||
select RELOCATABLE_MODULES
|
||||
bool
|
||||
default n
|
||||
|
||||
if CPU_SAMSUNG_EXYNOS5420
|
||||
|
||||
# ROM image layout.
|
||||
#
|
||||
# 0x0000: vendor-provided BL1 (8k).
|
||||
# 0x2000: variable length bootblock checksum header
|
||||
# 0x2010: bootblock
|
||||
# 0x9F80-0xA000: reserved for CBFS master header.
|
||||
# 0xA000: Free for CBFS data.
|
||||
|
||||
config BOOTBLOCK_ROM_OFFSET
|
||||
hex
|
||||
default 0
|
||||
|
||||
config CBFS_HEADER_ROM_OFFSET
|
||||
hex "offset of master CBFS header in ROM"
|
||||
default 0x9F80
|
||||
|
||||
config CBFS_ROM_OFFSET
|
||||
# Calculated by BOOTBLOCK_ROM_OFFSET + max bootblock size.
|
||||
hex "offset of CBFS data in ROM"
|
||||
default 0x0A000
|
||||
|
||||
endif
|
||||
|
Reference in New Issue
Block a user