Browse Source

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>
tags/v1.0.0
Bill Richardson 7 years ago
parent
commit
3b361af2a7
5 changed files with 108 additions and 41 deletions
  1. 40
    0
      README.fmap
  2. 18
    8
      chip/lm4/config.h
  3. 14
    15
      common/fmap.c
  4. 35
    17
      common/vboot.c
  5. 1
    1
      core/cortex-m/ec.lds.S

+ 40
- 0
README.fmap View File

@@ -0,0 +1,40 @@
1
+In the most general case, the flash layout looks something like this:
2
+
3
+  +---------------------+
4
+  | Reserved for EC use |
5
+  +---------------------+
6
+
7
+  +---------------------+
8
+  |     Vblock B        |
9
+  +---------------------+
10
+  |  RW firmware B      |
11
+  +---------------------+
12
+
13
+  +---------------------+
14
+  |     Vblock A        |
15
+  +---------------------+
16
+  |  RW firmware A      |
17
+  +---------------------+
18
+
19
+  +---------------------+
20
+  |       FMAP          |
21
+  +---------------------+
22
+  |   Public root key   |
23
+  +---------------------+
24
+  |  Read-only firmware |
25
+  +---------------------+
26
+
27
+
28
+BIOS firmware (and kernel) put the vblock info at the start of each image
29
+where it's easy to find. The Blizzard EC expects the firmware vector table
30
+to come first, so we have to put the vblock at the end. This means we have
31
+to know where to look for it, but that's built into the FMAP and the RO
32
+firmware anyway, so that's not an issue.
33
+
34
+The RO firmware doesn't need a vblock of course, but it does need some
35
+reserved space for vboot-related things.
36
+
37
+Using SHA256/RSA4096, the vblock is 2468 bytes (0x9a4), while the public
38
+root key is 1064 bytes (0x428) and the current FMAP is 644 bytes (0x284). If
39
+we reserve 4K at the top of each FW image, that should give us plenty of
40
+room for vboot-related stuff.

+ 18
- 8
chip/lm4/config.h View File

@@ -22,14 +22,24 @@
22 22
 #define CONFIG_FW_A_OFF         CONFIG_FW_IMAGE_SIZE
23 23
 #define CONFIG_FW_B_OFF         (2 * CONFIG_FW_IMAGE_SIZE)
24 24
 
25
-/* FIXME(wfrichar): Replace with real GBB size & location. */
26
-#define CONFIG_FW_RO_GBB_SIZE   CONFIG_FLASH_BANK_SIZE
27
-#define CONFIG_FW_RO_GBB_OFF    (CONFIG_FW_RO_OFF + CONFIG_FW_IMAGE_SIZE - \
28
-				 CONFIG_FW_RO_GBB_SIZE)
29
-#define CONFIG_FW_RO_SIZE (CONFIG_FW_IMAGE_SIZE - CONFIG_FW_RO_GBB_SIZE)
30
-#define CONFIG_FW_A_SIZE CONFIG_FW_IMAGE_SIZE
31
-#define CONFIG_FW_B_SIZE CONFIG_FW_IMAGE_SIZE
32
-
25
+/* We'll put the vboot stuff at the top of each image, since the vector table
26
+ * has to go at the start. 4K should be enough for what we need. 2K isn't. */
27
+#define CONFIG_VBOOT_REGION_SIZE     0x1000
28
+#define CONFIG_VBOOT_ROOTKEY_SIZE    0x800
29
+#define CONFIG_VBOOT_REGION_OFF      (CONFIG_FW_IMAGE_SIZE \
30
+					- CONFIG_VBOOT_REGION_SIZE)
31
+/* Specifics for each image */
32
+#define CONFIG_FW_RO_SIZE            CONFIG_VBOOT_REGION_OFF
33
+#define CONFIG_FW_A_SIZE             CONFIG_VBOOT_REGION_OFF
34
+#define CONFIG_FW_B_SIZE             CONFIG_VBOOT_REGION_OFF
35
+#define CONFIG_VBOOT_ROOTKEY_OFF     (CONFIG_FW_RO_OFF \
36
+					+ CONFIG_VBOOT_REGION_OFF)
37
+#define CONFIG_FMAP_OFF              (CONFIG_VBOOT_ROOTKEY_OFF \
38
+					+ CONFIG_VBOOT_ROOTKEY_SIZE)
39
+#define CONFIG_VBLOCK_A_OFF          (CONFIG_FW_A_OFF + CONFIG_FW_A_SIZE)
40
+#define CONFIG_VBLOCK_B_OFF          (CONFIG_FW_B_OFF + CONFIG_FW_B_SIZE)
41
+#define CONFIG_VBLOCK_A_SIZE         CONFIG_VBOOT_REGION_SIZE
42
+#define CONFIG_VBLOCK_B_SIZE         CONFIG_VBOOT_REGION_SIZE
33 43
 
34 44
 /* Number of IRQ vectors on the NVIC */
35 45
 #define CONFIG_IRQ_COUNT 132

+ 14
- 15
common/fmap.c View File

@@ -38,7 +38,6 @@ typedef struct _FmapAreaHeader {
38 38
 
39 39
 
40 40
 #define NUM_EC_FMAP_AREAS 14
41
-
42 41
 const struct _ec_fmap {
43 42
 	FmapHeader header;
44 43
 	FmapAreaHeader area[NUM_EC_FMAP_AREAS];
@@ -78,22 +77,22 @@ const struct _ec_fmap {
78 77
 
79 78
 		/* Other RO stuff: FMAP, GBB, etc. */
80 79
 		{
81
-			/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
82
-			.area_name = "FMAP",
83
-			.area_offset = CONFIG_FW_RO_GBB_OFF,
84
-			.area_size = CONFIG_FW_RO_GBB_SIZE,
80
+			.area_name = "ROOT_KEY",
81
+			.area_offset = CONFIG_VBOOT_ROOTKEY_OFF,
82
+			.area_size = CONFIG_VBOOT_ROOTKEY_SIZE,
85 83
 			.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
86 84
 		},
87 85
 		{
88
-			.area_name = "GBB",
89
-			.area_offset = CONFIG_FW_RO_GBB_OFF,
90
-			.area_size = 0,
86
+			/* FIXME(wfrichar): GBB != FMAP. Use the right terms */
87
+			.area_name = "FMAP",
88
+			.area_offset = (uint32_t)&ec_fmap,
89
+			.area_size = sizeof(ec_fmap),
91 90
 			.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
92 91
 		},
93 92
 		{
94 93
 			/* A dummy region to identify it as EC firmware */
95 94
 			.area_name = "EC_IMAGE",
96
-			.area_offset = CONFIG_FW_RO_GBB_OFF,
95
+			.area_offset = CONFIG_FW_RO_OFF,
97 96
 			.area_size = 0, /* Always zero */
98 97
 			.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
99 98
 		},
@@ -108,7 +107,7 @@ const struct _ec_fmap {
108 107
 		{
109 108
 			.area_name = "FW_MAIN_A",
110 109
 			.area_offset = CONFIG_FW_A_OFF,
111
-			.area_size = CONFIG_FW_IMAGE_SIZE,
110
+			.area_size = CONFIG_FW_A_SIZE,
112 111
 			.area_flags = FMAP_AREA_STATIC,
113 112
 		},
114 113
 		{
@@ -119,8 +118,8 @@ const struct _ec_fmap {
119 118
 		},
120 119
 		{
121 120
 			.area_name = "VBLOCK_A",
122
-			.area_offset = CONFIG_FW_A_OFF,
123
-			.area_size = 0,
121
+			.area_offset = CONFIG_VBLOCK_A_OFF,
122
+			.area_size = CONFIG_VBLOCK_A_SIZE,
124 123
 			.area_flags = FMAP_AREA_STATIC,
125 124
 		},
126 125
 
@@ -134,7 +133,7 @@ const struct _ec_fmap {
134 133
 		{
135 134
 			.area_name = "FW_MAIN_B",
136 135
 			.area_offset = CONFIG_FW_B_OFF,
137
-			.area_size = CONFIG_FW_IMAGE_SIZE,
136
+			.area_size = CONFIG_FW_B_SIZE,
138 137
 			.area_flags = FMAP_AREA_STATIC,
139 138
 		},
140 139
 		{
@@ -145,8 +144,8 @@ const struct _ec_fmap {
145 144
 		},
146 145
 		{
147 146
 			.area_name = "VBLOCK_B",
148
-			.area_offset = CONFIG_FW_A_OFF,
149
-			.area_size = 0,
147
+			.area_offset = CONFIG_VBLOCK_B_OFF,
148
+			.area_size = CONFIG_VBLOCK_B_SIZE,
150 149
 			.area_flags = FMAP_AREA_STATIC,
151 150
 		},
152 151
 	}

+ 35
- 17
common/vboot.c View File

@@ -17,43 +17,46 @@
17 17
 #define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
18 18
 
19 19
 
20
-/* Jumps to one of the RW images if necessary. */
21
-static void jump_to_other_image(void)
20
+/* Might I want to jump to one of the RW images? */
21
+static int maybe_jump_to_other_image(void)
22 22
 {
23
-	/* Only jump to another image if we're currently in RO */
23
+	/* Not all boards even have RW EC firmware. I think it's just Link at
24
+	 * the moment. */
25
+#ifndef BOARD_link
26
+	/* TODO: (crosbug.com/p/8561) once daisy can warm-boot to another
27
+	 * image, enable it here too. */
28
+	CPUTS("[Vboot staying in RO because that's all there is]\n");
29
+	return 0;
30
+#endif
31
+
32
+	/* We'll only jump to another image if we're currently in RO */
24 33
 	if (system_get_image_copy() != SYSTEM_IMAGE_RO)
25
-		return;
34
+		return 0;
26 35
 
27 36
 #ifdef CONFIG_TASK_KEYSCAN
28 37
 	/* Don't jump if recovery requested */
29 38
 	if (keyboard_scan_recovery_pressed()) {
30
-		CPUTS("[Vboot staying in RO because key pressed]\n");
31
-		return;
39
+		CPUTS("[Vboot staying in RO because recovery key pressed]\n");
40
+		return 0;
32 41
 	}
33 42
 #endif
34 43
 
35 44
 	/* Don't jump if we're in RO becuase we jumped there (this keeps us
36 45
 	 * from jumping to RO only to jump right back). */
37 46
 	if (system_jumped_to_this_image())
38
-		return;
47
+		return 0;
39 48
 
40 49
 #if !defined(BOARD_daisy)
41 50
 	/* TODO: (crosbug.com/p/8572) Daisy doesn't define a GPIO
42 51
 	 * for the recovery signal from servo, so can't check it. */
43 52
 	if (gpio_get_level(GPIO_RECOVERYn) == 0) {
44 53
 		CPUTS("[Vboot staying in RO due to recovery signal]\n");
45
-		return;
54
+		return 0;
46 55
 	}
47 56
 #endif
48 57
 
49
-
50
-#ifdef BOARD_link
51
-	/* TODO: (crosbug.com/p/8561) once daisy can warm-boot to another
52
-	 * image, enable this there too. */
53
-	/* TODO: real verified boot (including recovery reason); for now, just
54
-	 * jump to image A. */
55
-	system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
56
-#endif
58
+	/* Okay, we might want to jump to a RW image. */
59
+	return 1;
57 60
 }
58 61
 
59 62
 /*****************************************************************************/
@@ -68,9 +71,24 @@ int vboot_pre_init(void)
68 71
 
69 72
 int vboot_init(void)
70 73
 {
74
+	/* nothing to do, so do nothing */
75
+	if (!maybe_jump_to_other_image())
76
+		return EC_SUCCESS;
77
+
71 78
 	/* FIXME(wfrichar): placeholder for full verified boot implementation.
72 79
 	 * TBD exactly how, but we may want to continue in RO firmware, jump
73 80
 	 * directly to one of the RW firmwares, etc. */
74
-	jump_to_other_image();
81
+	CPRINTF("[ROOT_KEY is at 0x%x, size 0x%x]\n",
82
+		CONFIG_VBOOT_ROOTKEY_OFF, CONFIG_VBOOT_ROOTKEY_SIZE);
83
+	CPRINTF("[FW_MAIN_A is at 0x%x, size 0x%x]\n",
84
+		CONFIG_FW_A_OFF, CONFIG_FW_A_SIZE);
85
+	CPRINTF("[VBLOCK_A is at 0x%x, size 0x%x]\n",
86
+		CONFIG_VBLOCK_A_OFF, CONFIG_VBLOCK_A_SIZE);
87
+	CPRINTF("[FW_MAIN_B is at 0x%x, size 0x%x]\n",
88
+		CONFIG_FW_B_OFF, CONFIG_FW_B_SIZE);
89
+	CPRINTF("[VBLOCK_B is at 0x%x, size 0x%x]\n",
90
+		CONFIG_VBLOCK_B_OFF, CONFIG_VBLOCK_B_SIZE);
91
+
92
+	system_run_image_copy(SYSTEM_IMAGE_RW_A, 0);
75 93
 	return EC_SUCCESS;
76 94
 }

+ 1
- 1
core/cortex-m/ec.lds.S View File

@@ -79,7 +79,7 @@ SECTIONS
79 79
         __data_end = .;
80 80
     } > IRAM
81 81
 #if defined(SECTION_IS_RO) && defined(CONFIG_VBOOT)
82
-    .google CONFIG_FW_RO_GBB_OFF : AT(CONFIG_FW_RO_GBB_OFF) {
82
+    .google CONFIG_FMAP_OFF : AT(CONFIG_FMAP_OFF) {
83 83
         *(.google)
84 84
     } > FLASH
85 85
 #else

Loading…
Cancel
Save