mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-26 11:15:13 +00:00
Print LoadKernel() debug data from VbSharedData
Change-Id: I60cf9c4dd07e83b1ed1a5bac8a3ce8c2a54df45b R=reinauer@chromium.org BUG=chrome-os-partner:2748 TEST=manually check output of 'crossystem vdat_lkdebug' Review URL: http://codereview.chromium.org/6685097
This commit is contained in:
@@ -203,6 +203,7 @@ typedef struct VbSharedDataKernelPart {
|
|||||||
uint8_t gpt_index; /* Index of partition in GPT */
|
uint8_t gpt_index; /* Index of partition in GPT */
|
||||||
uint8_t check_result; /* Check result; see VBSD_LKP_CHECK_* */
|
uint8_t check_result; /* Check result; see VBSD_LKP_CHECK_* */
|
||||||
uint8_t flags; /* Flags (see VBSD_LKP_FLAG_* */
|
uint8_t flags; /* Flags (see VBSD_LKP_FLAG_* */
|
||||||
|
uint8_t reserved0; /* Reserved for padding */
|
||||||
} VbSharedDataKernelPart;
|
} VbSharedDataKernelPart;
|
||||||
|
|
||||||
/* Number of kernel partitions to track per call. Must be power of 2. */
|
/* Number of kernel partitions to track per call. Must be power of 2. */
|
||||||
@@ -234,6 +235,7 @@ typedef struct VbSharedDataKernelCall {
|
|||||||
uint8_t test_error_num; /* Test error number, if non-zero */
|
uint8_t test_error_num; /* Test error number, if non-zero */
|
||||||
uint8_t return_code; /* Return code from LoadKernel() */
|
uint8_t return_code; /* Return code from LoadKernel() */
|
||||||
uint8_t kernel_parts_found; /* Number of kernel partitions found */
|
uint8_t kernel_parts_found; /* Number of kernel partitions found */
|
||||||
|
uint8_t reserved0[7]; /* Reserved for padding */
|
||||||
VbSharedDataKernelPart parts[VBSD_MAX_KERNEL_PARTS]; /* Data on kernels */
|
VbSharedDataKernelPart parts[VBSD_MAX_KERNEL_PARTS]; /* Data on kernels */
|
||||||
} VbSharedDataKernelCall;
|
} VbSharedDataKernelCall;
|
||||||
|
|
||||||
@@ -261,6 +263,7 @@ typedef struct VbSharedDataHeader {
|
|||||||
uint64_t data_size; /* Size of shared data buffer in bytes */
|
uint64_t data_size; /* Size of shared data buffer in bytes */
|
||||||
uint64_t data_used; /* Amount of shared data used so far */
|
uint64_t data_used; /* Amount of shared data used so far */
|
||||||
uint32_t flags; /* Flags */
|
uint32_t flags; /* Flags */
|
||||||
|
uint32_t reserved0; /* Reserved for padding */
|
||||||
|
|
||||||
VbPublicKey kernel_subkey; /* Kernel subkey, from firmware */
|
VbPublicKey kernel_subkey; /* Kernel subkey, from firmware */
|
||||||
uint64_t kernel_subkey_data_offset; /* Offset of kernel subkey data from
|
uint64_t kernel_subkey_data_offset; /* Offset of kernel subkey data from
|
||||||
@@ -286,6 +289,7 @@ typedef struct VbSharedDataHeader {
|
|||||||
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
|
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
|
||||||
uint8_t firmware_index; /* Firmware index returned by
|
uint8_t firmware_index; /* Firmware index returned by
|
||||||
* LoadFirmware() or 0xFF if failure */
|
* LoadFirmware() or 0xFF if failure */
|
||||||
|
uint8_t reserved1; /* Reserved for padding */
|
||||||
uint32_t fw_version_tpm_start; /* Firmware TPM version at start of
|
uint32_t fw_version_tpm_start; /* Firmware TPM version at start of
|
||||||
* LoadFirmware() */
|
* LoadFirmware() */
|
||||||
uint32_t fw_version_lowest; /* Firmware lowest version found */
|
uint32_t fw_version_lowest; /* Firmware lowest version found */
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ typedef struct {
|
|||||||
/* Fields that GetVdatString() can get */
|
/* Fields that GetVdatString() can get */
|
||||||
typedef enum VdatStringField {
|
typedef enum VdatStringField {
|
||||||
VDAT_STRING_TIMERS = 0, /* Timer values */
|
VDAT_STRING_TIMERS = 0, /* Timer values */
|
||||||
VDAT_STRING_LOAD_FIRMWARE_DEBUG /* LoadFirmware() debug information */
|
VDAT_STRING_LOAD_FIRMWARE_DEBUG, /* LoadFirmware() debug information */
|
||||||
|
VDAT_STRING_LOAD_KERNEL_DEBUG /* LoadKernel() debug information */
|
||||||
} VdatStringField;
|
} VdatStringField;
|
||||||
|
|
||||||
|
|
||||||
@@ -618,10 +619,123 @@ int VbGetCrosDebug(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* GetVdatLoadFirmwareDebug(char* dest, int size,
|
||||||
|
const VbSharedDataHeader* sh) {
|
||||||
|
snprintf(dest, size,
|
||||||
|
"Check A result=%d\n"
|
||||||
|
"Check B result=%d\n"
|
||||||
|
"Firmware index booted=0x%02x\n"
|
||||||
|
"TPM combined version at start=0x%08x\n"
|
||||||
|
"Lowest combined version from firmware=0x%08x\n",
|
||||||
|
sh->check_fw_a_result,
|
||||||
|
sh->check_fw_b_result,
|
||||||
|
sh->firmware_index,
|
||||||
|
sh->fw_version_tpm_start,
|
||||||
|
sh->fw_version_lowest);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TRUNCATED "\n(truncated)\n"
|
||||||
|
|
||||||
|
char* GetVdatLoadKernelDebug(char* dest, int size,
|
||||||
|
const VbSharedDataHeader* sh) {
|
||||||
|
int used = 0;
|
||||||
|
int first_call_tracked = 0;
|
||||||
|
int call;
|
||||||
|
|
||||||
|
/* Make sure we have space for truncation warning */
|
||||||
|
if (size < strlen(TRUNCATED) + 1)
|
||||||
|
return NULL;
|
||||||
|
size -= strlen(TRUNCATED) + 1;
|
||||||
|
|
||||||
|
used += snprintf(
|
||||||
|
dest + used, size - used,
|
||||||
|
"Calls to LoadKernel()=%d\n",
|
||||||
|
sh->lk_call_count);
|
||||||
|
if (used > size)
|
||||||
|
goto LoadKernelDebugExit;
|
||||||
|
|
||||||
|
/* Report on the last calls */
|
||||||
|
if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS)
|
||||||
|
first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS;
|
||||||
|
for (call = first_call_tracked; call < sh->lk_call_count; call++) {
|
||||||
|
const VbSharedDataKernelCall* shc =
|
||||||
|
sh->lk_calls + (call & (VBSD_MAX_KERNEL_CALLS - 1));
|
||||||
|
int first_part_tracked = 0;
|
||||||
|
int part;
|
||||||
|
|
||||||
|
used += snprintf(
|
||||||
|
dest + used, size - used,
|
||||||
|
"Call %d:\n"
|
||||||
|
" Boot flags=0x%02x\n"
|
||||||
|
" Boot mode=%d\n"
|
||||||
|
" Test error=%d\n"
|
||||||
|
" Return code=%d\n"
|
||||||
|
" Debug flags=0x%02x\n"
|
||||||
|
" Drive sectors=%" PRIu64 "\n"
|
||||||
|
" Sector size=%d\n"
|
||||||
|
" Check result=%d\n"
|
||||||
|
" Kernel partitions found=%d\n",
|
||||||
|
call + 1,
|
||||||
|
shc->boot_flags,
|
||||||
|
shc->boot_mode,
|
||||||
|
shc->test_error_num,
|
||||||
|
shc->return_code,
|
||||||
|
shc->flags,
|
||||||
|
shc->sector_count,
|
||||||
|
shc->sector_size,
|
||||||
|
shc->check_result,
|
||||||
|
shc->kernel_parts_found);
|
||||||
|
if (used > size)
|
||||||
|
goto LoadKernelDebugExit;
|
||||||
|
|
||||||
|
/* If we found too many partitions, only prints ones where the
|
||||||
|
* structure has info. */
|
||||||
|
if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS)
|
||||||
|
first_part_tracked = shc->kernel_parts_found - VBSD_MAX_KERNEL_PARTS;
|
||||||
|
|
||||||
|
/* Report on the partitions checked */
|
||||||
|
for (part = first_part_tracked; part < shc->kernel_parts_found; part++) {
|
||||||
|
const VbSharedDataKernelPart* shp =
|
||||||
|
shc->parts + (part & (VBSD_MAX_KERNEL_PARTS - 1));
|
||||||
|
|
||||||
|
used += snprintf(
|
||||||
|
dest + used, size - used,
|
||||||
|
" Kernel %d:\n"
|
||||||
|
" GPT index=%d\n"
|
||||||
|
" Start sector=%" PRIu64 "\n"
|
||||||
|
" Sector count=%" PRIu64 "\n"
|
||||||
|
" Combined version=0x%08x\n"
|
||||||
|
" Check result=%d\n"
|
||||||
|
" Debug flags=0x%02x\n",
|
||||||
|
part + 1,
|
||||||
|
shp->gpt_index,
|
||||||
|
shp->sector_start,
|
||||||
|
shp->sector_count,
|
||||||
|
shp->combined_version,
|
||||||
|
shp->check_result,
|
||||||
|
shp->flags);
|
||||||
|
if (used > size)
|
||||||
|
goto LoadKernelDebugExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadKernelDebugExit:
|
||||||
|
|
||||||
|
/* Warn if data was truncated; we left space for this above. */
|
||||||
|
if (used > size)
|
||||||
|
strcat(dest, TRUNCATED);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char* GetVdatString(char* dest, int size, VdatStringField field)
|
char* GetVdatString(char* dest, int size, VdatStringField field)
|
||||||
{
|
{
|
||||||
VbSharedDataHeader* sh;
|
VbSharedDataHeader* sh;
|
||||||
AcpiBuffer* ab = VbGetBuffer(ACPI_VDAT_PATH);
|
AcpiBuffer* ab = VbGetBuffer(ACPI_VDAT_PATH);
|
||||||
|
char* value = dest;
|
||||||
if (!ab)
|
if (!ab)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -642,13 +756,11 @@ char* GetVdatString(char* dest, int size, VdatStringField field)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VDAT_STRING_LOAD_FIRMWARE_DEBUG:
|
case VDAT_STRING_LOAD_FIRMWARE_DEBUG:
|
||||||
snprintf(dest, size,
|
value = GetVdatLoadFirmwareDebug(dest, size, sh);
|
||||||
"check=%d,%d index=0x%02x tpmver=0x%x lowestver=0x%x",
|
break;
|
||||||
sh->check_fw_a_result,
|
|
||||||
sh->check_fw_b_result,
|
case VDAT_STRING_LOAD_KERNEL_DEBUG:
|
||||||
sh->firmware_index,
|
value = GetVdatLoadKernelDebug(dest, size, sh);
|
||||||
sh->fw_version_tpm_start,
|
|
||||||
sh->fw_version_lowest);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -657,7 +769,7 @@ char* GetVdatString(char* dest, int size, VdatStringField field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Free(ab);
|
Free(ab);
|
||||||
return dest;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -819,6 +931,8 @@ const char* VbGetSystemPropertyString(const char* name, char* dest, int size) {
|
|||||||
return GetVdatString(dest, size, VDAT_STRING_TIMERS);
|
return GetVdatString(dest, size, VDAT_STRING_TIMERS);
|
||||||
} else if (!strcasecmp(name, "vdat_lfdebug")) {
|
} else if (!strcasecmp(name, "vdat_lfdebug")) {
|
||||||
return GetVdatString(dest, size, VDAT_STRING_LOAD_FIRMWARE_DEBUG);
|
return GetVdatString(dest, size, VDAT_STRING_LOAD_FIRMWARE_DEBUG);
|
||||||
|
} else if (!strcasecmp(name, "vdat_lkdebug")) {
|
||||||
|
return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG);
|
||||||
} else
|
} else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
#include "crossystem.h"
|
#include "crossystem.h"
|
||||||
|
|
||||||
|
/* Max length of a string parameter */
|
||||||
|
#define MAX_STRING 8192
|
||||||
|
|
||||||
/* Flags for Param */
|
/* Flags for Param */
|
||||||
#define IS_STRING 0x01 /* String (not present = integer) */
|
#define IS_STRING 0x01 /* String (not present = integer) */
|
||||||
#define CAN_WRITE 0x02 /* Writable (not present = read-only */
|
#define CAN_WRITE 0x02 /* Writable (not present = read-only */
|
||||||
@@ -52,7 +55,6 @@ const Param sys_param_list[] = {
|
|||||||
{"ecfw_act", IS_STRING, "Active EC firmware"},
|
{"ecfw_act", IS_STRING, "Active EC firmware"},
|
||||||
{"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
|
{"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
|
||||||
{"vdat_timers", IS_STRING, "Timer values from VbSharedData"},
|
{"vdat_timers", IS_STRING, "Timer values from VbSharedData"},
|
||||||
{"vdat_lfdebug", IS_STRING, "LoadFirmware() debug data VbSharedData"},
|
|
||||||
/* Writable integers */
|
/* Writable integers */
|
||||||
{"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"},
|
{"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"},
|
||||||
{"kern_nv", CAN_WRITE, "Non-volatile field for kernel use", "0x%08x"},
|
{"kern_nv", CAN_WRITE, "Non-volatile field for kernel use", "0x%08x"},
|
||||||
@@ -61,7 +63,11 @@ const Param sys_param_list[] = {
|
|||||||
{"fwb_tries", CAN_WRITE, "Try firmware B count (writable)"},
|
{"fwb_tries", CAN_WRITE, "Try firmware B count (writable)"},
|
||||||
{"vbtest_errfunc", CAN_WRITE, "Verified boot test error function (writable)"},
|
{"vbtest_errfunc", CAN_WRITE, "Verified boot test error function (writable)"},
|
||||||
{"vbtest_errno", CAN_WRITE, "Verified boot test error number (writable)"},
|
{"vbtest_errno", CAN_WRITE, "Verified boot test error number (writable)"},
|
||||||
|
/* Fields not shown in a print-all list */
|
||||||
|
{"vdat_lfdebug", IS_STRING|NO_PRINT_ALL,
|
||||||
|
"LoadFirmware() debug data (not in print-all)"},
|
||||||
|
{"vdat_lkdebug", IS_STRING|NO_PRINT_ALL,
|
||||||
|
"LoadKernel() debug data (not in print-all)"},
|
||||||
/* Terminate with null name */
|
/* Terminate with null name */
|
||||||
{NULL, 0, NULL}
|
{NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
@@ -125,7 +131,7 @@ int SetParam(const Param* p, const char* value) {
|
|||||||
* Returns 0 if success (match), non-zero if error (mismatch). */
|
* Returns 0 if success (match), non-zero if error (mismatch). */
|
||||||
int CheckParam(const Param* p, char* expect) {
|
int CheckParam(const Param* p, char* expect) {
|
||||||
if (p->flags & IS_STRING) {
|
if (p->flags & IS_STRING) {
|
||||||
char buf[256];
|
char buf[MAX_STRING];
|
||||||
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
||||||
if (!v || 0 != strcmp(v, expect))
|
if (!v || 0 != strcmp(v, expect))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -147,7 +153,7 @@ int CheckParam(const Param* p, char* expect) {
|
|||||||
* Returns 0 if success, non-zero if error. */
|
* Returns 0 if success, non-zero if error. */
|
||||||
int PrintParam(const Param* p) {
|
int PrintParam(const Param* p) {
|
||||||
if (p->flags & IS_STRING) {
|
if (p->flags & IS_STRING) {
|
||||||
char buf[256];
|
char buf[MAX_STRING];
|
||||||
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
const char* v = VbGetSystemPropertyString(p->name, buf, sizeof(buf));
|
||||||
if (!v)
|
if (!v)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -168,7 +174,7 @@ int PrintParam(const Param* p) {
|
|||||||
int PrintAllParams(void) {
|
int PrintAllParams(void) {
|
||||||
const Param* p;
|
const Param* p;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
char buf[256];
|
char buf[MAX_STRING];
|
||||||
const char* value;
|
const char* value;
|
||||||
|
|
||||||
for (p = sys_param_list; p->name; p++) {
|
for (p = sys_param_list; p->name; p++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user