diff options
author | Randall Spangler <rspangler@chromium.org> | 2011-06-24 16:11:45 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2011-06-27 09:24:28 -0700 |
commit | 7adcc60e6f5f6db081b9ad6e02288335502a0d77 (patch) | |
tree | ef170014731bf8ffc95db5fb3cc2283e517c6733 | |
parent | c76136cd0de548a2b8a2fc9c8efd2466d0922319 (diff) | |
download | vboot-7adcc60e6f5f6db081b9ad6e02288335502a0d77.tar.gz |
Vboot wrapper API - crossystem and header files
Header file changes for wrapper API implementation
Crossystem support for reading recovery reason from VbSharedData, and
explicit support for version 1 VbSharedData structs.
BUG=chromium-os:16970
TEST=make && make runtests; run crossystem on Alex and make sure it still reports recovery_reason in recovery mode.
Change-Id: I15195b899583e425d3c9e8df09842d764528e2cb
Reviewed-on: http://gerrit.chromium.org/gerrit/3203
Reviewed-by: Tom Wai-Hong Tam <waihong@chromium.org>
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | firmware/include/bmpblk_header.h | 5 | ||||
-rw-r--r-- | firmware/include/load_kernel_fw.h | 4 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 2 | ||||
-rw-r--r-- | firmware/include/vboot_struct.h | 24 | ||||
-rw-r--r-- | host/arch/x86/lib/crossystem_arch.c | 30 | ||||
-rw-r--r-- | host/include/crossystem_arch.h | 4 | ||||
-rw-r--r-- | host/include/host_common.h | 5 | ||||
-rw-r--r-- | host/lib/crossystem.c | 10 |
8 files changed, 72 insertions, 12 deletions
diff --git a/firmware/include/bmpblk_header.h b/firmware/include/bmpblk_header.h index ea918cab..9007fe2b 100644 --- a/firmware/include/bmpblk_header.h +++ b/firmware/include/bmpblk_header.h @@ -98,7 +98,10 @@ typedef struct ImageInfo { uint32_t format; /* File format of the image */ uint32_t compression; /* Compression method for the image file */ uint32_t original_size; /* Size of the original uncompressed image */ - uint32_t compressed_size; /* Size of the compressed image */ + uint32_t compressed_size; /* Size of the compressed image; if image is not + * compressed, this will be the same as the + * original size. */ + uint32_t reserved; /* NOTE: actual image content follows immediately */ } __attribute__((packed)) ImageInfo; diff --git a/firmware/include/load_kernel_fw.h b/firmware/include/load_kernel_fw.h index 5815abfc..6dd6c93d 100644 --- a/firmware/include/load_kernel_fw.h +++ b/firmware/include/load_kernel_fw.h @@ -10,6 +10,7 @@ #define VBOOT_REFERENCE_LOAD_KERNEL_FW_H_ #include "sysincludes.h" +#include "vboot_api.h" #include "vboot_nvstorage.h" /* Interface provided by verified boot library to BDS */ @@ -43,9 +44,12 @@ typedef struct LoadKernelParams { * data size placed into the buffer. */ void* gbb_data; /* Pointer to GBB data */ uint64_t gbb_size; /* Size of GBB data in bytes */ + + VbExDiskHandle_t disk_handle; /* Disk handle for current device */ uint64_t bytes_per_lba; /* Bytes per lba sector on current device */ uint64_t ending_lba; /* Last addressable lba sector on current * device */ + void* kernel_buffer; /* Destination buffer for kernel * (normally at 0x100000) */ uint64_t kernel_buffer_size; /* Size of kernel buffer in bytes */ diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index 6018349a..02f81a70 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -103,6 +103,8 @@ typedef enum VbNvParam { #define VBNV_RECOVERY_RW_SHARED_DATA 0x46 /* Test error from LoadKernel() */ #define VBNV_RECOVERY_RW_TEST_LK 0x47 +/* No bootable disk found */ +#define VBNV_RECOVERY_RW_NO_DISK 0x48 /* Unspecified/unknown error in rewritable firmware */ #define VBNV_RECOVERY_RW_UNSPECIFIED 0x7F /* DM-verity error */ diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h index f8fd8c80..2dab7421 100644 --- a/firmware/include/vboot_struct.h +++ b/firmware/include/vboot_struct.h @@ -149,6 +149,13 @@ typedef struct VbKernelPreambleHeader { #define VBSD_KERNEL_KEY_VERIFIED 0x00000002 /* LoadFirmware() was told the developer switch was on */ #define VBSD_LF_DEV_SWITCH_ON 0x00000004 +/* Developer switch was enabled at boot time */ +#define VBSD_BOOT_DEV_SWITCH_ON 0x00000010 +/* Recovery switch was enabled at boot time */ +#define VBSD_BOOT_REC_SWITCH_ON 0x00000020 +/* Firmware write protect was enabled at boot time */ +#define VBSD_BOOT_FIRMWARE_WP_ENABLED 0x00000040 + /* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */ #define VBSD_LF_CHECK_NOT_DONE 0 @@ -306,10 +313,15 @@ typedef struct VbSharedDataHeader { uint64_t kernel_supplemental_offset; uint64_t kernel_supplemental_size; - /* After read-only firmware which uses version 1 is released, any additional + /* Fields added in version 2. Before accessing, make sure that + * struct_version >= 2*/ + uint8_t recovery_reason; /* Recovery reason for current boot */ + uint8_t reserved2[7]; /* Reserved for padding */ + + /* After read-only firmware which uses version 2 is released, any additional * fields must be added below, and the struct version must be increased. * Before reading/writing those fields, make sure that the struct being - * accessed is at least version 2. + * accessed is at least version 3. * * It's always ok for an older firmware to access a newer struct, since all * the fields it knows about are present. Newer firmware needs to use @@ -317,7 +329,13 @@ typedef struct VbSharedDataHeader { } __attribute__((packed)) VbSharedDataHeader; -#define VB_SHARED_DATA_VERSION 1 /* Version for struct_version */ +/* Size of VbSharedDataheader for each older version */ +// TODO: crossystem needs not to +// fail if called on a v1 system where sizeof(VbSharedDataHeader) was smaller + +#define VB_SHARED_DATA_HEADER_SIZE_V1 1072 + +#define VB_SHARED_DATA_VERSION 2 /* Version for struct_version */ __pragma(pack(pop)) /* Support packing for MSVC. */ diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c index 8b320e4b..25867e12 100644 --- a/host/arch/x86/lib/crossystem_arch.c +++ b/host/arch/x86/lib/crossystem_arch.c @@ -156,8 +156,7 @@ int VbWriteNvStorage(VbNvContext* vnc) { * deallocating the pointer, this will take care of both the structure * and the buffer. Null in case of error. */ -static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) -{ +static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) { FILE* f = NULL; char* file_buffer = NULL; uint8_t* output_buffer = NULL; @@ -240,14 +239,24 @@ static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) VbSharedDataHeader* VbSharedDataRead(void) { - VbSharedDataHeader* sh; int got_size = 0; + int expect_size; sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size); if (!sh) return NULL; - if (got_size < sizeof(VbSharedDataHeader)) { + + /* Make sure the size is sufficient for the struct version we got. + * Check supported old versions first. */ + if (1 == sh->struct_version) + expect_size = VB_SHARED_DATA_HEADER_SIZE_V1; + else { + /* There'd better be enough data for the current header size. */ + expect_size = sizeof(VbSharedDataHeader); + } + + if (got_size < expect_size) { Free(sh); return NULL; } @@ -371,7 +380,18 @@ static const char* VbReadMainFwType(char* dest, int size) { /* Read the recovery reason. Returns the reason code or -1 if error. */ static int VbGetRecoveryReason(void) { - int value; + VbSharedDataHeader* sh; + int value = -1; + + /* Try reading from VbSharedData first */ + sh = VbSharedDataRead(); + if (sh) { + if (sh->struct_version >= 2) + value = sh->recovery_reason; + Free(sh); + if (-1 != value) + return value; + } /* Try reading type from BINF.4 */ value = ReadFileInt(ACPI_BINF_PATH ".4"); diff --git a/host/include/crossystem_arch.h b/host/include/crossystem_arch.h index 6d33c65b..fbef9b19 100644 --- a/host/include/crossystem_arch.h +++ b/host/include/crossystem_arch.h @@ -58,8 +58,8 @@ int VbWriteNvStorage(VbNvContext* vnc); * some data was not returned; callers must handle this; this is not considered * an error. * - * Returns the data buffer, which must be freed by the caller, or NULL if - * error. */ + * Returns the data buffer, which must be freed by the caller using + * free(), or NULL if error. */ VbSharedDataHeader* VbSharedDataRead(void); /* Read an architecture-specific system property integer. diff --git a/host/include/host_common.h b/host/include/host_common.h index d8a2b092..007c9d91 100644 --- a/host/include/host_common.h +++ b/host/include/host_common.h @@ -8,12 +8,17 @@ #ifndef VBOOT_REFERENCE_HOST_COMMON_H_ #define VBOOT_REFERENCE_HOST_COMMON_H_ +/* Host is allowed direct use of stdlib funcs such as malloc() and free(), + * since it's using the stub implementation from firmware/lib/stub. */ +#define _STUB_IMPLEMENTATION_ + #include "cryptolib.h" #include "host_key.h" #include "host_keyblock.h" #include "host_misc.h" #include "host_signature.h" #include "utility.h" +#include "vboot_api.h" #include "vboot_struct.h" diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index 7ad5d805..54d08561 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -36,8 +36,9 @@ typedef enum VdatIntField { VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */ VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */ VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */ - VDAT_INT_KERNEL_KEY_VERIFIED /* Kernel key verified using + VDAT_INT_KERNEL_KEY_VERIFIED, /* Kernel key verified using * signature, not just hash */ + VDAT_INT_RECOVERY_REASON /* Recovery reason for current boot */ } VdatIntField; @@ -325,6 +326,11 @@ int GetVdatInt(VdatIntField field) { case VDAT_INT_KERNEL_KEY_VERIFIED: value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0); break; + case VDAT_INT_RECOVERY_REASON: + /* Field added in struct version 2 */ + if (sh->struct_version >= 2) + value = sh->recovery_reason; + break; } Free(sh); @@ -373,6 +379,8 @@ int VbGetSystemPropertyInt(const char* name) { value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM); } else if (!strcasecmp(name,"tried_fwb")) { value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B); + } else if (!strcasecmp(name,"recovery_reason")) { + value = GetVdatInt(VDAT_INT_RECOVERY_REASON); } return value; |