diff options
author | Mary Ruthven <mruthven@google.com> | 2015-10-06 10:42:31 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-10-13 14:02:26 -0700 |
commit | 12a55f255aaea2f12362e4f832a0bd48eb29f5dd (patch) | |
tree | f235ebf2cd846c852371a96cf76e3282ff0c26be | |
parent | 73a6372d22f74d0396253f6e5080442edec55d7f (diff) | |
download | vboot-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.c | 1 | ||||
-rw-r--r-- | firmware/2lib/2nvstorage.c | 15 | ||||
-rw-r--r-- | firmware/2lib/include/2nvstorage.h | 15 | ||||
-rw-r--r-- | firmware/2lib/include/2nvstorage_fields.h | 4 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 15 | ||||
-rw-r--r-- | firmware/lib/vboot_api_init.c | 1 | ||||
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 70 | ||||
-rw-r--r-- | firmware/lib/vboot_display.c | 6 | ||||
-rw-r--r-- | firmware/lib/vboot_nvstorage.c | 18 | ||||
-rw-r--r-- | firmware/lib/vboot_nvstorage_rollback.c | 1 | ||||
-rw-r--r-- | host/lib/crossystem.c | 15 | ||||
-rw-r--r-- | tests/vb2_misc_tests.c | 3 | ||||
-rw-r--r-- | tests/vb2_nvstorage_tests.c | 5 | ||||
-rw-r--r-- | tests/vboot_api_init_tests.c | 12 | ||||
-rw-r--r-- | tests/vboot_api_kernel2_tests.c | 40 | ||||
-rw-r--r-- | tests/vboot_nvstorage_test.c | 4 | ||||
-rw-r--r-- | utility/crossystem.c | 2 |
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"}, |