summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2015-10-06 10:42:31 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-10-13 14:02:26 -0700
commit12a55f255aaea2f12362e4f832a0bd48eb29f5dd (patch)
treef235ebf2cd846c852371a96cf76e3282ff0c26be
parent73a6372d22f74d0396253f6e5080442edec55d7f (diff)
downloadvboot-12a55f255aaea2f12362e4f832a0bd48eb29f5dd.tar.gz
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>
-rw-r--r--firmware/2lib/2misc.c1
-rw-r--r--firmware/2lib/2nvstorage.c15
-rw-r--r--firmware/2lib/include/2nvstorage.h15
-rw-r--r--firmware/2lib/include/2nvstorage_fields.h4
-rw-r--r--firmware/include/vboot_nvstorage.h15
-rw-r--r--firmware/lib/vboot_api_init.c1
-rw-r--r--firmware/lib/vboot_api_kernel.c70
-rw-r--r--firmware/lib/vboot_display.c6
-rw-r--r--firmware/lib/vboot_nvstorage.c18
-rw-r--r--firmware/lib/vboot_nvstorage_rollback.c1
-rw-r--r--host/lib/crossystem.c15
-rw-r--r--tests/vb2_misc_tests.c3
-rw-r--r--tests/vb2_nvstorage_tests.c5
-rw-r--r--tests/vboot_api_init_tests.c12
-rw-r--r--tests/vboot_api_kernel2_tests.c40
-rw-r--r--tests/vboot_nvstorage_test.c4
-rw-r--r--utility/crossystem.c2
17 files changed, 205 insertions, 22 deletions
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 4b30a5c6..a8567758 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -276,6 +276,7 @@ int vb2_check_dev_switch(struct vb2_context *ctx)
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 55f1d0dd..851c3872 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -139,6 +139,10 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param)
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 @@ void vb2_nv_set(struct vb2_context *ctx,
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 bfe9a3a3..31dfc8df 100644
--- a/firmware/2lib/include/2nvstorage.h
+++ b/firmware/2lib/include/2nvstorage.h
@@ -55,6 +55,8 @@ enum vb2_nv_param {
* 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 @@ enum vb2_nv_param {
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 8ae21f87..fd625d06 100644
--- a/firmware/2lib/include/2nvstorage_fields.h
+++ b/firmware/2lib/include/2nvstorage_fields.h
@@ -57,11 +57,13 @@ enum vb2_nv_offset {
#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 5a44ae14..dc4ab50e 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -76,6 +76,8 @@ typedef enum VbNvParam {
* 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 @@ typedef enum VbNvParam {
} 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 419175cf..2657fb5d 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -323,6 +323,7 @@ VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams)
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 0456123b..7b47dc69 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -170,6 +170,27 @@ uint32_t VbTryLoadKernel(VbCommonParams *cparams, LoadKernelParams *p,
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 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
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 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
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 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
*/
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 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
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 311bc8ef..1ad3c869 100644
--- a/firmware/lib/vboot_display.c
+++ b/firmware/lib/vboot_display.c
@@ -569,6 +569,12 @@ VbError_t VbDisplayDebugInfo(VbCommonParams *cparams, VbNvContext *vncptr)
"\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 6a21bfe8..403ce30f 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 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest)
*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 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
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 b1ec9aea..a9132436 100644
--- a/firmware/lib/vboot_nvstorage_rollback.c
+++ b/firmware/lib/vboot_nvstorage_rollback.c
@@ -21,6 +21,7 @@ static const VbNvParam backup_params[] = {
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 3080344d..e2066cee 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -61,6 +61,7 @@ typedef enum VbBuildOption {
} 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 @@ const char* VbGetSystemPropertyString(const char* name, char* dest,
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 @@ int VbSetSystemPropertyString(const char* name, const char* value) {
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 8be5ae3a..aa3b061f 100644
--- a/tests/vb2_misc_tests.c
+++ b/tests/vb2_misc_tests.c
@@ -310,6 +310,7 @@ static void dev_switch_tests(void)
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 @@ static void dev_switch_tests(void)
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 0bf58b61..7796a1b4 100644
--- a/tests/vb2_nvstorage_tests.c
+++ b/tests/vb2_nvstorage_tests.c
@@ -44,6 +44,7 @@ static struct nv_field nvfields[] = {
{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 @@ static void nv_storage_test(void)
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 bfa5d7df..366873b6 100644
--- a/tests/vboot_api_init_tests.c
+++ b/tests/vboot_api_init_tests.c
@@ -556,6 +556,7 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 @@ static void VbInitTestBackup(void)
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 6420d518..aebfab64 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -293,6 +293,45 @@ static void VbBootDevTest(void)
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 @@ static void VbBootDevTest(void)
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 a82a7429..6a90ea4d 100644
--- a/tests/vboot_nvstorage_test.c
+++ b/tests/vboot_nvstorage_test.c
@@ -34,6 +34,7 @@ static VbNvField nvfields[] = {
{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 @@ static void VbNvStorageTest(void) {
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 2c017aff..a1ef6e06 100644
--- a/utility/crossystem.c
+++ b/utility/crossystem.c
@@ -46,6 +46,8 @@ const Param sys_param_list[] = {
"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"},