mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
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>
113 lines
3.6 KiB
C
113 lines
3.6 KiB
C
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* High-level firmware wrapper API - entry points for init, firmware selection
|
|
*/
|
|
|
|
#include "gbb_header.h"
|
|
#include "load_firmware_fw.h"
|
|
#include "rollback_index.h"
|
|
#include "tpm_bootmode.h"
|
|
#include "utility.h"
|
|
#include "vboot_api.h"
|
|
#include "vboot_common.h"
|
|
#include "vboot_nvstorage.h"
|
|
|
|
VbError_t VbSelectFirmware(VbCommonParams* cparams,
|
|
VbSelectFirmwareParams* fparams) {
|
|
VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
|
|
VbNvContext vnc;
|
|
VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven successful */
|
|
int is_rec = (shared->recovery_reason ? 1 : 0);
|
|
int is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
|
|
uint32_t tpm_status = 0;
|
|
|
|
/* Start timer */
|
|
shared->timer_vb_select_firmware_enter = VbExGetTimer();
|
|
|
|
/* Load NV storage */
|
|
VbExNvStorageRead(vnc.raw);
|
|
VbNvSetup(&vnc);
|
|
|
|
if (is_rec) {
|
|
/* Recovery is requested; go straight to recovery without checking the
|
|
* RW firmware. */
|
|
VBDEBUG(("VbSelectFirmware() detected recovery request\n"));
|
|
|
|
/* Go directly to recovery mode */
|
|
fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY;
|
|
|
|
} else {
|
|
/* Chain to LoadFirmware() */
|
|
retval = LoadFirmware(cparams, fparams, &vnc);
|
|
|
|
/* Exit if we failed to find an acceptable firmware */
|
|
if (VBERROR_SUCCESS != retval)
|
|
goto VbSelectFirmware_exit;
|
|
|
|
/* Translate the selected firmware path */
|
|
if (shared->flags & VBSD_LF_USE_RO_NORMAL) {
|
|
/* Request the read-only normal/dev code path */
|
|
fparams->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
|
|
} else if (0 == shared->firmware_index)
|
|
fparams->selected_firmware = VB_SELECT_FIRMWARE_A;
|
|
else
|
|
fparams->selected_firmware = VB_SELECT_FIRMWARE_B;
|
|
|
|
/* Update TPM if necessary */
|
|
if (shared->fw_version_tpm_start < shared->fw_version_tpm) {
|
|
VBPERFSTART("VB_TPMU");
|
|
tpm_status = RollbackFirmwareWrite(shared->fw_version_tpm);
|
|
VBPERFEND("VB_TPMU");
|
|
if (0 != tpm_status) {
|
|
VBDEBUG(("Unable to write firmware version to TPM.\n"));
|
|
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
|
|
retval = VBERROR_TPM_WRITE_FIRMWARE;
|
|
goto VbSelectFirmware_exit;
|
|
}
|
|
}
|
|
|
|
/* Lock firmware versions in TPM */
|
|
VBPERFSTART("VB_TPML");
|
|
tpm_status = RollbackFirmwareLock();
|
|
VBPERFEND("VB_TPML");
|
|
if (0 != tpm_status) {
|
|
VBDEBUG(("Unable to lock firmware version in TPM.\n"));
|
|
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
|
|
retval = VBERROR_TPM_LOCK_FIRMWARE;
|
|
goto VbSelectFirmware_exit;
|
|
}
|
|
}
|
|
|
|
/* At this point, we have a good idea of how we are going to
|
|
* boot. Update the TPM with this state information. */
|
|
tpm_status = SetTPMBootModeState(is_dev, is_rec, shared->fw_keyblock_flags);
|
|
if (0 != tpm_status) {
|
|
VBDEBUG(("Unable to update the TPM with boot mode information.\n"));
|
|
if (!is_rec) {
|
|
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
|
|
retval = VBERROR_TPM_SET_BOOT_MODE_STATE;
|
|
goto VbSelectFirmware_exit;
|
|
}
|
|
}
|
|
|
|
/* Success! */
|
|
retval = VBERROR_SUCCESS;
|
|
|
|
VbSelectFirmware_exit:
|
|
|
|
/* Save NV storage */
|
|
VbNvTeardown(&vnc);
|
|
if (vnc.raw_changed)
|
|
VbExNvStorageWrite(vnc.raw);
|
|
|
|
/* Stop timer */
|
|
shared->timer_vb_select_firmware_exit = VbExGetTimer();
|
|
|
|
/* Should always have a known error code */
|
|
VbAssert(VBERROR_UNKNOWN != retval);
|
|
|
|
return retval;
|
|
}
|