summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-07-08 14:01:54 -0700
committerRandall Spangler <rspangler@chromium.org>2011-07-08 16:19:07 -0700
commit9619112a574b975476667545e3a326052fa0c50b (patch)
treec0eae41a3b481cab3029fa1283fdf6b6d8c0d8ed
parent1b1998dff0002f20b3f27a21e6e79d8951e64684 (diff)
downloadvboot-9619112a574b975476667545e3a326052fa0c50b.tar.gz
Vboot wrapper - add recovery reason, refactor timing
Pressing Tab at a firmware screen now displays real data, including the recovery reason, HWID, and contents of VbNvStorage. Entry point start/end time tracking in VbSharedData now refers to the new wrapper APIs. Added capability for calling firmware to request recovery mode (for example, if it's unable to initialize RAM, can't find the SSD, etc.). Previously, calling firmware had no (good) way to do this other than faking the recovery button being pressed. BUG=chromium-os:17018 TEST=emerge on x86 and tegra2_seaboard Change-Id: I7d377f279842b30a10d945d13571c41c464633f1 Reviewed-on: http://gerrit.chromium.org/gerrit/3814 Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--firmware/include/vboot_api.h14
-rw-r--r--firmware/include/vboot_nvstorage.h3
-rw-r--r--firmware/include/vboot_struct.h19
-rw-r--r--firmware/lib/vboot_api_firmware.c7
-rw-r--r--firmware/lib/vboot_api_init.c47
-rw-r--r--firmware/lib/vboot_api_kernel.c65
-rw-r--r--firmware/lib/vboot_firmware.c5
-rw-r--r--firmware/lib/vboot_kernel.c180
-rw-r--r--firmware/linktest/main.c3
-rw-r--r--host/lib/crossystem.c12
10 files changed, 175 insertions, 180 deletions
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index c9eeb33d..48859e06 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -95,7 +95,11 @@ typedef struct VbCommonParams {
#define VB_INIT_FLAG_WP_ENABLED 0x00000004
/* This is a S3 resume, not a normal boot. */
#define VB_INIT_FLAG_S3_RESUME 0x00000008
-
+/* Previous boot attempt failed for reasons external to verified boot (RAM
+ * init failure, SSD missing, etc.). */
+/* TODO: add a field to VbInitParams which holds a reason code, and report
+ * that via VbSharedData. */
+#define VB_INIT_FLAG_PREVIOUS_BOOT_FAIL 0x00000010
/* Output flags for VbInitParams.out_flags. Used to indicate
* potential boot paths and configuration to the calling firmware
@@ -210,14 +214,6 @@ void VbUpdateFirmwareBodyHash(VbCommonParams* cparams,
VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams,
VbSelectAndLoadKernelParams* kparams);
-/* S3 resume handler. This only needs to be called if the hardware
- * does not maintain power to the TPM when in S3 (suspend-to-RAM).
- *
- * Returns VBERROR_SUCCESS if success, non-zero if error; on error,
- * caller should reboot. */
-VbError_t VbS3Resume(void);
-
-
/*****************************************************************************/
/* Debug output (from utility.h) */
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h
index 02f81a70..046dd75d 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -86,6 +86,9 @@ typedef enum VbNvParam {
* vboot_struct.h. */
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN 0x10
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX 0x1F
+/* Firmware boot failure outside of verified boot (RAM init, missing SSD,
+ * etc.). */
+#define VBNV_RECOVERY_RO_FIRMWARE 0x20
/* Unspecified/unknown error in read-only firmware */
#define VBNV_RECOVERY_RO_UNSPECIFIED 0x3F
/* User manually requested recovery by pressing a key at developer
diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h
index e9336dfe..0271979c 100644
--- a/firmware/include/vboot_struct.h
+++ b/firmware/include/vboot_struct.h
@@ -280,14 +280,17 @@ typedef struct VbSharedDataHeader {
uint64_t kernel_subkey_data_size; /* Size of kernel subkey data */
/* Timer values from VbExGetTimer(). Unused values are set to 0.
- * If a function is called mutiple times, these are the times from
- * the most recent call. See crosbug.com/17018. */
- uint64_t timer_load_firmware_start_enter; /* VbInit() - enter */
- uint64_t timer_load_firmware_start_exit; /* VbInit() - exit */
- uint64_t timer_load_firmware_enter; /* LoadFirmware() - enter */
- uint64_t timer_load_firmware_exit; /* LoadFirmware() - exit */
- uint64_t timer_load_kernel_enter; /* LoadKernel() - enter */
- uint64_t timer_load_kernel_exit; /* LoadKernel() - exit */
+ * Note that these are now the enter/exit times for the wrapper API entry
+ * points; see crosbug.com/17018. */
+ /* VbInit() enter/exit */
+ uint64_t timer_vb_init_enter;
+ uint64_t timer_vb_init_exit;
+ /* VbSelectFirmware() enter/exit */
+ uint64_t timer_vb_select_firmware_enter;
+ uint64_t timer_vb_select_firmware_exit;
+ /* VbSelectAndLoadKernel() enter/exit */
+ uint64_t timer_vb_select_and_load_kernel_enter;
+ uint64_t timer_vb_select_and_load_kernel_exit;
/* Information stored in TPM, as retrieved by firmware */
uint32_t fw_version_tpm; /* Current firmware version in TPM */
diff --git a/firmware/lib/vboot_api_firmware.c b/firmware/lib/vboot_api_firmware.c
index b4c14811..e4e4af02 100644
--- a/firmware/lib/vboot_api_firmware.c
+++ b/firmware/lib/vboot_api_firmware.c
@@ -20,11 +20,15 @@ VbError_t VbSelectFirmware(VbCommonParams* cparams,
VbNvContext vnc;
int rv;
+ /* Start timer */
+ shared->timer_vb_select_firmware_enter = VbExGetTimer();
+
/* If recovery is requested, go straight to recovery without checking the
* RW firmware. */
if (VBNV_RECOVERY_NOT_REQUESTED != shared->recovery_reason) {
VBDEBUG(("VbSelectFirmware() detected recovery request, reason=%d.\n",
(int)shared->recovery_reason));
+ shared->timer_vb_select_firmware_exit = VbExGetTimer();
fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY;
return VBERROR_SUCCESS;
}
@@ -66,6 +70,9 @@ VbError_t VbSelectFirmware(VbCommonParams* cparams,
/* Copy amount of used shared data back to the wrapper API struct */
cparams->shared_data_size = (uint32_t)p.shared_data_size;
+ /* Stop timer */
+ shared->timer_vb_select_firmware_exit = VbExGetTimer();
+
/* Translate return codes */
if (LOAD_FIRMWARE_SUCCESS == rv) {
/* Found good firmware in either A or B */
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index 8bccfe53..890b5768 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -17,6 +17,7 @@
VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
VbNvContext vnc;
+ VbError_t retval = VBERROR_SUCCESS;
uint32_t recovery = VBNV_RECOVERY_NOT_REQUESTED;
int is_s3_resume = 0;
uint32_t s3_debug_boot = 0;
@@ -36,7 +37,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
return 1;
}
- shared->timer_load_firmware_start_enter = VbExGetTimer();
+ shared->timer_vb_init_enter = VbExGetTimer();
/* Copy boot switch flags */
shared->flags = 0;
@@ -74,6 +75,15 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_NOT_REQUESTED);
}
+ /* If the previous boot failed in the firmware somewhere outside of verified
+ * boot, and recovery is not requested for our own reasons, request recovery
+ * mode. This gives the calling firmware a way to request recovery if it
+ * finds something terribly wrong. */
+ if (VBNV_RECOVERY_NOT_REQUESTED == recovery &&
+ iparams->flags & VB_INIT_FLAG_PREVIOUS_BOOT_FAIL) {
+ recovery = VBNV_RECOVERY_RO_FIRMWARE;
+ }
+
/* If recovery button is pressed, override recovery reason. Note that we
* do this in the S3 resume path also. */
if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED)
@@ -97,11 +107,15 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
/* Copy current recovery reason to shared data */
shared->recovery_reason = (uint8_t)recovery;
- /* Clear the recovery request, so we won't get stuck in recovery mode */
- VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_NOT_REQUESTED);
-
- // TODO: Handle S3 resume path ourselves, if VB_INIT_FLAG_S3_RESUME
- // (I believe we can do this now...)
+ /* If this is a S3 resume, resume the TPM */
+ if (is_s3_resume) {
+ if (TPM_SUCCESS != RollbackS3Resume()) {
+ /* If we can't resume, just do a full reboot. No need to go to recovery
+ * mode here, since if the TPM is really broken we'll catch it on the
+ * next boot. */
+ retval = 1;
+ }
+ }
/* Tear down NV storage */
VbNvTeardown(&vnc);
@@ -110,24 +124,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) {
VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags));
- shared->timer_load_firmware_start_exit = VbExGetTimer();
-
- return VBERROR_SUCCESS;
-}
-
-
-VbError_t VbS3Resume(void) {
+ shared->timer_vb_init_exit = VbExGetTimer();
- /* TODO: handle test errors (requires passing in VbNvContext) */
-
- /* Resume the TPM */
- uint32_t status = RollbackS3Resume();
-
- /* If we can't resume, just do a full reboot. No need to go to recovery
- * mode here, since if the TPM is really broken we'll catch it on the
- * next boot. */
- if (status == TPM_SUCCESS)
- return VBERROR_SUCCESS;
- else
- return 1;
+ return retval;
}
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 1afac378..738c4769 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -219,24 +219,67 @@ static VbError_t VbDisplayScreen(VbCommonParams* cparams, uint32_t screen,
return VbExDisplayScreen(screen);
}
+#define DEBUG_INFO_SIZE 512
static VbError_t VbCheckDisplayKey(VbCommonParams* cparams, uint32_t key) {
+ VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
+ GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
if ('\t' == key) {
/* Tab = display debug info */
+ char buf[DEBUG_INFO_SIZE] = "";
+ uint32_t used = 0;
+ uint32_t i;
/* Redisplay the current screen, to overwrite any previous debug output */
VbDisplayScreen(cparams, disp_current_screen, 1);
- /* TODO: add real data:
- * - HWID
- * - Current recovery request
- * - Boot flags
+ /* Add hardware ID */
+ used += Strncat(buf + used, "HWID: ", DEBUG_INFO_SIZE - used);
+ if (0 == gbb->hwid_size ||
+ gbb->hwid_offset > cparams->gbb_size ||
+ gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) {
+ VBDEBUG(("VbCheckDisplayKey(): invalid hwid offset/size\n"));
+ used += Strncat(buf + used, "(INVALID)", DEBUG_INFO_SIZE - used);
+ } else {
+ used += Strncat(buf + used, (char*)((uint8_t*)gbb + gbb->hwid_offset),
+ DEBUG_INFO_SIZE - used);
+ }
+
+ /* Add recovery request */
+ used += Strncat(buf + used, "\nrecovery_request: 0x",
+ DEBUG_INFO_SIZE - used);
+ used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
+ shared->recovery_reason, 16, 2);
+
+ /* Add VbSharedData flags */
+ used += Strncat(buf + used, "\nVbSD.flags: 0x", DEBUG_INFO_SIZE - used);
+ used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
+ shared->flags, 16, 8);
+
+ /* Add raw contents of VbNvStorage */
+ used += Strncat(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used);
+ for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
+ used += Strncat(buf + used, " ", DEBUG_INFO_SIZE - used);
+ used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
+ vnc.raw[i], 16, 2);
+ }
+
+ used += Strncat(buf + used, "\n", DEBUG_INFO_SIZE - used);
+
+ /* TODO: add more interesting data:
+ * - TPM firmware and kernel versions. In the current code, they're
+ * only filled into VbSharedData by LoadFirmware() and LoadKernel(), and
+ * since neither of those is called in the recovery path this isn't
+ * feasible yet.
+ * - SHA1 of kernel subkey (assuming we always set it in VbSelectFirmware,
+ * even in recovery mode, where we just copy it from the root key)
* - Information on current disks
- * - Anything else interesting from cparams and/or nvram
- *
- * TODO: Add a VbExSnprintf() function for this? */
- return VbExDisplayDebugInfo("Testing 1 2 3\nTesting 4 5 6\n");
+ * - Anything else interesting from VbNvStorage */
+
+ buf[DEBUG_INFO_SIZE - 1] = '\0';
+ VBDEBUG(("VbCheckDisplayKey() wants to show '%s'\n", buf));
+ return VbExDisplayDebugInfo(buf);
} else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key) {
/* Arrow keys = change localization */
@@ -505,6 +548,9 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams,
VBDEBUG(("VbSelectAndLoadKernel() start\n"));
+ /* Start timer */
+ shared->timer_vb_select_and_load_kernel_enter = VbExGetTimer();
+
VbExNvStorageRead(vnc.raw);
vnc.raw_changed = 0;
@@ -563,6 +609,9 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams,
if (vnc.raw_changed)
VbExNvStorageWrite(vnc.raw);
+ /* Stop timer */
+ shared->timer_vb_select_and_load_kernel_exit = VbExGetTimer();
+
VBDEBUG(("VbSelectAndLoadKernel() returning %d\n", (int)retval));
/* Pass through return value from boot path */
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c
index 1022ad9d..1e989a4d 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -64,9 +64,6 @@ int LoadFirmware(LoadFirmwareParams* params) {
/* Setup NV storage */
VbNvSetup(vnc);
- /* Start timer */
- shared->timer_load_firmware_enter = VbExGetTimer();
-
/* Handle test errors */
VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err);
if (VBNV_TEST_ERROR_LOAD_FIRMWARE == test_err) {
@@ -378,8 +375,6 @@ LoadFirmwareExit:
recovery : VBNV_RECOVERY_NOT_REQUESTED);
VbNvTeardown(vnc);
- shared->timer_load_firmware_exit = VbExGetTimer();
-
/* Note that we don't reduce params->shared_data_size to shared->data_used,
* since we want to leave space for LoadKernel() to add to the shared data
* buffer. */
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 26c91210..97d32d34 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -145,7 +145,6 @@ int LoadKernel(LoadKernelParams* params) {
int retval = LOAD_KERNEL_RECOVERY;
int recovery = VBNV_RECOVERY_RO_UNSPECIFIED;
- uint64_t timer_enter = VbExGetTimer();
/* Setup NV storage */
VbNvSetup(vnc);
@@ -178,38 +177,23 @@ int LoadKernel(LoadKernelParams* params) {
dev_switch = 0; /* Always do a fully verified boot */
}
- if (kBootRecovery == boot_mode) {
- /* Initialize the shared data structure, since LoadFirmware() didn't do it
- * for us. */
- if (0 != VbSharedDataInit(shared, params->shared_data_size)) {
- /* Error initializing the shared data, but we can keep going. We just
- * can't use the shared data. */
- VBDEBUG(("Shared data init error\n"));
- params->shared_data_size = 0;
- shared = NULL;
- }
- }
-
- if (shared) {
- /* Set up tracking for this call. This wraps around if called many times,
- * so we need to initialize the call entry each time. */
- shcall = shared->lk_calls + (shared->lk_call_count
- & (VBSD_MAX_KERNEL_CALLS - 1));
- Memset(shcall, 0, sizeof(VbSharedDataKernelCall));
- shcall->boot_flags = (uint32_t)params->boot_flags;
- shcall->boot_mode = boot_mode;
- shcall->sector_size = (uint32_t)params->bytes_per_lba;
- shcall->sector_count = params->ending_lba + 1;
- shared->lk_call_count++;
- }
+ /* Set up tracking for this call. This wraps around if called many times,
+ * so we need to initialize the call entry each time. */
+ shcall = shared->lk_calls + (shared->lk_call_count
+ & (VBSD_MAX_KERNEL_CALLS - 1));
+ Memset(shcall, 0, sizeof(VbSharedDataKernelCall));
+ shcall->boot_flags = (uint32_t)params->boot_flags;
+ shcall->boot_mode = boot_mode;
+ shcall->sector_size = (uint32_t)params->bytes_per_lba;
+ shcall->sector_count = params->ending_lba + 1;
+ shared->lk_call_count++;
/* Handle test errors */
VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err);
if (VBNV_TEST_ERROR_LOAD_KERNEL == test_err) {
/* Get error code */
VbNvGet(vnc, VBNV_TEST_ERROR_NUM, &test_err);
- if (shcall)
- shcall->test_error_num = (uint8_t)test_err;
+ shcall->test_error_num = (uint8_t)test_err;
/* Clear test params so we don't repeat the error */
VbNvSet(vnc, VBNV_TEST_ERROR_FUNC, 0);
VbNvSet(vnc, VBNV_TEST_ERROR_NUM, 0);
@@ -237,11 +221,10 @@ int LoadKernel(LoadKernelParams* params) {
}
if (kBootDev == boot_mode && !dev_switch) {
- /* Dev firmware should be signed such that it never boots with the dev
- * switch is off; so something is terribly wrong. */
+ /* Dev firmware should be signed such that it never boots with the dev
+ * switch is off; so something is terribly wrong. */
VBDEBUG(("LoadKernel() called with dev firmware but dev switch off\n"));
- if (shcall)
- shcall->check_result = VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH;
+ shcall->check_result = VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH;
recovery = VBNV_RECOVERY_RW_DEV_MISMATCH;
goto LoadKernelExit;
}
@@ -253,17 +236,14 @@ int LoadKernel(LoadKernelParams* params) {
/* Let the TPM know if we're in recovery mode */
if (0 != RollbackKernelRecovery(dev_switch)) {
VBDEBUG(("Error setting up TPM for recovery kernel\n"));
- if (shcall)
- shcall->flags |= VBSD_LK_FLAG_REC_TPM_INIT_ERROR;
+ shcall->flags |= VBSD_LK_FLAG_REC_TPM_INIT_ERROR;
/* Ignore return code, since we need to boot recovery mode to
* fix the TPM. */
}
/* Read the key indices from the TPM; ignore any errors */
- if (shared) {
- RollbackFirmwareRead(&shared->fw_version_tpm);
- RollbackKernelRead(&shared->kernel_version_tpm);
- }
+ RollbackFirmwareRead(&shared->fw_version_tpm);
+ RollbackKernelRead(&shared->kernel_version_tpm);
} else {
/* Use the kernel subkey passed from LoadFirmware(). */
kernel_subkey = &shared->kernel_subkey;
@@ -279,8 +259,7 @@ int LoadKernel(LoadKernelParams* params) {
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
goto LoadKernelExit;
}
- if (shared)
- shared->kernel_version_tpm = tpm_version;
+ shared->kernel_version_tpm = tpm_version;
}
do {
@@ -289,16 +268,14 @@ int LoadKernel(LoadKernelParams* params) {
gpt.drive_sectors = params->ending_lba + 1;
if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) {
VBDEBUG(("Unable to read GPT data\n"));
- if (shcall)
- shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
+ shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
break;
}
/* Initialize GPT library */
if (GPT_SUCCESS != GptInit(&gpt)) {
VBDEBUG(("Error parsing GPT\n"));
- if (shcall)
- shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
+ shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
break;
}
@@ -323,19 +300,17 @@ int LoadKernel(LoadKernelParams* params) {
VBDEBUG(("Found kernel entry at %" PRIu64 " size %" PRIu64 "\n",
part_start, part_size));
- if (shcall) {
- /* Set up tracking for this partition. This wraps around if called
- * many times, so initialize the partition entry each time. */
- shpart = shcall->parts + (shcall->kernel_parts_found
- & (VBSD_MAX_KERNEL_PARTS - 1));
- Memset(shpart, 0, sizeof(VbSharedDataKernelPart));
- shpart->sector_start = part_start;
- shpart->sector_count = part_size;
- /* TODO: GPT partitions start at 1, but cgptlib starts them at 0.
- * Adjust here, until cgptlib is fixed. */
- shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1);
- shcall->kernel_parts_found++;
- }
+ /* Set up tracking for this partition. This wraps around if called
+ * many times, so initialize the partition entry each time. */
+ shpart = shcall->parts + (shcall->kernel_parts_found
+ & (VBSD_MAX_KERNEL_PARTS - 1));
+ Memset(shpart, 0, sizeof(VbSharedDataKernelPart));
+ shpart->sector_start = part_start;
+ shpart->sector_count = part_size;
+ /* TODO: GPT partitions start at 1, but cgptlib starts them at 0.
+ * Adjust here, until cgptlib is fixed. */
+ shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1);
+ shcall->kernel_parts_found++;
/* Found at least one kernel partition. */
found_partitions++;
@@ -343,16 +318,14 @@ int LoadKernel(LoadKernelParams* params) {
/* Read the first part of the kernel partition. */
if (part_size < kbuf_sectors) {
VBDEBUG(("Partition too small to hold kernel.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL;
+ shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL;
goto bad_kernel;
}
if (0 != VbExDiskRead(params->disk_handle, part_start, kbuf_sectors,
kbuf)) {
VBDEBUG(("Unable to read start of partition.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_READ_START;
+ shpart->check_result = VBSD_LKP_CHECK_READ_START;
goto bad_kernel;
}
@@ -360,8 +333,7 @@ int LoadKernel(LoadKernelParams* params) {
key_block = (VbKeyBlockHeader*)kbuf;
if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 0)) {
VBDEBUG(("Verifying key block signature failed.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;
+ shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;
key_block_valid = 0;
@@ -373,8 +345,7 @@ int LoadKernel(LoadKernelParams* params) {
* block is valid. */
if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 1)) {
VBDEBUG(("Verifying key block hash failed.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH;
+ shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH;
goto bad_kernel;
}
}
@@ -384,16 +355,14 @@ int LoadKernel(LoadKernelParams* params) {
(dev_switch ? KEY_BLOCK_FLAG_DEVELOPER_1 :
KEY_BLOCK_FLAG_DEVELOPER_0))) {
VBDEBUG(("Key block developer flag mismatch.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH;
+ shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH;
key_block_valid = 0;
}
if (!(key_block->key_block_flags &
(rec_switch ? KEY_BLOCK_FLAG_RECOVERY_1 :
KEY_BLOCK_FLAG_RECOVERY_0))) {
VBDEBUG(("Key block recovery flag mismatch.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH;
+ shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH;
key_block_valid = 0;
}
@@ -402,8 +371,7 @@ int LoadKernel(LoadKernelParams* params) {
if (kBootRecovery != boot_mode) {
if (key_version < (tpm_version >> 16)) {
VBDEBUG(("Key version too old.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK;
+ shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK;
key_block_valid = 0;
}
}
@@ -418,8 +386,7 @@ int LoadKernel(LoadKernelParams* params) {
data_key = PublicKeyToRSA(&key_block->data_key);
if (!data_key) {
VBDEBUG(("Data key bad.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
+ shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
goto bad_kernel;
}
@@ -429,8 +396,7 @@ int LoadKernel(LoadKernelParams* params) {
KBUF_SIZE - key_block->key_block_size,
data_key))) {
VBDEBUG(("Preamble verification failed.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
+ shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
goto bad_kernel;
}
@@ -438,13 +404,11 @@ int LoadKernel(LoadKernelParams* params) {
* rollback of the kernel version. */
combined_version = ((key_version << 16) |
(preamble->kernel_version & 0xFFFF));
- if (shpart)
- shpart->combined_version = (uint32_t)combined_version;
+ shpart->combined_version = (uint32_t)combined_version;
if (key_block_valid && kBootRecovery != boot_mode) {
if (combined_version < tpm_version) {
VBDEBUG(("Kernel version too low.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK;
+ shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK;
/* If we're not in developer mode, kernel version must be valid. */
if (kBootDev != boot_mode)
goto bad_kernel;
@@ -452,8 +416,7 @@ int LoadKernel(LoadKernelParams* params) {
}
VBDEBUG(("Kernel preamble is good.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID;
+ shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID;
/* Check for lowest version from a valid header. */
if (key_block_valid && lowest_version > combined_version)
@@ -473,8 +436,7 @@ int LoadKernel(LoadKernelParams* params) {
if ((preamble->body_load_address != (size_t)params->kernel_buffer) &&
!(params->boot_flags & BOOT_FLAG_SKIP_ADDR_CHECK)) {
VBDEBUG(("Wrong body load address.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_BODY_ADDRESS;
+ shpart->check_result = VBSD_LKP_CHECK_BODY_ADDRESS;
goto bad_kernel;
}
@@ -482,8 +444,7 @@ int LoadKernel(LoadKernelParams* params) {
body_offset = key_block->key_block_size + preamble->preamble_size;
if (0 != body_offset % blba) {
VBDEBUG(("Kernel body not at multiple of sector size.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET;
+ shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET;
goto bad_kernel;
}
body_offset_sectors = body_offset / blba;
@@ -492,16 +453,14 @@ int LoadKernel(LoadKernelParams* params) {
body_sectors = (preamble->body_signature.data_size + blba - 1) / blba;
if (body_sectors * blba > params->kernel_buffer_size) {
VBDEBUG(("Kernel body doesn't fit in memory.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM;
+ shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM;
goto bad_kernel;
}
/* Verify kernel body fits in the partition */
if (body_offset_sectors + body_sectors > part_size) {
VBDEBUG(("Kernel body doesn't fit in partition.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_PART;
+ shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_PART;
goto bad_kernel;
}
@@ -512,8 +471,7 @@ int LoadKernel(LoadKernelParams* params) {
body_sectors, params->kernel_buffer)) {
VBDEBUG(("Unable to read kernel data.\n"));
VBPERFEND("VB_RKD");
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_READ_DATA;
+ shpart->check_result = VBSD_LKP_CHECK_READ_DATA;
goto bad_kernel;
}
VBPERFEND("VB_RKD");
@@ -523,8 +481,7 @@ int LoadKernel(LoadKernelParams* params) {
params->kernel_buffer_size,
&preamble->body_signature, data_key)) {
VBDEBUG(("Kernel data verification failed.\n"));
- if (shpart)
- shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA;
+ shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA;
goto bad_kernel;
}
@@ -535,11 +492,9 @@ int LoadKernel(LoadKernelParams* params) {
/* If we're still here, the kernel is valid. */
/* Save the first good partition we find; that's the one we'll boot */
VBDEBUG(("Partition is good.\n"));
- if (shpart) {
- shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD;
- if (key_block_valid)
- shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID;
- }
+ shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD;
+ if (key_block_valid)
+ shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID;
good_partition_key_block_valid = key_block_valid;
/* TODO: GPT partitions start at 1, but cgptlib starts them at 0.
@@ -597,8 +552,7 @@ int LoadKernel(LoadKernelParams* params) {
/* Handle finding a good partition */
if (good_partition >= 0) {
VBDEBUG(("Good_partition >= 0\n"));
- if (shcall)
- shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION;
+ shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION;
/* See if we need to update the TPM */
if ((kBootNormal == boot_mode) &&
@@ -619,8 +573,7 @@ int LoadKernel(LoadKernelParams* params) {
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
goto LoadKernelExit;
}
- if (shared)
- shared->kernel_version_tpm = (uint32_t)lowest_version;
+ shared->kernel_version_tpm = (uint32_t)lowest_version;
}
}
@@ -641,10 +594,9 @@ int LoadKernel(LoadKernelParams* params) {
/* Success! */
retval = LOAD_KERNEL_SUCCESS;
} else {
- if (shcall)
- shcall->check_result = (found_partitions > 0
- ? VBSD_LKC_CHECK_INVALID_PARTITIONS
- : VBSD_LKC_CHECK_NO_PARTITIONS);
+ shcall->check_result = (found_partitions > 0
+ ? VBSD_LKC_CHECK_INVALID_PARTITIONS
+ : VBSD_LKC_CHECK_NO_PARTITIONS);
/* TODO: differentiate between finding an invalid kernel
* (found_partitions>0) and not finding one at all. Right now we
@@ -659,20 +611,14 @@ LoadKernelExit:
recovery : VBNV_RECOVERY_NOT_REQUESTED);
VbNvTeardown(vnc);
- if (shared) {
- if (shcall)
- shcall->return_code = (uint8_t)retval;
+ shcall->return_code = (uint8_t)retval;
- /* Save whether the good partition's key block was fully verified */
- if (good_partition_key_block_valid)
- shared->flags |= VBSD_KERNEL_KEY_VERIFIED;
+ /* Save whether the good partition's key block was fully verified */
+ if (good_partition_key_block_valid)
+ shared->flags |= VBSD_KERNEL_KEY_VERIFIED;
- /* Save timer values */
- shared->timer_load_kernel_enter = timer_enter;
- shared->timer_load_kernel_exit = VbExGetTimer();
- /* Store how much shared data we used, if any */
- params->shared_data_size = shared->data_used;
- }
+ /* Store how much shared data we used, if any */
+ params->shared_data_size = shared->data_used;
return retval;
}
diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c
index 49500b71..4aae27d9 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+/* 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.
*/
@@ -65,7 +65,6 @@ int main(void)
TlclGetPermissions(0, 0);
/* vboot_api.h - entry points INTO vboot_reference */
- VbS3Resume();
VbInit(0, 0);
VbSelectFirmware(0, 0);
VbUpdateFirmwareBodyHash(0, 0, 0);
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 72f2c666..88afde25 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -277,12 +277,12 @@ char* GetVdatString(char* dest, int size, VdatStringField field)
"LFS=%" PRIu64 ",%" PRIu64
" LF=%" PRIu64 ",%" PRIu64
" LK=%" PRIu64 ",%" PRIu64,
- sh->timer_load_firmware_start_enter,
- sh->timer_load_firmware_start_exit,
- sh->timer_load_firmware_enter,
- sh->timer_load_firmware_exit,
- sh->timer_load_kernel_enter,
- sh->timer_load_kernel_exit);
+ sh->timer_vb_init_enter,
+ sh->timer_vb_init_exit,
+ sh->timer_vb_select_firmware_enter,
+ sh->timer_vb_select_firmware_exit,
+ sh->timer_vb_select_and_load_kernel_enter,
+ sh->timer_vb_select_and_load_kernel_exit);
break;
case VDAT_STRING_LOAD_FIRMWARE_DEBUG: