If CONFIG_CBFS_LOCATION is set to a non-zero value then it means the CBFS flash is not at the very end of memory. In this case, it's unclear if the anchor pointer is an absolute pointer or if it is relative to CONFIG_CBFS_LOCATION. Some devices have been using absolute pointers, but it appears some devices are now using relative pointers there. Since the anchor pointer almost always points to a structure in the last 64K of the rom, it should be possible to auto-detect if the pointer is relative or not.
Signed-off-by: Kevin O'Connor kevin@koconnor.net ---
This parallels a commit in the Google seabios repo (commit a7539dcb). However, that patch unconditionally changes to relative pointers - which would defintely not work if the CBFS was setup with absolute pointers.
I'm hoping auto-detecting absolute vs relative will work in practice, and therefore the same code can be used on both new and old devices.
--- src/fw/coreboot.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index 8fd8449..e0f997d 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -421,6 +421,9 @@ coreboot_cbfs_init(void) return;
struct cbfs_header *hdr = *(void **)(CONFIG_CBFS_LOCATION - 4); + if (CBFS_HEADER_MAGIC && (u32)hdr > CONFIG_CBFS_LOCATION) + // Looks like the pointer is relative to CONFIG_CBFS_LOCATION + hdr = (void*)hdr + CONFIG_CBFS_LOCATION; if (hdr->magic != cpu_to_be32(CBFS_HEADER_MAGIC)) { dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n" , hdr, hdr->magic, cpu_to_be32(CBFS_HEADER_MAGIC));
If CONFIG_CBFS_LOCATION is set to a non-zero value then it means the CBFS flash is not at the very end of memory. In this case, it's unclear if the anchor pointer is an absolute pointer or if it is relative to CONFIG_CBFS_LOCATION. Some devices have been using absolute pointers, but it appears some devices are now using relative pointers there. Since the anchor pointer almost always points to a structure in the last 64K of the rom, it should be possible to auto-detect if the pointer is relative or not.
Signed-off-by: Kevin O'Connor kevin@koconnor.net ---
Previous patch had a typo that broke normal CBFS users. This patch should be better.
--- src/fw/coreboot.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index 8fd8449..b077fe1 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -421,6 +421,9 @@ coreboot_cbfs_init(void) return;
struct cbfs_header *hdr = *(void **)(CONFIG_CBFS_LOCATION - 4); + if (CONFIG_CBFS_LOCATION && (u32)hdr > CONFIG_CBFS_LOCATION) + // Looks like the pointer is relative to CONFIG_CBFS_LOCATION + hdr = (void*)hdr + CONFIG_CBFS_LOCATION; if (hdr->magic != cpu_to_be32(CBFS_HEADER_MAGIC)) { dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n" , hdr, hdr->magic, cpu_to_be32(CBFS_HEADER_MAGIC));
I guess this heuristic should be very unlikely to fail with the current cbfstool implementation, so I'd be fine with it (at least as long as SeaBIOS is x86-only... non-x86 CBFS put the header close to the start address instead).
Still, is anyone except Chrome OS actually using CONFIG_CBFS_LOCATION and absolute offsets? Because we have completely switched over now, and the absolute offset was hacked in as part of our SeaBIOS build script which is now updated, so at least with our SDK you can't really build a new SeaBIOS with the old-style absolute offset unless you intentionally revert some stuff. If there's no other system out there that still relies on absolute offsets, I'd suggest to just switch over to the new relative style completely.