Update EC config and FMAP to reserve room for vboot signatures
This just reserves room. It doesn't actually perform any verification yet. BUG=chrome-os-partner:7459 TEST=manual make BOARD=link dump_fmap build/link/ec.bin Change-Id: I424db1d601a614be3dfe5abb200e24e8bc62e47e Signed-off-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
parent
d5deade06f
commit
3b361af2a7
|
@ -0,0 +1,40 @@
|
|||
In the most general case, the flash layout looks something like this:
|
||||
|
||||
+---------------------+
|
||||
| Reserved for EC use |
|
||||
+---------------------+
|
||||
|
||||
+---------------------+
|
||||
| Vblock B |
|
||||
+---------------------+
|
||||
| RW firmware B |
|
||||
+---------------------+
|
||||
|
||||
+---------------------+
|
||||
| Vblock A |
|
||||
+---------------------+
|
||||
| RW firmware A |
|
||||
+---------------------+
|
||||
|
||||
+---------------------+
|
||||
| FMAP |
|
||||
+---------------------+
|
||||
| Public root key |
|
||||
+---------------------+
|
||||
| Read-only firmware |
|
||||
+---------------------+
|
||||
|
||||
|
||||
BIOS firmware (and kernel) put the vblock info at the start of each image
|
||||
where it's easy to find. The Blizzard EC expects the firmware vector table
|
||||
to come first, so we have to put the vblock at the end. This means we have
|
||||
to know where to look for it, but that's built into the FMAP and the RO
|
||||
firmware anyway, so that's not an issue.
|
||||
|
||||
The RO firmware doesn't need a vblock of course, but it does need some
|
||||
reserved space for vboot-related things.
|
||||
|
||||
Using SHA256/RSA4096, the vblock is 2468 bytes (0x9a4), while the public
|
||||
root key is 1064 bytes (0x428) and the current FMAP is 644 bytes (0x284). If
|
||||
we reserve 4K at the top of each FW image, that should give us plenty of
|
||||
room for vboot-related stuff.
|
|
@ -22,14 +22,24 @@
|
|||
#define CONFIG_FW_A_OFF CONFIG_FW_IMAGE_SIZE
|
||||
#define CONFIG_FW_B_OFF (2 * CONFIG_FW_IMAGE_SIZE)
|
||||
|
||||
/* FIXME(wfrichar): Replace with real GBB size & location. */
|
||||
#define CONFIG_FW_RO_GBB_SIZE CONFIG_FLASH_BANK_SIZE
|
||||
#define CONFIG_FW_RO_GBB_OFF (CONFIG_FW_RO_OFF + CONFIG_FW_IMAGE_SIZE - \
|
||||
CONFIG_FW_RO_GBB_SIZE)
|
||||
#define CONFIG_FW_RO_SIZE (CONFIG_FW_IMAGE_SIZE - CONFIG_FW_RO_GBB_SIZE)
|
||||
#define CONFIG_FW_A_SIZE CONFIG_FW_IMAGE_SIZE
|
||||
#define CONFIG_FW_B_SIZE CONFIG_FW_IMAGE_SIZE
|
||||
|
||||
/* We'll put the vboot stuff at the top of each image, since the vector table
|
||||
* has to go at the start. 4K should be enough for what we need. 2K isn't. */
|
||||
#define CONFIG_VBOOT_REGION_SIZE 0x1000
|
||||
#define CONFIG_VBOOT_ROOTKEY_SIZE 0x800
|
||||
#define CONFIG_VBOOT_REGION_OFF (CONFIG_FW_IMAGE_SIZE \
|
||||
- CONFIG_VBOOT_REGION_SIZE)
|
||||
/* Specifics for each image */
|
||||
#define CONFIG_FW_RO_SIZE CONFIG_VBOOT_REGION_OFF
|
||||
#define CONFIG_FW_A_SIZE CONFIG_VBOOT_REGION_OFF
|
||||
#define CONFIG_FW_B_SIZE CONFIG_VBOOT_REGION_OFF
|
||||
#define CONFIG_VBOOT_ROOTKEY_OFF (CONFIG_FW_RO_OFF \
|
||||
+ CONFIG_VBOOT_REGION_OFF)
|
||||
#define CONFIG_FMAP_OFF (CONFIG_VBOOT_ROOTKEY_OFF \
|
||||
+ CONFIG_VBOOT_ROOTKEY_SIZE)
|
||||
#define CONFIG_VBLOCK_A_OFF (CONFIG_FW_A_OFF + CONFIG_FW_A_SIZE)
|
||||
#define CONFIG_VBLOCK_B_OFF (CONFIG_FW_B_OFF + CONFIG_FW_B_SIZE)
|
||||
#define CONFIG_VBLOCK_A_SIZE CONFIG_VBOOT_REGION_SIZE
|
||||
#define CONFIG_VBLOCK_B_SIZE CONFIG_VBOOT_REGION_SIZE
|
||||
|
||||
/* Number of IRQ vectors on the NVIC */
|
||||
#define CONFIG_IRQ_COUNT 132
|
||||
|
|
|
@ -38,7 +38,6 @@ typedef struct _FmapAreaHeader {
|
|||
|
||||
|
||||
#define NUM_EC_FMAP_AREAS 14
|
||||
|
||||
const struct _ec_fmap {
|
||||
FmapHeader header;
|
||||
FmapAreaHeader area[NUM_EC_FMAP_AREAS];
|
||||
|
@ -78,22 +77,22 @@ const struct _ec_fmap {
|
|||
|
||||
/* Other RO stuff: FMAP, GBB, etc. */
|
||||
{
|
||||
/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
|
||||
.area_name = "FMAP",
|
||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
||||
.area_size = CONFIG_FW_RO_GBB_SIZE,
|
||||
.area_name = "ROOT_KEY",
|
||||
.area_offset = CONFIG_VBOOT_ROOTKEY_OFF,
|
||||
.area_size = CONFIG_VBOOT_ROOTKEY_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||
},
|
||||
{
|
||||
.area_name = "GBB",
|
||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
||||
.area_size = 0,
|
||||
/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
|
||||
.area_name = "FMAP",
|
||||
.area_offset = (uint32_t)&ec_fmap,
|
||||
.area_size = sizeof(ec_fmap),
|
||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||
},
|
||||
{
|
||||
/* A dummy region to identify it as EC firmware */
|
||||
.area_name = "EC_IMAGE",
|
||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
||||
.area_offset = CONFIG_FW_RO_OFF,
|
||||
.area_size = 0, /* Always zero */
|
||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||
},
|
||||
|
@ -108,7 +107,7 @@ const struct _ec_fmap {
|
|||
{
|
||||
.area_name = "FW_MAIN_A",
|
||||
.area_offset = CONFIG_FW_A_OFF,
|
||||
.area_size = CONFIG_FW_IMAGE_SIZE,
|
||||
.area_size = CONFIG_FW_A_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
{
|
||||
|
@ -119,8 +118,8 @@ const struct _ec_fmap {
|
|||
},
|
||||
{
|
||||
.area_name = "VBLOCK_A",
|
||||
.area_offset = CONFIG_FW_A_OFF,
|
||||
.area_size = 0,
|
||||
.area_offset = CONFIG_VBLOCK_A_OFF,
|
||||
.area_size = CONFIG_VBLOCK_A_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
|
||||
|
@ -134,7 +133,7 @@ const struct _ec_fmap {
|
|||
{
|
||||
.area_name = "FW_MAIN_B",
|
||||
.area_offset = CONFIG_FW_B_OFF,
|
||||
.area_size = CONFIG_FW_IMAGE_SIZE,
|
||||
.area_size = CONFIG_FW_B_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
{
|
||||
|
@ -145,8 +144,8 @@ const struct _ec_fmap {
|
|||
},
|
||||
{
|
||||
.area_name = "VBLOCK_B",
|
||||
.area_offset = CONFIG_FW_A_OFF,
|
||||
.area_size = 0,
|
||||
.area_offset = CONFIG_VBLOCK_B_OFF,
|
||||
.area_size = CONFIG_VBLOCK_B_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,43 +17,46 @@
|
|||
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
||||
|
||||
|
||||
/* Jumps to one of the RW images if necessary. */
|
||||
static void jump_to_other_image(void)
|
||||
/* Might I want to jump to one of the RW images? */
|
||||
static int maybe_jump_to_other_image(void)
|
||||
{
|
||||
/* Only jump to another image if we're currently in RO */
|
||||
/* Not all boards even have RW EC firmware. I think it's just Link at
|
||||
* the moment. */
|
||||
#ifndef BOARD_link
|
||||
/* TODO: (crosbug.com/p/8561) once daisy can warm-boot to another
|
||||
* image, enable it here too. */
|
||||
CPUTS("[Vboot staying in RO because that's all there is]\n");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* We'll only jump to another image if we're currently in RO */
|
||||
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_TASK_KEYSCAN
|
||||
/* Don't jump if recovery requested */
|
||||
if (keyboard_scan_recovery_pressed()) {
|
||||
CPUTS("[Vboot staying in RO because key pressed]\n");
|
||||
return;
|
||||
CPUTS("[Vboot staying in RO because recovery key pressed]\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Don't jump if we're in RO becuase we jumped there (this keeps us
|
||||
* from jumping to RO only to jump right back). */
|
||||
if (system_jumped_to_this_image())
|
||||
return;
|
||||
return 0;
|
||||
|
||||
#if !defined(BOARD_daisy)
|
||||
/* TODO: (crosbug.com/p/8572) Daisy doesn't define a GPIO
|
||||
* for the recovery signal from servo, so can't check it. */
|
||||
if (gpio_get_level(GPIO_RECOVERYn) == 0) {
|
||||
CPUTS("[Vboot staying in RO due to recovery signal]\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOARD_link
|
||||
/* TODO: (crosbug.com/p/8561) once daisy can warm-boot to another
|
||||
* image, enable this there too. */
|
||||
/* TODO: real verified boot (including recovery reason); for now, just
|
||||
* jump to image A. */
|
||||
system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
|
||||
#endif
|
||||
/* Okay, we might want to jump to a RW image. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -68,9 +71,24 @@ int vboot_pre_init(void)
|
|||
|
||||
int vboot_init(void)
|
||||
{
|
||||
/* nothing to do, so do nothing */
|
||||
if (!maybe_jump_to_other_image())
|
||||
return EC_SUCCESS;
|
||||
|
||||
/* FIXME(wfrichar): placeholder for full verified boot implementation.
|
||||
* TBD exactly how, but we may want to continue in RO firmware, jump
|
||||
* directly to one of the RW firmwares, etc. */
|
||||
jump_to_other_image();
|
||||
CPRINTF("[ROOT_KEY is at 0x%x, size 0x%x]\n",
|
||||
CONFIG_VBOOT_ROOTKEY_OFF, CONFIG_VBOOT_ROOTKEY_SIZE);
|
||||
CPRINTF("[FW_MAIN_A is at 0x%x, size 0x%x]\n",
|
||||
CONFIG_FW_A_OFF, CONFIG_FW_A_SIZE);
|
||||
CPRINTF("[VBLOCK_A is at 0x%x, size 0x%x]\n",
|
||||
CONFIG_VBLOCK_A_OFF, CONFIG_VBLOCK_A_SIZE);
|
||||
CPRINTF("[FW_MAIN_B is at 0x%x, size 0x%x]\n",
|
||||
CONFIG_FW_B_OFF, CONFIG_FW_B_SIZE);
|
||||
CPRINTF("[VBLOCK_B is at 0x%x, size 0x%x]\n",
|
||||
CONFIG_VBLOCK_B_OFF, CONFIG_VBLOCK_B_SIZE);
|
||||
|
||||
system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ SECTIONS
|
|||
__data_end = .;
|
||||
} > IRAM
|
||||
#if defined(SECTION_IS_RO) && defined(CONFIG_VBOOT)
|
||||
.google CONFIG_FW_RO_GBB_OFF : AT(CONFIG_FW_RO_GBB_OFF) {
|
||||
.google CONFIG_FMAP_OFF : AT(CONFIG_FMAP_OFF) {
|
||||
*(.google)
|
||||
} > FLASH
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue