Index: host/lib/crossystem.c |
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c |
index e841bad6f302c2c153ce7484c6c98050ed36288a..5c5dec0d9541cb4304f6da6b0f5b123a960d7a7d 100644 |
--- a/host/lib/crossystem.c |
+++ b/host/lib/crossystem.c |
@@ -94,8 +94,9 @@ typedef struct { |
/* Fields that GetVdatString() can get */ |
typedef enum VdatStringField { |
- VDAT_STRING_TIMERS = 0, /* Timer values */ |
- VDAT_STRING_LOAD_FIRMWARE_DEBUG /* LoadFirmware() debug information */ |
+ VDAT_STRING_TIMERS = 0, /* Timer values */ |
+ VDAT_STRING_LOAD_FIRMWARE_DEBUG, /* LoadFirmware() debug information */ |
+ VDAT_STRING_LOAD_KERNEL_DEBUG /* LoadKernel() debug information */ |
} 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) |
{ |
VbSharedDataHeader* sh; |
AcpiBuffer* ab = VbGetBuffer(ACPI_VDAT_PATH); |
+ char* value = dest; |
if (!ab) |
return NULL; |
@@ -642,13 +756,11 @@ char* GetVdatString(char* dest, int size, VdatStringField field) |
break; |
case VDAT_STRING_LOAD_FIRMWARE_DEBUG: |
- snprintf(dest, size, |
- "check=%d,%d index=0x%02x tpmver=0x%x lowestver=0x%x", |
- sh->check_fw_a_result, |
- sh->check_fw_b_result, |
- sh->firmware_index, |
- sh->fw_version_tpm_start, |
- sh->fw_version_lowest); |
+ value = GetVdatLoadFirmwareDebug(dest, size, sh); |
+ break; |
+ |
+ case VDAT_STRING_LOAD_KERNEL_DEBUG: |
+ value = GetVdatLoadKernelDebug(dest, size, sh); |
break; |
default: |
@@ -657,7 +769,7 @@ char* GetVdatString(char* dest, int size, VdatStringField field) |
} |
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); |
} else if (!strcasecmp(name, "vdat_lfdebug")) { |
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 |
return NULL; |
} |