mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
Support virtual dev-switch (keyboard-based dev-mode)
BUG=chrome-os-partner:9706
TEST=manual
Currently, Link is the only platform that enables this feature.
To enter dev-mode:
Boot into recovery mode using the magic key chord. At the Insert screen,
press Ctrl-D. You'll be asked if you want to enter developer mode. If you
then press ENTER, it will reboot with dev-mode enabled. If you press SPACE
or ESC, it will return to the Insert screen.
If you enter recovery mode through any other means, or if dev-mode is
already enabled, pressing Ctrl-D at the Insert screen will have no effect.
To return to normal mode:
Reboot. At the Dev screen, press ENTER or SPACE. It will reboot to
recovery mode and ask you if you want to return to normal mode. If you
press ESC or power off, you'll still be in dev-mode. Press ENTER or SPACE,
and it will reboot into normal mode (of course, if you've messed up your
images while in dev-mode, you'll just come right back to recovery mode
again).
You can also request a direct return to normal mode by running
crossystem disable_dev_request=1
and rebooting.
Change-Id: I435905855a6c39932ee466cc046bdc4c4c860f98
Reviewed-on: https://gerrit.chromium.org/gerrit/24160
Tested-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Ready: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -110,6 +110,7 @@ uint32_t VbTryLoadKernel(VbCommonParams* cparams, LoadKernelParams* p,
|
||||
/* Handle a normal boot. */
|
||||
VbError_t VbBootNormal(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
/* Boot from fixed disk only */
|
||||
VBDEBUG(("Entering %s()\n", __func__));
|
||||
return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
|
||||
}
|
||||
|
||||
@@ -118,6 +119,8 @@ VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
uint32_t allow_usb = 0;
|
||||
VbAudioContext* audio = 0;
|
||||
|
||||
VBDEBUG(("Entering %s()\n", __func__));
|
||||
|
||||
/* Check if USB booting is allowed */
|
||||
VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
|
||||
|
||||
@@ -202,6 +205,49 @@ fallout:
|
||||
}
|
||||
|
||||
|
||||
/* FIXME(crosbug.com/p/9953): The platform BIOS should implement this! */
|
||||
/* And not here: somewhere outside of vboot with the other VbEx functions */
|
||||
int VbExTrustEC(void) {
|
||||
/* Only return true if the EC is running in its RO firmware *right now*. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Ask the user to confirm changing the virtual dev-mode switch. If they confirm
|
||||
* we'll change it and return a reason to reboot. */
|
||||
static VbError_t VbConfirmChangeDevMode(VbCommonParams* cparams, int to_dev) {
|
||||
uint32_t key;
|
||||
|
||||
VBDEBUG(("Entering %s(%d)\n", __func__, to_dev));
|
||||
/* Show the dev-mode confirmation screen */
|
||||
VbDisplayScreen(cparams, (to_dev ? VB_SCREEN_RECOVERY_TO_DEV
|
||||
: VB_SCREEN_RECOVERY_TO_NORM), 0, &vnc);
|
||||
|
||||
/* Await further instructions */
|
||||
while (1) {
|
||||
if (VbExIsShutdownRequested())
|
||||
return VBERROR_SHUTDOWN_REQUESTED;
|
||||
/* ENTER is always yes, ESC is always no.
|
||||
* SPACE is yes when leaving dev-mode, but is no when entering it. */
|
||||
key = VbExKeyboardRead();
|
||||
if (key == '\r' || (key == ' ' && !to_dev)) {
|
||||
VBDEBUG(("%s() - Yes: virtual dev-mode switch => %d\n",
|
||||
__func__, to_dev));
|
||||
if (TPM_SUCCESS != SetVirtualDevMode(to_dev))
|
||||
return VBERROR_TPM_SET_BOOT_MODE_STATE;
|
||||
VBDEBUG(("%s() - Reboot so it will take effect\n", __func__));
|
||||
return VBERROR_TPM_REBOOT_REQUIRED;
|
||||
} else if (key == 0x1B || (key == ' ' && to_dev)) {
|
||||
VBDEBUG(("%s() - No: don't change virtual dev-mode switch\n", __func__));
|
||||
VbDisplayScreen(cparams, VB_SCREEN_RECOVERY_INSERT, 0, &vnc);
|
||||
return VBERROR_SUCCESS;
|
||||
} else if (key) {
|
||||
/* Anything else, just keep waiting */
|
||||
VbCheckDisplayKey(cparams, key, &vnc);
|
||||
VbExSleepMs(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delay between disk checks in recovery mode */
|
||||
#define REC_DELAY_INCREMENT 250
|
||||
|
||||
@@ -209,6 +255,7 @@ fallout:
|
||||
VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
|
||||
uint32_t retval;
|
||||
uint32_t key;
|
||||
int i;
|
||||
|
||||
VBDEBUG(("VbBootRecovery() start\n"));
|
||||
@@ -224,7 +271,7 @@ VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
|
||||
while (1) {
|
||||
if (VBERROR_SUCCESS != VbExDiskGetInfo(&disk_info, &disk_count,
|
||||
VB_DISK_FLAG_REMOVABLE))
|
||||
VB_DISK_FLAG_REMOVABLE))
|
||||
disk_count = 0;
|
||||
VbExDiskFreeInfo(disk_info, NULL);
|
||||
|
||||
@@ -249,6 +296,18 @@ VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
}
|
||||
}
|
||||
|
||||
/* See if we should disable the virtual dev-mode switch. */
|
||||
VBDEBUG(("VbBootRecovery() shared->flags=0x%x, recovery_reason=%d\n",
|
||||
shared->flags, shared->recovery_reason));
|
||||
if (shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
|
||||
shared->flags & VBSD_BOOT_DEV_SWITCH_ON &&
|
||||
shared->recovery_reason == VBNV_RECOVERY_RW_DEV_SCREEN) {
|
||||
retval = VbConfirmChangeDevMode(cparams, 0); /* .. so go ask */
|
||||
VBDEBUG(("VbConfirmChangeDevMode() returned %d\n", retval));
|
||||
if (retval != VBERROR_SUCCESS)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Loop and wait for a recovery image */
|
||||
while (1) {
|
||||
VBDEBUG(("VbBootRecovery() attempting to load kernel\n"));
|
||||
@@ -260,7 +319,7 @@ VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);
|
||||
|
||||
if (VBERROR_SUCCESS == retval)
|
||||
break; /* Found a recovery kernel */
|
||||
break; /* Found a recovery kernel */
|
||||
|
||||
VbDisplayScreen(cparams, VBERROR_NO_DISK_FOUND == retval ?
|
||||
VB_SCREEN_RECOVERY_INSERT : VB_SCREEN_RECOVERY_NO_GOOD,
|
||||
@@ -269,7 +328,19 @@ VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
|
||||
/* Scan keyboard more frequently than media, since x86 platforms don't like
|
||||
* to scan USB too rapidly. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
VbCheckDisplayKey(cparams, VbExKeyboardRead(), &vnc);
|
||||
key = VbExKeyboardRead();
|
||||
/* We might want to enter dev-mode from the Insert screen if... */
|
||||
if (key == 0x04 && /* user pressed Ctrl-D */
|
||||
shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH && /* we can do that */
|
||||
!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) && /* not in dev-mode */
|
||||
(shared->flags & VBSD_BOOT_REC_SWITCH_ON) && /* user forced rec */
|
||||
VbExTrustEC()) { /* EC isn't pwned */
|
||||
retval = VbConfirmChangeDevMode(cparams, 1); /* .. so go ask */
|
||||
VBDEBUG(("VbConfirmChangeDevMode() returned %d\n", retval));
|
||||
if (retval != VBERROR_SUCCESS)
|
||||
return retval;
|
||||
} else
|
||||
VbCheckDisplayKey(cparams, key, &vnc);
|
||||
if (VbExIsShutdownRequested())
|
||||
return VBERROR_SHUTDOWN_REQUESTED;
|
||||
VbExSleepMs(REC_DELAY_INCREMENT);
|
||||
@@ -287,8 +358,6 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams,
|
||||
LoadKernelParams p;
|
||||
uint32_t tpm_status = 0;
|
||||
|
||||
VBDEBUG(("VbSelectAndLoadKernel() start\n"));
|
||||
|
||||
/* Start timer */
|
||||
shared->timer_vb_select_and_load_kernel_enter = VbExGetTimer();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user