From 75226bb879837e2e4aa710aadb27dbadb4044ed3 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 30 Mar 2022 20:16:36 +0200 Subject: [PATCH] Makefile.inc: Generate master header and pointer as C structs The makefiles don't like cbfs file names with spaces in them so update the file name with '_' instead of spaces. To keep the master header at the top of cbfs, add a placeholder. This removes the need to handle the cbfs master header in cbfstool. This functionality will be dropped in a later CL. On x86 reserve some space in the linker script to add the pointer. On non-x86 generate a pointer inside a C struct file. As a bonus this would actually fix the master header pointer mechanism on Intel/APL as only the bootblock inside IFWI gets memory mapped. TESTED on thinkpad X201: SeaBIOS correctly finds the cbfs master header. Change-Id: I3ba01be7da1f09a8cac287751497c18cda97d293 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/59132 Tested-by: build bot (Jenkins) Reviewed-by: Raul Rangel --- Makefile.inc | 11 ----------- src/arch/x86/bootblock.ld | 9 +++++++-- src/lib/Makefile.inc | 15 +++++++++++++++ src/lib/cbfs_master_header.c | 30 ++++++++++++++++++++++++++++++ src/lib/master_header_pointer.c | 21 +++++++++++++++++++++ src/security/vboot/Makefile.inc | 2 ++ 6 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 src/lib/cbfs_master_header.c create mode 100644 src/lib/master_header_pointer.c diff --git a/Makefile.inc b/Makefile.inc index 654b366ade..ff2b0c4f15 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -1120,18 +1120,7 @@ else # ifeq ($(CONFIG_ARCH_X86),y) $(CBFSTOOL) $@.tmp write -u \ -r BOOTBLOCK \ -f $(objcbfs)/bootblock.bin - # make space for the CBFS master header pointer. "ptr_" is just - # arbitrary 4 bytes that will be overwritten by add-master-header. - printf "ptr_" > $@.tmp.2 - $(CBFSTOOL) $@.tmp add \ - -f $@.tmp.2 \ - -n "header pointer" \ - -t "cbfs header" \ - -b -4 \ - $(CBFSTOOL_ADD_CMD_OPTIONS) - rm -f $@.tmp.2 endif # ifeq ($(CONFIG_ARCH_X86),y) - $(CBFSTOOL) $@.tmp add-master-header $(TS_OPTIONS) $(CBFSTOOL_ADD_CMD_OPTIONS) $(prebuild-files) true mv $@.tmp $@ else # ifneq ($(CONFIG_UPDATE_IMAGE),y) diff --git a/src/arch/x86/bootblock.ld b/src/arch/x86/bootblock.ld index 0b908bbec6..d59eb27a64 100644 --- a/src/arch/x86/bootblock.ld +++ b/src/arch/x86/bootblock.ld @@ -73,9 +73,14 @@ SECTIONS { _X86_RESET_VECTOR = .; .reset . : { *(.reset); - . = 15; - BYTE(0x00); + . = _X86_RESET_VECTOR_FILLING; + BYTE(0); } + . = 0xfffffffc; + .header_pointer . : { + KEEP(*(.header_pointer)); + } + _X86_RESET_VECTOR_FILLING = 15 - SIZEOF(.header_pointer); _ebootblock = .; } diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index f3da503b8b..a930663047 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -393,3 +393,18 @@ endif ramstage-y += uuid.c romstage-$(CONFIG_SPD_CACHE_IN_FMAP) += spd_cache.c + +cbfs-files-y += cbfs_master_header +cbfs_master_header-file := cbfs_master_header.c:struct +cbfs_master_header-type := "cbfs header" +cbfs_master_header-position := 0 + +ifeq ($(CONFIG_ARCH_X86),y) +$(call src-to-obj,bootblock,$(dir)/header_pointer.c): $(obj)/fmap_config.h +bootblock-y += master_header_pointer.c +else +cbfs-files-y += header_pointer +header_pointer-file := master_header_pointer.c:struct +header_pointer-position := -4 +header_pointer-type := "cbfs header" +endif diff --git a/src/lib/cbfs_master_header.c b/src/lib/cbfs_master_header.c new file mode 100644 index 0000000000..d358d1a37d --- /dev/null +++ b/src/lib/cbfs_master_header.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +struct cbfs_header header = { + .magic = cpu_to_be32(CBFS_HEADER_MAGIC), + .version = cpu_to_be32(CBFS_HEADER_VERSION), + /* + * The offset and romsize fields within the master header are absolute + * values within the boot media. As such, romsize needs to reflect + * 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. + */ + .romsize = cpu_to_be32(FMAP_SECTION_COREBOOT_START + FMAP_SECTION_COREBOOT_SIZE + - FMAP_SECTION_FLASH_START), + /* + * 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. + */ + .bootblocksize = cpu_to_be32(4), + .align = cpu_to_be32(CBFS_ALIGNMENT), + .offset = cpu_to_be32(FMAP_SECTION_COREBOOT_START - FMAP_SECTION_FLASH_START), + .architecture = cpu_to_be32(CBFS_ARCHITECTURE_UNKNOWN), +}; diff --git a/src/lib/master_header_pointer.c b/src/lib/master_header_pointer.c new file mode 100644 index 0000000000..b1146121c5 --- /dev/null +++ b/src/lib/master_header_pointer.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +#if ENV_X86 +__attribute__((used, __section__(".header_pointer"))) +#endif + +#if FMAP_SECTION_COREBOOT_START < (0xffffffff - CONFIG_ROM_SIZE + 1) +#define COREBOOT_CBFS_START (0xffffffff - CONFIG_ROM_SIZE + 1 + FMAP_SECTION_COREBOOT_START) +#else +#define COREBOOT_CBFS_START FMAP_SECTION_COREBOOT_START +#endif + +uint32_t header_pointer = + cpu_to_le32(COREBOOT_CBFS_START + ALIGN_UP(sizeof(struct cbfs_file) + + sizeof("cbfs_master_header"), + CBFS_ATTRIBUTE_ALIGN)); diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc index d604d1c862..2ea5d3005c 100644 --- a/src/security/vboot/Makefile.inc +++ b/src/security/vboot/Makefile.inc @@ -175,6 +175,8 @@ regions-for-file = $(subst $(spc),$(comma),$(sort \ $(regions-for-file-$(1)), \ $(if $(filter $(if $(filter y,$(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)), \ %/romstage,) \ + header_pointer \ + cbfs_master_header \ mts \ %/verstage \ locales \