Add CTRL-L in dev screen to support a "legacy boot option"
This option is disabled per default and can be enabled with
crossystem dev_boot_legacy=1
or by setting the GBB flag
GBB_FLAG_FORCE_DEV_BOOT_LEGACY 0x00000080
BUG=chrome-os-partner:6108
TEST=crossystem dev_boot_legacy=1
boot to dev mode screen, press CTRL-L, see SeaBIOS start
(other CLs needed)
BRANCH=link
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
Change-Id: I593d2be7cff5ca07b8d08012c4514a172bd75a38
Reviewed-on: https://gerrit.chromium.org/gerrit/31265
Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Tested-by: Stefan Reinauer <reinauer@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Ready: Stefan Reinauer <reinauer@chromium.org>
diff --git a/firmware/include/gbb_header.h b/firmware/include/gbb_header.h
index 57fb701..5031eeb 100644
--- a/firmware/include/gbb_header.h
+++ b/firmware/include/gbb_header.h
@@ -51,6 +51,8 @@
#define GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK 0x00000020
/* Allow Enter key to trigger dev->tonorm screen transition */
#define GBB_FLAG_ENTER_TRIGGERS_TONORM 0x00000040
+/* Allow booting Legacy OSes in dev mode even if dev_boot_legacy=0. */
+#define GBB_FLAG_FORCE_DEV_BOOT_LEGACY 0x00000080
#ifdef __cplusplus
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index 12da955..5b55bf5 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -688,4 +688,7 @@
void *outbuf, uint32_t *out_size);
+/* Execute legacy boot option */
+int VbExLegacy(void);
+
#endif /* VBOOT_REFERENCE_VBOOT_API_H_ */
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h
index 8748a5c..e350459 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -49,6 +49,8 @@
VBNV_KERNEL_FIELD,
/* Allow booting from USB in developer mode. 0=no, 1=yes. */
VBNV_DEV_BOOT_USB,
+ /* Allow booting of legacy OSes in developer mode. 0=no, 1=yes. */
+ VBNV_DEV_BOOT_LEGACY,
/* Only boot Google-signed images in developer mode. 0=no, 1=yes. */
VBNV_DEV_BOOT_SIGNED_ONLY,
/* Set by userspace to request that RO firmware disable dev-mode on the next
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index 0a1ee43..9c6d80e 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -235,6 +235,7 @@
* initially disabled if the user later transitions back into developer
* mode. */
VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 0);
+ VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0);
VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0);
/* If we don't need the VGA option ROM but got it anyway, stop asking for
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 3ce5983..750edb2 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -156,16 +156,19 @@
VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) {
GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
- uint32_t allow_usb = 0;
+ uint32_t allow_usb = 0, allow_legacy = 0;
VbAudioContext* audio = 0;
VBDEBUG(("Entering %s()\n", __func__));
/* Check if USB booting is allowed */
VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
+ VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &allow_legacy);
/* Handle GBB flag override */
if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
allow_usb = 1;
+ if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_LEGACY)
+ allow_legacy = 1;
/* Show the dev mode warning screen */
VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);
@@ -227,6 +230,20 @@
VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+D; skip delay\n"));
goto fallout;
break;
+ case 0x0c:
+ VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+L; Try legacy boot\n"));
+ /* If VbExLegacy() succeeds, it will never return.
+ * If it returns, beep.
+ */
+ if (allow_legacy)
+ VbExLegacy();
+ else
+ VBDEBUG(("VbBootDeveloper() - Legacy boot is disabled\n"));
+
+ VbExBeep(120, 400);
+ VbExSleepMs(120);
+ VbExBeep(120, 400);
+ break;
/* The Ctrl-Enter is special for Lumpy test purpose. */
case VB_KEY_CTRL_ENTER:
case 0x15:
diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c
index ca3360b..065eee5 100644
--- a/firmware/lib/vboot_display.c
+++ b/firmware/lib/vboot_display.c
@@ -553,6 +553,11 @@
used += Strncat(buf + used, "\ndev_boot_usb: ", DEBUG_INFO_SIZE - used);
used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
+ /* Add dev_boot_legacy flag */
+ VbNvGet(vncptr, VBNV_DEV_BOOT_LEGACY, &i);
+ used += Strncat(buf + used, "\ndev_boot_legacy: ", DEBUG_INFO_SIZE - used);
+ used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
+
/* Add dev_boot_signed_only flag */
VbNvGet(vncptr, VBNV_DEV_BOOT_SIGNED_ONLY, &i);
used += Strncat(buf + used, "\ndev_boot_signed_only: ",
diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index 0f4633b..618ff52 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -32,6 +32,7 @@
#define DEV_FLAGS_OFFSET 4
#define DEV_BOOT_USB_MASK 0x01
#define DEV_BOOT_SIGNED_ONLY_MASK 0x02
+#define DEV_BOOT_LEGACY_MASK 0x04
#define TPM_FLAGS_OFFSET 5
#define TPM_CLEAR_OWNER_REQUEST 0x01
@@ -116,6 +117,10 @@
*dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_USB_MASK ? 1 : 0);
return 0;
+ case VBNV_DEV_BOOT_LEGACY:
+ *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_LEGACY_MASK ? 1 : 0);
+ return 0;
+
case VBNV_DEV_BOOT_SIGNED_ONLY:
*dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_SIGNED_ONLY_MASK ? 1 : 0);
return 0;
@@ -210,6 +215,13 @@
raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_USB_MASK;
break;
+ case VBNV_DEV_BOOT_LEGACY:
+ if (value)
+ raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_LEGACY_MASK;
+ else
+ raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_LEGACY_MASK;
+ break;
+
case VBNV_DEV_BOOT_SIGNED_ONLY:
if (value)
raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_SIGNED_ONLY_MASK;
diff --git a/firmware/stub/vboot_api_stub.c b/firmware/stub/vboot_api_stub.c
index 53a49d2..8521db0 100644
--- a/firmware/stub/vboot_api_stub.c
+++ b/firmware/stub/vboot_api_stub.c
@@ -188,3 +188,8 @@
VbError_t VbExEcProtectRW(void) {
return VBERROR_SUCCESS;
}
+
+int VbExLegacy(void)
+{
+ return 1;
+}
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index a19384d..e1ee4fc 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -421,6 +421,8 @@
value = VbGetNvStorage(VBNV_LOCALIZATION_INDEX);
} else if (!strcasecmp(name,"dev_boot_usb")) {
value = VbGetNvStorage(VBNV_DEV_BOOT_USB);
+ } else if (!strcasecmp(name,"dev_boot_legacy")) {
+ value = VbGetNvStorage(VBNV_DEV_BOOT_LEGACY);
} else if (!strcasecmp(name,"dev_boot_signed_only")) {
value = VbGetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY);
} else if (!strcasecmp(name,"oprom_needed")) {
@@ -521,6 +523,8 @@
return VbSetNvStorage(VBNV_LOCALIZATION_INDEX, value);
} else if (!strcasecmp(name,"dev_boot_usb")) {
return VbSetNvStorage(VBNV_DEV_BOOT_USB, value);
+ } else if (!strcasecmp(name,"dev_boot_legacy")) {
+ return VbSetNvStorage(VBNV_DEV_BOOT_LEGACY, value);
} else if (!strcasecmp(name,"dev_boot_signed_only")) {
return VbSetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY, value);
} else if (!strcasecmp(name,"oprom_needed")) {
diff --git a/scripts/image_signing/set_gbb_flags.sh b/scripts/image_signing/set_gbb_flags.sh
index 47f3691..de17c83 100755
--- a/scripts/image_signing/set_gbb_flags.sh
+++ b/scripts/image_signing/set_gbb_flags.sh
@@ -29,6 +29,7 @@
GBB_FLAG_FORCE_DEV_BOOT_USB 0x00000010
GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK 0x00000020
GBB_FLAG_ENTER_TRIGGERS_TONORM 0x00000040
+ GBB_FLAG_FORCE_DEV_BOOT_LEGACY 0x00000080
To get a developer-friendly device, try 0x11 (short_delay + boot_usb).
For factory-related tests (always DEV), try 0x39.
diff --git a/tests/vboot_nvstorage_test.c b/tests/vboot_nvstorage_test.c
index a555ac7..19937d6 100644
--- a/tests/vboot_nvstorage_test.c
+++ b/tests/vboot_nvstorage_test.c
@@ -30,6 +30,7 @@
{VBNV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"},
{VBNV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"},
{VBNV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"},
+ {VBNV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
{VBNV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
{VBNV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
{VBNV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c
index 7528f01..d819107 100644
--- a/utility/crossystem_main.c
+++ b/utility/crossystem_main.c
@@ -43,6 +43,8 @@
{"disable_dev_request", CAN_WRITE, "Disable virtual dev-mode on next boot"},
{"dev_boot_usb", CAN_WRITE,
"Enable developer mode boot from USB/SD (writable)"},
+ {"dev_boot_legacy", CAN_WRITE,
+ "Enable developer mode boot Legacy OSes (writable)"},
{"dev_boot_signed_only", CAN_WRITE,
"Enable developer mode boot only from official kernels (writable)"},
{"devsw_boot", 0, "Developer switch position at boot"},