434 lines
12 KiB
C
434 lines
12 KiB
C
/*++
|
|
|
|
Copyright (c) 1999 Intel Corporation
|
|
|
|
Module Name:
|
|
|
|
EfiDump.c
|
|
|
|
Abstract:
|
|
|
|
Dump out info about EFI structs
|
|
|
|
|
|
|
|
Revision History
|
|
|
|
--*/
|
|
|
|
#include "shelle.h"
|
|
#include "fat.h"
|
|
|
|
typedef union {
|
|
FAT_BOOT_SECTOR Fat;
|
|
FAT_BOOT_SECTOR_EX Fat32;
|
|
} EFI_FAT_BOOT_SECTOR;
|
|
|
|
FAT_VOLUME_TYPE
|
|
ValidBPB (
|
|
IN EFI_FAT_BOOT_SECTOR *Bpb,
|
|
IN UINTN BlockSize
|
|
);
|
|
|
|
VOID
|
|
DumpBpb (
|
|
IN FAT_VOLUME_TYPE FatType,
|
|
IN EFI_FAT_BOOT_SECTOR *Bpb,
|
|
IN UINTN BlockSize
|
|
);
|
|
|
|
typedef union {
|
|
VOID *RawData;
|
|
UINT8 *PtrMath;
|
|
EFI_TABLE_HEADER *Hdr;
|
|
EFI_PARTITION_HEADER *Partition;
|
|
EFI_SYSTEM_TABLE *Sys;
|
|
EFI_RUNTIME_SERVICES *RT;
|
|
EFI_BOOT_SERVICES *BS;
|
|
} EFI_TABLE_HEADER_PTR;
|
|
|
|
VOID
|
|
EFIFileAttributePrint (
|
|
IN UINT64 Attrib
|
|
);
|
|
|
|
CHAR16 *
|
|
EFIClassString (
|
|
IN UINT32 Class
|
|
);
|
|
|
|
BOOLEAN
|
|
IsValidEfiHeader (
|
|
IN UINTN BlockSize,
|
|
IN EFI_TABLE_HEADER_PTR Hdr
|
|
);
|
|
|
|
VOID
|
|
EFITableHeaderPrint (
|
|
IN VOID *Buffer,
|
|
IN UINTN ByteSize,
|
|
IN UINT64 BlockAddress,
|
|
IN BOOLEAN IsBlkDevice
|
|
);
|
|
|
|
VOID
|
|
DumpGenericHeader (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
);
|
|
|
|
VOID
|
|
DumpPartition (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
);
|
|
|
|
VOID
|
|
DumpFileHeader (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
);
|
|
|
|
VOID
|
|
DumpSystemTable (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
);
|
|
|
|
UINT8 FatNumber[] = { 12, 16, 32, 0 };
|
|
|
|
VOID
|
|
EFIStructsPrint (
|
|
IN VOID *Buffer,
|
|
IN UINTN BlockSize,
|
|
IN UINT64 BlockAddress,
|
|
IN EFI_BLOCK_IO *BlkIo
|
|
)
|
|
{
|
|
MASTER_BOOT_RECORD *Mbr;
|
|
INTN i;
|
|
BOOLEAN IsBlkDevice;
|
|
FAT_VOLUME_TYPE FatType;
|
|
|
|
Print (L"\n");
|
|
Mbr = NULL;
|
|
if (BlockAddress == 0 && BlkIo != NULL) {
|
|
Mbr = (MASTER_BOOT_RECORD *)Buffer;
|
|
if (ValidMBR (Mbr, BlkIo)) {
|
|
Print (L" Valid MBR\n ---------\n");
|
|
for (i=0; i<MAX_MBR_PARTITIONS; i++) {
|
|
Print (L" Partition %d OS %02x Start 0x%08x Size 0x%08x\n",
|
|
i,
|
|
Mbr->Partition[i].OSIndicator,
|
|
EXTRACT_UINT32(Mbr->Partition[i].StartingLBA),
|
|
EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA)
|
|
);
|
|
}
|
|
} else if ((FatType = ValidBPB ((EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize)) != FatUndefined) {
|
|
DumpBpb (FatType, (EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize);
|
|
}
|
|
}
|
|
|
|
if (!Mbr) {
|
|
IsBlkDevice = (BlkIo != NULL);
|
|
EFITableHeaderPrint (Buffer, BlockSize, BlockAddress, IsBlkDevice);
|
|
}
|
|
}
|
|
|
|
|
|
typedef
|
|
VOID
|
|
(*EFI_DUMP_HEADER) (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
);
|
|
|
|
typedef struct {
|
|
UINT64 Signature;
|
|
CHAR16 *String;
|
|
EFI_DUMP_HEADER Func;
|
|
} TABLE_HEADER_INFO;
|
|
|
|
TABLE_HEADER_INFO TableHeader[] = {
|
|
EFI_PARTITION_SIGNATURE, L"Partition", DumpPartition,
|
|
EFI_SYSTEM_TABLE_SIGNATURE, L"System", DumpSystemTable,
|
|
EFI_BOOT_SERVICES_SIGNATURE, L"Boot Services", DumpGenericHeader,
|
|
EFI_RUNTIME_SERVICES_SIGNATURE, L"Runtime Services", DumpGenericHeader,
|
|
0x00, L"", DumpGenericHeader
|
|
};
|
|
|
|
VOID
|
|
EFITableHeaderPrint (
|
|
IN VOID *Buffer,
|
|
IN UINTN ByteSize,
|
|
IN UINT64 BlockAddress,
|
|
IN BOOLEAN IsBlkDevice
|
|
)
|
|
{
|
|
EFI_TABLE_HEADER_PTR Hdr;
|
|
INTN i;
|
|
|
|
Hdr.RawData = Buffer;
|
|
if (IsValidEfiHeader (ByteSize, Hdr)) {
|
|
for (i=0; TableHeader[i].Signature != 0x00; i++) {
|
|
if (TableHeader[i].Signature == Hdr.Hdr->Signature) {
|
|
Print (L" Valid EFI Header at %a %016lx\n ----------------------------------------%a\n",
|
|
(IsBlkDevice ? "LBA":"Address"),
|
|
BlockAddress,
|
|
(IsBlkDevice ? "":"----")
|
|
);
|
|
Print (L" %H%s: Table Structure%N size %08x revision %08x\n", TableHeader[i].String, Hdr.Hdr->HeaderSize, Hdr.Hdr->Revision);
|
|
TableHeader[i].Func (Hdr);
|
|
return;
|
|
}
|
|
}
|
|
/*
|
|
* Dump the Generic Header, since we don't know the type
|
|
*/
|
|
TableHeader[i].Func (Hdr);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
IsValidEfiHeader (
|
|
IN UINTN BlockSize,
|
|
IN EFI_TABLE_HEADER_PTR Hdr
|
|
)
|
|
{
|
|
|
|
if (Hdr.Hdr->HeaderSize == 0x00) {
|
|
return FALSE;
|
|
}
|
|
if (Hdr.Hdr->HeaderSize > BlockSize) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
DumpGenericHeader (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
)
|
|
{
|
|
Print (L" Header 0x%016lx Revision 0x%08x Size 0x%08x CRC 0x%08x\n",
|
|
Tbl.Hdr->Signature,
|
|
Tbl.Hdr->Revision,
|
|
Tbl.Hdr->HeaderSize,
|
|
Tbl.Hdr->CRC32
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpPartition (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
)
|
|
{
|
|
Print (L" LBA's 0x%016lx - 0x%016lx Unusable (0x%016lx)\n",
|
|
Tbl.Partition->FirstUsableLba,
|
|
Tbl.Partition->LastUsableLba,
|
|
Tbl.Partition->UnusableSpace
|
|
);
|
|
Print (L" Free Space LBA 0x%016lx Root LBA 0x%016lx\n",
|
|
Tbl.Partition->FreeSpace,
|
|
Tbl.Partition->RootFile
|
|
);
|
|
Print (L" Block Size 0x%08x Dir Allocation Units 0x%08x\n",
|
|
Tbl.Partition->BlockSize,
|
|
Tbl.Partition->DirectoryAllocationNumber
|
|
);
|
|
}
|
|
|
|
|
|
CHAR16 *
|
|
EFIClassString (
|
|
IN UINT32 Class
|
|
)
|
|
{
|
|
switch (Class) {
|
|
case EFI_FILE_CLASS_FREE_SPACE:
|
|
return L"Free Space";
|
|
case EFI_FILE_CLASS_EMPTY:
|
|
return L"Empty";
|
|
case EFI_FILE_CLASS_NORMAL:
|
|
return L"Nornal";
|
|
default:
|
|
return L"Invalid";
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpSystemTable (
|
|
IN EFI_TABLE_HEADER_PTR Tbl
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_DEVICE_PATH *DevicePath;
|
|
VOID *AcpiTable = NULL;
|
|
VOID *SMBIOSTable = NULL;
|
|
VOID *SalSystemTable = NULL;
|
|
VOID *MpsTable = NULL;
|
|
|
|
Print (L" ConIn (0x%08x) ConOut (0x%08x) StdErr (0x%08x)\n",
|
|
Tbl.Sys->ConsoleInHandle,
|
|
Tbl.Sys->ConsoleOutHandle,
|
|
Tbl.Sys->StandardErrorHandle
|
|
);
|
|
|
|
Status = BS->HandleProtocol (Tbl.Sys->ConsoleInHandle, &DevicePathProtocol, (VOID*)&DevicePath);
|
|
if (Status == EFI_SUCCESS && DevicePath) {
|
|
Print (L" Console In on %s\n", DevicePathToStr (DevicePath));
|
|
}
|
|
Status = BS->HandleProtocol (Tbl.Sys->ConsoleOutHandle, &DevicePathProtocol, (VOID*)&DevicePath);
|
|
if (Status == EFI_SUCCESS && DevicePath) {
|
|
Print (L" Console Out on %s\n", DevicePathToStr (DevicePath));
|
|
}
|
|
|
|
Status = BS->HandleProtocol (Tbl.Sys->StandardErrorHandle, &DevicePathProtocol, (VOID*)&DevicePath);
|
|
if (Status == EFI_SUCCESS && DevicePath) {
|
|
Print (L" Std Error on %s\n", DevicePathToStr (DevicePath));
|
|
}
|
|
|
|
Print (L" Runtime Services 0x%016lx\n", (UINT64)Tbl.Sys->RuntimeServices);
|
|
Print (L" Boot Services 0x%016lx\n", (UINT64)Tbl.Sys->BootServices);
|
|
|
|
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
|
|
if (!EFI_ERROR(Status)) {
|
|
Print (L" SAL System Table 0x%016lx\n", (UINT64)SalSystemTable);
|
|
}
|
|
|
|
Status = LibGetSystemConfigurationTable(&AcpiTableGuid, &AcpiTable);
|
|
if (!EFI_ERROR(Status)) {
|
|
Print (L" ACPI Table 0x%016lx\n", (UINT64)AcpiTable);
|
|
}
|
|
|
|
Status = LibGetSystemConfigurationTable(&MpsTableGuid, &MpsTable);
|
|
if (!EFI_ERROR(Status)) {
|
|
Print (L" MPS Table 0x%016lx\n", (UINT64)MpsTable);
|
|
}
|
|
|
|
Status = LibGetSystemConfigurationTable(&SMBIOSTableGuid, &SMBIOSTable);
|
|
if (!EFI_ERROR(Status)) {
|
|
Print (L" SMBIOS Table 0x%016lx\n", (UINT64)SMBIOSTable);
|
|
}
|
|
}
|
|
|
|
FAT_VOLUME_TYPE
|
|
ValidBPB (
|
|
IN EFI_FAT_BOOT_SECTOR *Bpb,
|
|
IN UINTN BlockSize
|
|
)
|
|
{
|
|
UINT32 BlockSize32;
|
|
BOOLEAN IsFat;
|
|
UINT32 RootSize;
|
|
UINT32 RootLba;
|
|
UINT32 FirstClusterLba;
|
|
UINT32 MaxCluster;
|
|
UINT32 Sectors;
|
|
FAT_VOLUME_TYPE FatType;
|
|
|
|
BlockSize32 = (UINT32)BlockSize;
|
|
|
|
if (Bpb->Fat.SectorsPerFat == 0) {
|
|
FatType = FAT32;
|
|
} else {
|
|
FatType = FatUndefined;
|
|
}
|
|
|
|
IsFat = TRUE;
|
|
if (Bpb->Fat.Ia32Jump[0] != 0xe9 &&
|
|
Bpb->Fat.Ia32Jump[0] != 0xeb &&
|
|
Bpb->Fat.Ia32Jump[0] != 0x49) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
|
|
|
|
if (Bpb->Fat.SectorSize != BlockSize32 ||
|
|
Bpb->Fat.ReservedSectors == 0 ||
|
|
Bpb->Fat.NoFats == 0 ||
|
|
Sectors == 0 ) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
if (Bpb->Fat.SectorsPerCluster != 1 &&
|
|
Bpb->Fat.SectorsPerCluster != 2 &&
|
|
Bpb->Fat.SectorsPerCluster != 4 &&
|
|
Bpb->Fat.SectorsPerCluster != 8 &&
|
|
Bpb->Fat.SectorsPerCluster != 16 &&
|
|
Bpb->Fat.SectorsPerCluster != 32 &&
|
|
Bpb->Fat.SectorsPerCluster != 64 &&
|
|
Bpb->Fat.SectorsPerCluster != 128) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
if (FatType == FAT32 && (Bpb->Fat32.LargeSectorsPerFat == 0 || Bpb->Fat32.FsVersion != 0)) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
if (Bpb->Fat.Media != 0xf0 &&
|
|
Bpb->Fat.Media != 0xf8 &&
|
|
Bpb->Fat.Media != 0xf9 &&
|
|
Bpb->Fat.Media != 0xfb &&
|
|
Bpb->Fat.Media != 0xfc &&
|
|
Bpb->Fat.Media != 0xfd &&
|
|
Bpb->Fat.Media != 0xfe &&
|
|
Bpb->Fat.Media != 0xff &&
|
|
/* FujitsuFMR */
|
|
Bpb->Fat.Media != 0x00 &&
|
|
Bpb->Fat.Media != 0x01 &&
|
|
Bpb->Fat.Media != 0xfa) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
if (FatType != FAT32 && Bpb->Fat.RootEntries == 0) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
/* If this is fat32, refuse to mount mirror-disabled volumes */
|
|
if (FatType == FAT32 && (Bpb->Fat32.ExtendedFlags & 0x80)) {
|
|
IsFat = FALSE;
|
|
}
|
|
|
|
if (FatType != FAT32) {
|
|
RootSize = Bpb->Fat.RootEntries * sizeof(FAT_DIRECTORY_ENTRY);
|
|
RootLba = Bpb->Fat.NoFats * Bpb->Fat.SectorsPerFat + Bpb->Fat.ReservedSectors;
|
|
FirstClusterLba = RootLba + (RootSize / Bpb->Fat.SectorSize);
|
|
MaxCluster = (Bpb->Fat.Sectors - FirstClusterLba) / Bpb->Fat.SectorsPerCluster;
|
|
FatType = (MaxCluster + 1) < 4087 ? FAT12 : FAT16;
|
|
}
|
|
return (IsFat ? FatType : FatUndefined);
|
|
}
|
|
|
|
VOID
|
|
DumpBpb (
|
|
IN FAT_VOLUME_TYPE FatType,
|
|
IN EFI_FAT_BOOT_SECTOR *Bpb,
|
|
IN UINTN BlockSize
|
|
)
|
|
{
|
|
UINT32 Sectors;
|
|
|
|
Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
|
|
|
|
Print (L"%HFat %d%N BPB ", FatNumber[FatType]);
|
|
if (FatType == FAT32) {
|
|
Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
|
|
sizeof(Bpb->Fat32.FatLabel), Bpb->Fat32.FatLabel,
|
|
sizeof(Bpb->Fat32.SystemId), Bpb->Fat32.SystemId,
|
|
sizeof(Bpb->Fat32.OemId), Bpb->Fat32.OemId
|
|
);
|
|
} else {
|
|
Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
|
|
sizeof(Bpb->Fat.FatLabel), Bpb->Fat.FatLabel,
|
|
sizeof(Bpb->Fat.SystemId), Bpb->Fat.SystemId,
|
|
sizeof(Bpb->Fat.OemId), Bpb->Fat.OemId
|
|
);
|
|
}
|
|
|
|
Print (L" SectorSize 0x%x SectorsPerCluster %d", Bpb->Fat.SectorSize, Bpb->Fat.SectorsPerCluster);
|
|
Print (L" ReservedSectors %d # Fats %d\n Root Entries 0x%x Media 0x%x", Bpb->Fat.ReservedSectors, Bpb->Fat.NoFats, Bpb->Fat.RootEntries, Bpb->Fat.Media);
|
|
if (FatType == FAT32) {
|
|
Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat32.LargeSectorsPerFat);
|
|
} else {
|
|
Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat.SectorsPerFat);
|
|
}
|
|
Print (L" SectorsPerTrack 0x%x Heads %d\n", Bpb->Fat.SectorsPerTrack, Bpb->Fat.Heads);
|
|
|
|
}
|