summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2012-05-04 14:00:55 -0700
committerBill Richardson <wfrichar@chromium.org>2012-05-04 14:42:58 -0700
commit3b361af2a76794b0d05be9a2cd6beaff4208cfd7 (patch)
treec7976e42e4df927338ca0ed869df5e97187eb548
parentd5deade06fc6e42bfdda14fd28dbc716922bf2da (diff)
downloadchrome-ec-3b361af2a76794b0d05be9a2cd6beaff4208cfd7.tar.gz
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>
-rw-r--r--README.fmap40
-rw-r--r--chip/lm4/config.h26
-rw-r--r--common/fmap.c29
-rw-r--r--common/vboot.c52
-rw-r--r--core/cortex-m/ec.lds.S2
5 files changed, 108 insertions, 41 deletions
diff --git a/README.fmap b/README.fmap
new file mode 100644
index 0000000000..416d27fe50
--- /dev/null
+++ b/README.fmap
@@ -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.
diff --git a/chip/lm4/config.h b/chip/lm4/config.h
index 88354a2ea2..d6c3f39639 100644
--- a/chip/lm4/config.h
+++ b/chip/lm4/config.h
@@ -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
diff --git a/common/fmap.c b/common/fmap.c
index 5316917b6a..438a45d1c1 100644
--- a/common/fmap.c
+++ b/common/fmap.c
@@ -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,
},
}
diff --git a/common/vboot.c b/common/vboot.c
index 0b0a9ef3dc..8f20054dcc 100644
--- a/common/vboot.c
+++ b/common/vboot.c
@@ -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;
}
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index eb72c4fc19..ba0b2733b5 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -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