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_A_OFF CONFIG_FW_IMAGE_SIZE
|
||||||
#define CONFIG_FW_B_OFF (2 * CONFIG_FW_IMAGE_SIZE)
|
#define CONFIG_FW_B_OFF (2 * CONFIG_FW_IMAGE_SIZE)
|
||||||
|
|
||||||
/* FIXME(wfrichar): Replace with real GBB size & location. */
|
/* We'll put the vboot stuff at the top of each image, since the vector table
|
||||||
#define CONFIG_FW_RO_GBB_SIZE CONFIG_FLASH_BANK_SIZE
|
* has to go at the start. 4K should be enough for what we need. 2K isn't. */
|
||||||
#define CONFIG_FW_RO_GBB_OFF (CONFIG_FW_RO_OFF + CONFIG_FW_IMAGE_SIZE - \
|
#define CONFIG_VBOOT_REGION_SIZE 0x1000
|
||||||
CONFIG_FW_RO_GBB_SIZE)
|
#define CONFIG_VBOOT_ROOTKEY_SIZE 0x800
|
||||||
#define CONFIG_FW_RO_SIZE (CONFIG_FW_IMAGE_SIZE - CONFIG_FW_RO_GBB_SIZE)
|
#define CONFIG_VBOOT_REGION_OFF (CONFIG_FW_IMAGE_SIZE \
|
||||||
#define CONFIG_FW_A_SIZE CONFIG_FW_IMAGE_SIZE
|
- CONFIG_VBOOT_REGION_SIZE)
|
||||||
#define CONFIG_FW_B_SIZE CONFIG_FW_IMAGE_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 */
|
/* Number of IRQ vectors on the NVIC */
|
||||||
#define CONFIG_IRQ_COUNT 132
|
#define CONFIG_IRQ_COUNT 132
|
||||||
|
|
|
@ -38,7 +38,6 @@ typedef struct _FmapAreaHeader {
|
||||||
|
|
||||||
|
|
||||||
#define NUM_EC_FMAP_AREAS 14
|
#define NUM_EC_FMAP_AREAS 14
|
||||||
|
|
||||||
const struct _ec_fmap {
|
const struct _ec_fmap {
|
||||||
FmapHeader header;
|
FmapHeader header;
|
||||||
FmapAreaHeader area[NUM_EC_FMAP_AREAS];
|
FmapAreaHeader area[NUM_EC_FMAP_AREAS];
|
||||||
|
@ -78,22 +77,22 @@ const struct _ec_fmap {
|
||||||
|
|
||||||
/* Other RO stuff: FMAP, GBB, etc. */
|
/* Other RO stuff: FMAP, GBB, etc. */
|
||||||
{
|
{
|
||||||
/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
|
.area_name = "ROOT_KEY",
|
||||||
.area_name = "FMAP",
|
.area_offset = CONFIG_VBOOT_ROOTKEY_OFF,
|
||||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
.area_size = CONFIG_VBOOT_ROOTKEY_SIZE,
|
||||||
.area_size = CONFIG_FW_RO_GBB_SIZE,
|
|
||||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.area_name = "GBB",
|
/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
|
||||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
.area_name = "FMAP",
|
||||||
.area_size = 0,
|
.area_offset = (uint32_t)&ec_fmap,
|
||||||
|
.area_size = sizeof(ec_fmap),
|
||||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* A dummy region to identify it as EC firmware */
|
/* A dummy region to identify it as EC firmware */
|
||||||
.area_name = "EC_IMAGE",
|
.area_name = "EC_IMAGE",
|
||||||
.area_offset = CONFIG_FW_RO_GBB_OFF,
|
.area_offset = CONFIG_FW_RO_OFF,
|
||||||
.area_size = 0, /* Always zero */
|
.area_size = 0, /* Always zero */
|
||||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||||
},
|
},
|
||||||
|
@ -108,7 +107,7 @@ const struct _ec_fmap {
|
||||||
{
|
{
|
||||||
.area_name = "FW_MAIN_A",
|
.area_name = "FW_MAIN_A",
|
||||||
.area_offset = CONFIG_FW_A_OFF,
|
.area_offset = CONFIG_FW_A_OFF,
|
||||||
.area_size = CONFIG_FW_IMAGE_SIZE,
|
.area_size = CONFIG_FW_A_SIZE,
|
||||||
.area_flags = FMAP_AREA_STATIC,
|
.area_flags = FMAP_AREA_STATIC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -119,8 +118,8 @@ const struct _ec_fmap {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.area_name = "VBLOCK_A",
|
.area_name = "VBLOCK_A",
|
||||||
.area_offset = CONFIG_FW_A_OFF,
|
.area_offset = CONFIG_VBLOCK_A_OFF,
|
||||||
.area_size = 0,
|
.area_size = CONFIG_VBLOCK_A_SIZE,
|
||||||
.area_flags = FMAP_AREA_STATIC,
|
.area_flags = FMAP_AREA_STATIC,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ const struct _ec_fmap {
|
||||||
{
|
{
|
||||||
.area_name = "FW_MAIN_B",
|
.area_name = "FW_MAIN_B",
|
||||||
.area_offset = CONFIG_FW_B_OFF,
|
.area_offset = CONFIG_FW_B_OFF,
|
||||||
.area_size = CONFIG_FW_IMAGE_SIZE,
|
.area_size = CONFIG_FW_B_SIZE,
|
||||||
.area_flags = FMAP_AREA_STATIC,
|
.area_flags = FMAP_AREA_STATIC,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -145,8 +144,8 @@ const struct _ec_fmap {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.area_name = "VBLOCK_B",
|
.area_name = "VBLOCK_B",
|
||||||
.area_offset = CONFIG_FW_A_OFF,
|
.area_offset = CONFIG_VBLOCK_B_OFF,
|
||||||
.area_size = 0,
|
.area_size = CONFIG_VBLOCK_B_SIZE,
|
||||||
.area_flags = FMAP_AREA_STATIC,
|
.area_flags = FMAP_AREA_STATIC,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,43 +17,46 @@
|
||||||
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
||||||
|
|
||||||
|
|
||||||
/* Jumps to one of the RW images if necessary. */
|
/* Might I want to jump to one of the RW images? */
|
||||||
static void jump_to_other_image(void)
|
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)
|
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_TASK_KEYSCAN
|
#ifdef CONFIG_TASK_KEYSCAN
|
||||||
/* Don't jump if recovery requested */
|
/* Don't jump if recovery requested */
|
||||||
if (keyboard_scan_recovery_pressed()) {
|
if (keyboard_scan_recovery_pressed()) {
|
||||||
CPUTS("[Vboot staying in RO because key pressed]\n");
|
CPUTS("[Vboot staying in RO because recovery key pressed]\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Don't jump if we're in RO becuase we jumped there (this keeps us
|
/* Don't jump if we're in RO becuase we jumped there (this keeps us
|
||||||
* from jumping to RO only to jump right back). */
|
* from jumping to RO only to jump right back). */
|
||||||
if (system_jumped_to_this_image())
|
if (system_jumped_to_this_image())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
#if !defined(BOARD_daisy)
|
#if !defined(BOARD_daisy)
|
||||||
/* TODO: (crosbug.com/p/8572) Daisy doesn't define a GPIO
|
/* TODO: (crosbug.com/p/8572) Daisy doesn't define a GPIO
|
||||||
* for the recovery signal from servo, so can't check it. */
|
* for the recovery signal from servo, so can't check it. */
|
||||||
if (gpio_get_level(GPIO_RECOVERYn) == 0) {
|
if (gpio_get_level(GPIO_RECOVERYn) == 0) {
|
||||||
CPUTS("[Vboot staying in RO due to recovery signal]\n");
|
CPUTS("[Vboot staying in RO due to recovery signal]\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Okay, we might want to jump to a RW image. */
|
||||||
#ifdef BOARD_link
|
return 1;
|
||||||
/* 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -68,9 +71,24 @@ int vboot_pre_init(void)
|
||||||
|
|
||||||
int vboot_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.
|
/* FIXME(wfrichar): placeholder for full verified boot implementation.
|
||||||
* TBD exactly how, but we may want to continue in RO firmware, jump
|
* TBD exactly how, but we may want to continue in RO firmware, jump
|
||||||
* directly to one of the RW firmwares, etc. */
|
* 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;
|
return EC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ SECTIONS
|
||||||
__data_end = .;
|
__data_end = .;
|
||||||
} > IRAM
|
} > IRAM
|
||||||
#if defined(SECTION_IS_RO) && defined(CONFIG_VBOOT)
|
#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)
|
*(.google)
|
||||||
} > FLASH
|
} > FLASH
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue