Add NV flag to default boot legacy OS
In developer mode, this option will make the system try to boot into
a legacy OS first after the 30 second timeout. This removes the need to
press a key during boot to try legacy mode and the need to remove the
write protect screw to boot legacy as default.
BUG=chromium:310697
BRANCH=none
TEST=make runtests
Change-Id: I9a9f64c14ad015e21d08eec36e8fc187189cd2f2
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/304077
Reviewed-by: Randall Spangler <rspangler@chromium.org>
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 4b30a5c..a856775 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -276,6 +276,7 @@
vb2_nv_set(ctx, VB2_NV_DEV_BOOT_LEGACY, 0);
vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 0);
vb2_nv_set(ctx, VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP, 0);
+ vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT, 0);
vb2_nv_set(ctx, VB2_NV_FASTBOOT_UNLOCK_IN_FW, 0);
}
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c
index 55f1d0d..851c387 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -139,6 +139,10 @@
return GETBIT(VB2_NV_OFFS_DEV,
VB2_NV_DEV_FLAG_FASTBOOT_FULL_CAP);
+ case VB2_NV_DEV_DEFAULT_BOOT:
+ return (p[VB2_NV_OFFS_DEV] & VB2_NV_DEV_FLAG_DEFAULT_BOOT)
+ >> VB2_NV_DEV_DEFAULT_BOOT_SHIFT;
+
case VB2_NV_DISABLE_DEV_REQUEST:
return GETBIT(VB2_NV_OFFS_BOOT, VB2_NV_BOOT_DISABLE_DEV);
@@ -292,6 +296,17 @@
SETBIT(VB2_NV_OFFS_DEV, VB2_NV_DEV_FLAG_FASTBOOT_FULL_CAP);
break;
+ case VB2_NV_DEV_DEFAULT_BOOT:
+ /* Map out of range values to disk */
+ if (value > (VB2_NV_DEV_FLAG_DEFAULT_BOOT >>
+ VB2_NV_DEV_DEFAULT_BOOT_SHIFT))
+ value = VB2_DEV_DEFAULT_BOOT_DISK;
+
+ p[VB2_NV_OFFS_DEV] &= ~VB2_NV_DEV_FLAG_DEFAULT_BOOT;
+ p[VB2_NV_OFFS_DEV] |=
+ (uint8_t)(value << VB2_NV_DEV_DEFAULT_BOOT_SHIFT);
+ break;
+
case VB2_NV_DISABLE_DEV_REQUEST:
SETBIT(VB2_NV_OFFS_BOOT, VB2_NV_BOOT_DISABLE_DEV);
break;
diff --git a/firmware/2lib/include/2nvstorage.h b/firmware/2lib/include/2nvstorage.h
index bfe9a3a..31dfc8d 100644
--- a/firmware/2lib/include/2nvstorage.h
+++ b/firmware/2lib/include/2nvstorage.h
@@ -55,6 +55,8 @@
* 0=no, 1=yes.
*/
VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP,
+ /* Set default boot mode (see vb2_dev_default_boot) */
+ VB2_NV_DEV_DEFAULT_BOOT,
/*
* Set by userspace to request that RO firmware disable dev-mode on the
* next boot. This is likely only possible if the dev-switch is
@@ -94,6 +96,19 @@
VB2_NV_BOOT_ON_AC_DETECT,
};
+/* Set default boot in developer mode */
+enum vb2_dev_default_boot {
+ /* Default to boot from disk*/
+ VB2_DEV_DEFAULT_BOOT_DISK = 0,
+
+ /* Default to boot from USB */
+ VB2_DEV_DEFAULT_BOOT_USB= 1,
+
+ /* Default to boot legacy OS */
+ VB2_DEV_DEFAULT_BOOT_LEGACY = 2,
+
+};
+
/* Firmware result codes for VB2_NV_FW_RESULT and VB2_NV_FW_PREV_RESULT */
enum vb2_fw_result {
/* Unknown */
diff --git a/firmware/2lib/include/2nvstorage_fields.h b/firmware/2lib/include/2nvstorage_fields.h
index 8ae21f8..fd625d0 100644
--- a/firmware/2lib/include/2nvstorage_fields.h
+++ b/firmware/2lib/include/2nvstorage_fields.h
@@ -57,11 +57,13 @@
#define VB2_NV_BOOT2_PREV_RESULT_SHIFT 4 /* Number of bits to shift result */
#define VB2_NV_BOOT2_PREV_TRIED 0x40
-/* Fields in VB2_NV_OFFS_DEV (unused = 0xf0) */
+/* Fields in VB2_NV_OFFS_DEV (unused = 0xc0) */
#define VB2_NV_DEV_FLAG_USB 0x01
#define VB2_NV_DEV_FLAG_SIGNED_ONLY 0x02
#define VB2_NV_DEV_FLAG_LEGACY 0x04
#define VB2_NV_DEV_FLAG_FASTBOOT_FULL_CAP 0x08
+#define VB2_NV_DEV_FLAG_DEFAULT_BOOT 0x30
+#define VB2_NV_DEV_DEFAULT_BOOT_SHIFT 4 /* Number of bits to shift */
/* Fields in VB2_NV_OFFS_TPM (unused = 0xf8) */
#define VB2_NV_TPM_CLEAR_OWNER_REQUEST 0x01
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h
index 5a44ae1..dc4ab50 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -76,6 +76,8 @@
* 0=no, 1=yes.
*/
VBNV_DEV_BOOT_FASTBOOT_FULL_CAP,
+ /* Set default boot mode (see VbDevDefaultBoot) */
+ VBNV_DEV_DEFAULT_BOOT,
/*
* Set by userspace to request that RO firmware disable dev-mode on the
* next boot. This is likely only possible if the dev-switch is
@@ -119,6 +121,19 @@
} VbNvParam;
+/* Set default boot in developer mode */
+typedef enum VbDevDefaultBoot {
+ /* Default to boot from disk*/
+ VBNV_DEV_DEFAULT_BOOT_DISK = 0,
+
+ /* Default to boot from USB */
+ VBNV_DEV_DEFAULT_BOOT_USB = 1,
+
+ /* Default to boot legacy OS */
+ VBNV_DEV_DEFAULT_BOOT_LEGACY = 2,
+
+} VbDevDefaultBoot;
+
/* Result of trying the firmware in VBNV_FW_TRIED */
typedef enum VbFwResult {
/* Unknown */
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index 419175c..2657fb5 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -323,6 +323,7 @@
VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0);
VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0);
VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 0);
+ VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 0);
VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 0);
/*
* Back up any changes now, so these values can't be forgotten
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 0456123..7b47dc6 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -170,6 +170,27 @@
return retval;
}
+uint32_t VbTryUsb(VbCommonParams *cparams, LoadKernelParams *p)
+{
+ uint32_t retval = VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE);
+ if (VBERROR_SUCCESS == retval) {
+ VBDEBUG(("VbBootDeveloper() - booting USB\n"));
+ } else {
+ VBDEBUG(("VbBootDeveloper() - no kernel found on USB\n"));
+ VbExBeep(250, 200);
+ VbExSleepMs(120);
+ /*
+ * Clear recovery requests from failed
+ * kernel loading, so that powering off
+ * at this point doesn't put us into
+ * recovery mode.
+ */
+ VbSetRecoveryRequest(
+ VBNV_RECOVERY_NOT_REQUESTED);
+ }
+ return retval;
+}
+
#define CONFIRM_KEY_DELAY 20 /* Check confirm screen keys every 20ms */
int VbUserConfirms(VbCommonParams *cparams, uint32_t confirm_flags)
@@ -251,7 +272,14 @@
GoogleBinaryBlockHeader *gbb = cparams->gbb;
VbSharedDataHeader *shared =
(VbSharedDataHeader *)cparams->shared_data_blob;
- uint32_t allow_usb = 0, allow_legacy = 0, ctrl_d_pressed = 0;
+
+ uint32_t allow_usb = 0;
+ uint32_t allow_legacy = 0;
+ uint32_t use_usb = 0;
+ uint32_t use_legacy = 0;
+ uint32_t default_boot = 0;
+ uint32_t ctrl_d_pressed = 0;
+
VbAudioContext *audio = 0;
VBDEBUG(("Entering %s()\n", __func__));
@@ -260,11 +288,23 @@
VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &allow_legacy);
+ /* Check if the default is to boot using disk, usb, or legacy */
+ VbNvGet(&vnc, VBNV_DEV_DEFAULT_BOOT, &default_boot);
+
+ if(default_boot == VBNV_DEV_DEFAULT_BOOT_USB)
+ use_usb = 1;
+ if(default_boot == VBNV_DEV_DEFAULT_BOOT_LEGACY)
+ use_legacy = 1;
+
/* 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;
+ if (gbb->flags & GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY) {
+ use_legacy = 1;
+ use_usb = 0;
+ }
/* Show the dev mode warning screen */
VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);
@@ -397,26 +437,10 @@
*/
VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0,
&vnc);
- if (VBERROR_SUCCESS ==
- VbTryLoadKernel(cparams, p,
- VB_DISK_FLAG_REMOVABLE)) {
- VBDEBUG(("VbBootDeveloper() - "
- "booting USB\n"));
+ if (VBERROR_SUCCESS == VbTryUsb(cparams, p)) {
VbAudioClose(audio);
return VBERROR_SUCCESS;
} else {
- VBDEBUG(("VbBootDeveloper() - "
- "no kernel found on USB\n"));
- VbExBeep(250, 200);
- VbExSleepMs(120);
- /*
- * Clear recovery requests from failed
- * kernel loading, so that powering off
- * at this point doesn't put us into
- * recovery mode.
- */
- VbSetRecoveryRequest(
- VBNV_RECOVERY_NOT_REQUESTED);
/* Show dev mode warning screen again */
VbDisplayScreen(
cparams,
@@ -435,12 +459,18 @@
fallout:
/* If defaulting to legacy boot, try that unless Ctrl+D was pressed */
- if ((gbb->flags & GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY) &&
- !ctrl_d_pressed) {
+ if (use_legacy && !ctrl_d_pressed) {
VBDEBUG(("VbBootDeveloper() - defaulting to legacy\n"));
VbTryLegacy(allow_legacy);
}
+ if ((use_usb && !ctrl_d_pressed) && allow_usb) {
+ if (VBERROR_SUCCESS == VbTryUsb(cparams, p)) {
+ VbAudioClose(audio);
+ return VBERROR_SUCCESS;
+ }
+ }
+
/* Timeout or Ctrl+D; attempt loading from fixed disk */
VBDEBUG(("VbBootDeveloper() - trying fixed disk\n"));
VbAudioClose(audio);
diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c
index 311bc8e..1ad3c86 100644
--- a/firmware/lib/vboot_display.c
+++ b/firmware/lib/vboot_display.c
@@ -569,6 +569,12 @@
"\ndev_boot_legacy: ", DEBUG_INFO_SIZE - used);
used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);
+ /* Add dev_default_boot flag */
+ VbNvGet(vncptr, VBNV_DEV_DEFAULT_BOOT, &i);
+ used += StrnAppend(buf + used,
+ "\ndev_default_boot: ", 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 += StrnAppend(buf + used, "\ndev_boot_signed_only: ",
diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index 6a21bfe..403ce30 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -42,6 +42,8 @@
#define DEV_BOOT_SIGNED_ONLY_MASK 0x02
#define DEV_BOOT_LEGACY_MASK 0x04
#define DEV_BOOT_FASTBOOT_FULL_CAP_MASK 0x08
+#define DEV_DEFAULT_BOOT_MASK 0x30
+#define DEV_DEFAULT_BOOT_SHIFT 4 /* Number of bits to shift */
#define TPM_FLAGS_OFFSET 5
#define TPM_CLEAR_OWNER_REQUEST 0x01
@@ -151,6 +153,11 @@
*dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_LEGACY_MASK ? 1 : 0);
return 0;
+ case VBNV_DEV_DEFAULT_BOOT:
+ *dest = (raw[DEV_FLAGS_OFFSET] & DEV_DEFAULT_BOOT_MASK)
+ >> DEV_DEFAULT_BOOT_SHIFT;
+ return 0;
+
case VBNV_DEV_BOOT_SIGNED_ONLY:
*dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_SIGNED_ONLY_MASK ?
1 : 0);
@@ -308,6 +315,17 @@
raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_LEGACY_MASK;
break;
+ case VBNV_DEV_DEFAULT_BOOT:
+ /* Map out of range values to boot disk */
+ if (value > (DEV_DEFAULT_BOOT_MASK >>
+ DEV_DEFAULT_BOOT_SHIFT))
+ value = VBNV_DEV_DEFAULT_BOOT_DISK;
+
+ raw[DEV_FLAGS_OFFSET] &= ~DEV_DEFAULT_BOOT_MASK;
+ raw[DEV_FLAGS_OFFSET] |= (uint8_t)value <<
+ DEV_DEFAULT_BOOT_SHIFT;
+ break;
+
case VBNV_DEV_BOOT_SIGNED_ONLY:
if (value)
raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_SIGNED_ONLY_MASK;
diff --git a/firmware/lib/vboot_nvstorage_rollback.c b/firmware/lib/vboot_nvstorage_rollback.c
index b1ec9ae..a913243 100644
--- a/firmware/lib/vboot_nvstorage_rollback.c
+++ b/firmware/lib/vboot_nvstorage_rollback.c
@@ -21,6 +21,7 @@
VBNV_DEV_BOOT_LEGACY,
VBNV_DEV_BOOT_SIGNED_ONLY,
VBNV_DEV_BOOT_FASTBOOT_FULL_CAP,
+ VBNV_DEV_DEFAULT_BOOT,
VBNV_FASTBOOT_UNLOCK_IN_FW,
};
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 3080344..e2066ce 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -61,6 +61,7 @@
} VbBuildOption;
static const char *fw_results[] = {"unknown", "trying", "success", "failure"};
+static const char *default_boot[] = {"disk", "usb", "legacy"};
/* Masks for kern_nv usage by kernel. */
#define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F
@@ -586,6 +587,12 @@
return fw_results[v];
else
return "unknown";
+ } else if (!strcasecmp(name,"dev_default_boot")) {
+ int v = VbGetNvStorage(VBNV_DEV_DEFAULT_BOOT);
+ if (v < ARRAY_SIZE(default_boot))
+ return default_boot[v];
+ else
+ return "unknown";
}
return NULL;
@@ -694,6 +701,14 @@
return VbSetNvStorage(VBNV_FW_RESULT, i);
}
return -1;
+ } else if (!strcasecmp(name, "dev_default_boot")) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(default_boot); i++) {
+ if (!strcasecmp(value, default_boot[i]))
+ return VbSetNvStorage(VBNV_DEV_DEFAULT_BOOT, i);
+ }
+ return -1;
}
return -1;
diff --git a/tests/vb2_misc_tests.c b/tests/vb2_misc_tests.c
index 8be5ae3..aa3b061 100644
--- a/tests/vb2_misc_tests.c
+++ b/tests/vb2_misc_tests.c
@@ -310,6 +310,7 @@
vb2_nv_set(&cc, VB2_NV_DEV_BOOT_LEGACY, 1);
vb2_nv_set(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
vb2_nv_set(&cc, VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP, 1);
+ vb2_nv_set(&cc, VB2_NV_DEV_DEFAULT_BOOT, 1);
vb2_nv_set(&cc, VB2_NV_FASTBOOT_UNLOCK_IN_FW, 1);
TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_USB),
@@ -320,6 +321,8 @@
0, " cleared dev boot signed only");
TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP),
0, " cleared dev boot fastboot full cap");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_DEFAULT_BOOT),
+ 0, " cleared dev default boot");
TEST_EQ(vb2_nv_get(&cc, VB2_NV_FASTBOOT_UNLOCK_IN_FW),
0, " cleared dev boot fastboot unlock in fw");
diff --git a/tests/vb2_nvstorage_tests.c b/tests/vb2_nvstorage_tests.c
index 0bf58b6..7796a1b 100644
--- a/tests/vb2_nvstorage_tests.c
+++ b/tests/vb2_nvstorage_tests.c
@@ -44,6 +44,7 @@
{VB2_NV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
{VB2_NV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
{VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP, 0, 1, 0, "dev boot fb full cap"},
+ {VB2_NV_DEV_DEFAULT_BOOT, 0, 1, 2, "dev default boot"},
{VB2_NV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
{VB2_NV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
{VB2_NV_CLEAR_TPM_OWNER_DONE, 0, 1, 0, "clear tpm owner done"},
@@ -195,6 +196,10 @@
vb2_nv_set(&c, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN + 100);
TEST_EQ(vb2_nv_get(&c, VB2_NV_FW_RESULT),
VB2_FW_RESULT_UNKNOWN, "Firmware result out of range");
+
+ vb2_nv_set(&c, VB2_NV_DEV_DEFAULT_BOOT, VB2_DEV_DEFAULT_BOOT_DISK + 100);
+ TEST_EQ(vb2_nv_get(&c, VB2_NV_DEV_DEFAULT_BOOT),
+ VB2_DEV_DEFAULT_BOOT_DISK, "default to booting from disk");
}
int main(int argc, char* argv[])
diff --git a/tests/vboot_api_init_tests.c b/tests/vboot_api_init_tests.c
index bfa5d7d..366873b 100644
--- a/tests/vboot_api_init_tests.c
+++ b/tests/vboot_api_init_tests.c
@@ -556,6 +556,7 @@
VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1);
VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 1);
+ VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 1);
VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 1);
/* and some that don't */
VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
@@ -586,6 +587,8 @@
TEST_EQ(u, 0, " NV dev_boot_signed_only");
VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u);
TEST_EQ(u, 0, " NV dev_boot_fastboot_full_cap");
+ VbNvGet(&vnc, VBNV_DEV_DEFAULT_BOOT, &u);
+ TEST_EQ(u, 0, " NV dev_default_boot");
VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u);
TEST_EQ(u, 0, " NV_fastboot_unlock_in_fw ");
/* So we should have written the backup */
@@ -605,6 +608,8 @@
TEST_EQ(u, 0, " BU dev_boot_signed_only");
VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u);
TEST_EQ(u, 0, " BU dev_boot_fastboot_full_cap");
+ VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u);
+ TEST_EQ(u, 0, " BU dev_default_boot");
VbNvGet(&tmp_vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u);
TEST_EQ(u, 0, " BU fastboot_unlock_in_fw");
/* but not the others */
@@ -647,6 +652,7 @@
VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1);
VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 1);
+ VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 1);
VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 1);
/* and some that don't */
VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
@@ -697,6 +703,8 @@
TEST_EQ(u, 1, " BU dev_boot_signed_only");
VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u);
TEST_EQ(u, 1, " BU dev_boot_fastboot_full_cap");
+ VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u);
+ TEST_EQ(u, 1, " BU dev_default_boot");
VbNvGet(&tmp_vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u);
TEST_EQ(u, 1, " BU fastboot_unlock_in_fw");
/* but not the others */
@@ -738,6 +746,8 @@
TEST_EQ(u, 1, " BU dev_boot_signed_only");
VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u);
TEST_EQ(u, 1, " BU dev_boot_fastboot_full_cap");
+ VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u);
+ TEST_EQ(u, 1, " BU dev_default_boot");
VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u);
TEST_EQ(u, 1, " BU fastboot_unlock_in_fw");
@@ -776,6 +786,8 @@
TEST_EQ(u, 0, " BU dev_boot_signed_only");
VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u);
TEST_EQ(u, 0, " BU dev_boot_fastboot_full_cap");
+ VbNvGet(&vnc, VBNV_DEV_DEFAULT_BOOT, &u);
+ TEST_EQ(u, 0, " BU dev_default_boot");
VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u);
TEST_EQ(u, 0, " BU fastboot_unlock_in_fw");
}
diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c
index 6420d51..aebfab6 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -293,6 +293,45 @@
TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
TEST_EQ(vbexlegacy_called, 1, " try legacy");
+ /* Proceed to legacy after timeout if boot legacy and default boot
+ * legacy are set */
+ ResetMocks();
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
+ VBNV_DEV_DEFAULT_BOOT_LEGACY);
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_LEGACY, 1);
+ TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
+ TEST_EQ(vbexlegacy_called, 1, " try legacy");
+
+ /* Proceed to legacy boot mode only if enabled */
+ ResetMocks();
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
+ VBNV_DEV_DEFAULT_BOOT_LEGACY);
+ TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
+ TEST_EQ(vbexlegacy_called, 0, " not legacy");
+
+ /* Proceed to usb after timeout if boot usb and default boot
+ * usb are set */
+ ResetMocks();
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
+ VBNV_DEV_DEFAULT_BOOT_USB);
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
+ vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
+ TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U USB");
+
+ /* Proceed to usb boot mode only if enabled */
+ ResetMocks();
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
+ VBNV_DEV_DEFAULT_BOOT_USB);
+ TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
+
+ /* If no USB tries fixed disk */
+ ResetMocks();
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
+ VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
+ VBNV_DEV_DEFAULT_BOOT_USB);
+ TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U enabled");
+ TEST_EQ(vbexlegacy_called, 0, " not legacy");
+
/* Up arrow is uninteresting / passed to VbCheckDisplayKey() */
ResetMocks();
mock_keypress[0] = VB_KEY_UP;
@@ -402,7 +441,6 @@
TEST_EQ(vbexlegacy_called, 0, " not legacy");
ResetMocks();
-
gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_LEGACY;
mock_keypress[0] = 0x0c;
TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L force legacy");
diff --git a/tests/vboot_nvstorage_test.c b/tests/vboot_nvstorage_test.c
index a82a742..6a90ea4 100644
--- a/tests/vboot_nvstorage_test.c
+++ b/tests/vboot_nvstorage_test.c
@@ -34,6 +34,7 @@
{VBNV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
{VBNV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
{VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 0, 1, 0, "dev boot fastboot full cap"},
+ {VBNV_DEV_DEFAULT_BOOT, 0, 1, 2, "dev default boot"},
{VBNV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
{VBNV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
{VBNV_CLEAR_TPM_OWNER_DONE, 0, 1, 0, "clear tpm owner done"},
@@ -189,6 +190,9 @@
VbNvSet(&c, VBNV_FW_RESULT, VBNV_FW_RESULT_UNKNOWN + 100);
VbNvGet(&c, VBNV_FW_RESULT, &data);
TEST_EQ(data, VBNV_FW_RESULT_UNKNOWN, "Firmware result out of range");
+ VbNvSet(&c, VBNV_DEV_DEFAULT_BOOT, VBNV_DEV_DEFAULT_BOOT_DISK + 100);
+ VbNvGet(&c, VBNV_DEV_DEFAULT_BOOT, &data);
+ TEST_EQ(data, VBNV_DEV_DEFAULT_BOOT_DISK, "Firmware result out of range");
VbNvTeardown(&c);
}
diff --git a/utility/crossystem.c b/utility/crossystem.c
index 2c017af..a1ef6e0 100644
--- a/utility/crossystem.c
+++ b/utility/crossystem.c
@@ -46,6 +46,8 @@
"Enable developer mode boot Legacy OSes (writable)"},
{"dev_boot_signed_only", CAN_WRITE,
"Enable developer mode boot only from official kernels (writable)"},
+ {"dev_default_boot", IS_STRING|CAN_WRITE,
+ "default boot from legacy or usb (writable)"},
{"devsw_boot", 0, "Developer switch position at boot"},
{"devsw_cur", 0, "Developer switch current position"},
{"disable_dev_request", CAN_WRITE, "Disable virtual dev-mode on next boot"},