dumpbs.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,125 行 · 第 1/2 页
C
1,125 行
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
DumpBs.c
Abstract:
Revision History:
--*/
#include "Tiano.h"
#include "EfiCommonLib.h"
#include "EfiShellLib.h"
#define BOOT_HEADER_SIZE 0x200
#define BOOT_HEADER_MASK 0x1ff
#define BOOT_HEADER_SHIFT 9
#define MBR_START_OFFSET 0x1BE
#define MBR_END_OFFSET 0x1FE
#define MBR_ENTRY_LEN 0x10
#define MBR_OS_TYPE_OFFSET 4
#define MBR_STARTINGLBA_OFFSET 8
#define GPT_PARTITIONENTRY_LBA 72
#define GPT_PARTITIONENTRY_SIZE 84
#define GPT_ENTRT_STARTING_LBA 32
#define FAT32_BPB_START_OFFSET 11
#define FAT32_BPB_END_OFFSET 65
#define FAT_BPB_START_OFFSET 11
#define FAT_BPB_END_OFFSET 37
#define BOOT_SECTOR_LBA_OFFSET 0x1FA
#define GPT_PARTITION_INDEX 0x1B7
EFI_HANDLE mImageHandle;
EFI_STATUS
GetBlkIOFromName (
IN CHAR16 *BlockIdName,
OUT EFI_BLOCK_IO_PROTOCOL **BlkIo
);
EFI_STATUS
GetFileHandleFromName (
IN CHAR16 *FileName,
OUT EFI_FILE **FileHandle
);
VOID
PrintHelp (
VOID
);
EFI_STATUS
PatchBootSectorLbaOffset (
IN UINT64 BootSectorLbaOffset,
IN CHAR16 *FileName
);
EFI_STATUS
PatchGptPartitionIndex (
IN UINT8 GptPartitionIndex,
IN CHAR16 *FileName
);
UINT64
ShowBootSectorLbaOffset (
IN CHAR16 *BlkIoName,
IN UINTN PartitionIndex
);
EFI_STATUS
WriteMbr (
IN CHAR16 *BlkIoName,
IN CHAR16 *FileName
);
EFI_STATUS
WriteBootSector (
IN CHAR16 *BlkIoName,
IN CHAR16 *FileName,
IN UINT64 StartingLba
);
EFI_STATUS
ReadBootSector (
IN CHAR16 *BlkIoName,
IN CHAR16 *FileName,
IN UINT64 StartingLba
);
EFI_STATUS
ReadBootSectorAndPatch (
IN CHAR16 *BlkIoName,
IN CHAR16 *FileName,
IN UINT64 StartingLba
);
EFI_STATUS
AutomaticalPatch (
IN UINTN Argc,
IN CHAR16 **Argv
);
EFI_APPLICATION_ENTRY_POINT(DumpBootSector)
EFI_STATUS
EFIAPI
DumpBootSector (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Dump Data from block IO devices.
Arguments:
ImageHandle The image handle.
SystemTable The system table.
Returns:
EFI_SUCCESS - Command completed successfully
EFI_INVALID_PARAMETER - Command usage error
--*/
{
EFI_STATUS Status;
CHAR16 **Argv;
UINTN Argc;
EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
mImageHandle = ImageHandle;
Argc = SI->Argc;
Argv = SI->Argv;
Status = EFI_SUCCESS;
if ((Argc == 2) &&
(Argv[1][0] == '-' || Argv[1][0] == '/') && (Argv[1][1] == '?')) {
PrintHelp ();
return EFI_SUCCESS;
}
if (Argv[1][0] != '-') {
Print (L"dumpbs: arguments error\n");
return EFI_INVALID_PARAMETER;
}
if (Argv[1][1] != 'a') {
if (Argc != 4) {
Print (L"dumpbs: arguments error\n");
return EFI_INVALID_PARAMETER;
}
} else {
if ((Argc != 6) && (Argc != 7)) {
Print (L"dumpbs: arguments error\n");
return EFI_INVALID_PARAMETER;
}
}
//
// Parse parameters
//
if (Argv[1][1] == 'g') {
WriteMbr (Argv[2], Argv[3]);
} else if (Argv[1][1] == 'w') {
WriteBootSector (Argv[2], Argv[3], 0);
} else if (Argv[1][1] == 'r') {
ReadBootSector (Argv[2], Argv[3], 0);
} else if (Argv[1][1] == 'p') {
ReadBootSectorAndPatch (Argv[2], Argv[3], 0);
} else if (Argv[1][1] == 'v') {
ShowBootSectorLbaOffset (Argv[2], Atoi(Argv[3]));
} else if (Argv[1][1] == 'l') {
PatchBootSectorLbaOffset ((UINT64)Xtoi(Argv[2]), Argv[3]);
} else if (Argv[1][1] == 'i') {
PatchGptPartitionIndex ((UINT8)Atoi(Argv[2]), Argv[3]);
} else if (Argv[1][1] == 'a') {
AutomaticalPatch (Argc, Argv);
} else {
Print (L"dumpbs: arguments error\n");
return EFI_INVALID_PARAMETER;
}
return EFI_SUCCESS;
}
//
// Internal Function
//
VOID
PrintHelp (
VOID
)
{
Print (
L"Read or write the boot sector of the specified block device.\n"
L"\n"
L"dumpbs -r|-p|-w|-g BlockDeviceName SectorFileName\n"
L"dumpbs -l BootSectorLBAOffset SectorFileName\n"
L"dumpbs -i PartitionIndex SectorFileName\n"
L"dumpbs -v BlockDeviceName PartitionIndex\n"
L"dumpbs -a BlockDeviceName PartitionIndex EfildrFileName SectorFileName [GptFileName]\n"
L" -a - Automatically prepare all environment\n"
L" -r - Read the boot sector to file\n"
L" -p - Read the boot sector and patch to file\n"
L" -w - Write FAT boot sector from a file\n"
L" -g - Write GPT from a file\n"
L" -l - Patch BootSectorLBAOffset for sector file\n"
L" -i - Patch GPT Partition for sector file\n"
L" -v - View the BootSectorLBAOffset\n"
L" BlockDeviceName - Block device name\n"
L" SectorFileName - Boot sector file name\n"
L" BootSectorLBAOffset - Heximal-based BootSector LBA Offset\n"
L" PartitionIndex - Decimal-based Partition Index (from 0)\n"
L"For example:\n"
L" dumpbs -a 0 blk3 Efildr20 bs32.com gpt.com\n"
);
}
VOID
PatchBlock (
IN UINT8 *DestBuffer,
IN UINT8 *SourceBuffer,
IN BOOLEAN IsMbr
)
{
if (IsMbr) {
//
// Handle MBR
//
CopyMem (
DestBuffer + MBR_START_OFFSET,
SourceBuffer + MBR_START_OFFSET,
MBR_END_OFFSET - MBR_START_OFFSET
);
} else {
if (*(UINT64 *)(DestBuffer + 82) == (0x2020203233544146l)) {
//
// Handle FAT32 BPB
//
CopyMem (
DestBuffer + FAT32_BPB_START_OFFSET,
SourceBuffer + FAT32_BPB_START_OFFSET,
FAT32_BPB_END_OFFSET - FAT32_BPB_START_OFFSET
);
} else {
//
// Handle FAT BPB
//
CopyMem (
DestBuffer + FAT_BPB_START_OFFSET,
SourceBuffer + FAT_BPB_START_OFFSET,
FAT_BPB_END_OFFSET - FAT_BPB_START_OFFSET
);
}
}
return ;
}
EFI_STATUS
PatchBootSectorLbaOffset (
IN UINT64 BootSectorLbaOffset,
IN CHAR16 *FileName
)
{
EFI_FILE *FileHandle;
VOID *Buffer;
UINTN BufSize;
EFI_STATUS Status;
Print (L"dumpbs: BootSectorLBAOffset - 0x%x\n", BootSectorLbaOffset);
//
// Get the File from sector file name
//
Status = GetFileHandleFromName (FileName, &FileHandle);
if (EFI_ERROR(Status)) {
Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
return Status;
}
//
// Init
//
BufSize = BOOT_HEADER_SIZE;
Buffer = AllocatePool (BOOT_HEADER_SIZE);
ASSERT (Buffer != NULL);
//
// Set file pointer to end start position
//
Status = FileHandle->SetPosition (FileHandle, 0);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
goto Done;
}
//
// Read data from file
//
Status = FileHandle->Read (FileHandle, &BufSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: - Read error - %r\n", Status);
goto Done;
}
*(UINT32 *)((UINT8 *)Buffer + BOOT_SECTOR_LBA_OFFSET) = (UINT32)BootSectorLbaOffset;
//
// Set file pointer to end start position
//
Status = FileHandle->SetPosition (FileHandle, 0);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
goto Done;
}
//
// Write the boot sector to file
//
Status = FileHandle->Write (FileHandle, &BufSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: - Write error - %r\n", Status);
goto Done;
}
Print(L"dumpbs: Patch BootSectorLBAOffset successfully!\n");
Done:
FreePool(Buffer);
FileHandle->Close(FileHandle);
return Status;
}
EFI_STATUS
PatchGptPartitionIndex (
IN UINT8 GptPartitionIndex,
IN CHAR16 *FileName
)
{
EFI_FILE *FileHandle;
VOID *Buffer;
UINTN BufSize;
EFI_STATUS Status;
Print (L"dumpbs: GptPartitionIndex - 0x%x\n", GptPartitionIndex);
//
// Get the File from sector file name
//
Status = GetFileHandleFromName (FileName, &FileHandle);
if (EFI_ERROR(Status)) {
Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
return Status;
}
//
// Init
//
BufSize = BOOT_HEADER_SIZE;
Buffer = AllocatePool (BOOT_HEADER_SIZE);
ASSERT (Buffer != NULL);
//
// Set file pointer to end start position
//
Status = FileHandle->SetPosition (FileHandle, 0);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
goto Done;
}
//
// Read data from file
//
Status = FileHandle->Read (FileHandle, &BufSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: - Read error - %r\n", Status);
goto Done;
}
*((UINT8 *)Buffer + GPT_PARTITION_INDEX) = (UINT8)GptPartitionIndex;
//
// Set file pointer to end start position
//
Status = FileHandle->SetPosition (FileHandle, 0);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
goto Done;
}
//
// Write the boot sector to file
//
Status = FileHandle->Write (FileHandle, &BufSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: - Write error - %r\n", Status);
goto Done;
}
Print(L"dumpbs: Patch GptParitionIndex successfully!\n");
Done:
FreePool(Buffer);
FileHandle->Close(FileHandle);
return Status;
}
UINT64
ShowBootSectorLbaOffset (
IN CHAR16 *BlkIoName,
IN UINTN PartitionIndex
)
{
EFI_BLOCK_IO_PROTOCOL *BlkIo;
VOID *Buffer;
UINTN BufSize;
EFI_STATUS Status;
UINT64 LBAOffset;
UINT64 PartitionEntryLBA;
UINT64 TargetEntryLBA;
UINT32 TargetEntryOffset;
Status = GetBlkIOFromName (BlkIoName, &BlkIo);
if (EFI_ERROR(Status)) {
Print (L"dumpbs: GetBlkIOFromName fail - %s\n", BlkIoName);
return 0;
}
LBAOffset = 0;
//
// Init
//
BufSize = BOOT_HEADER_SIZE;
Buffer = AllocatePool (BOOT_HEADER_SIZE);
ASSERT (Buffer != NULL);
//
// Read the block device's boot sector
//
Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 0, BOOT_HEADER_SIZE, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Read boot sector error - %r\n", Status);
goto Done;
}
if (*((UINT8 *)Buffer + MBR_START_OFFSET + MBR_OS_TYPE_OFFSET) != 0xEE) {
//
// MBR
//
Print(L"dumpbs: MBR Parition\n");
if (PartitionIndex >= 4) {
Print (L"dumpbs: ParitionIndex error - %d\n", PartitionIndex);
} else {
LBAOffset = (UINT64)*(UINT32 *)((UINT8 *)Buffer +
MBR_START_OFFSET +
MBR_ENTRY_LEN * PartitionIndex +
MBR_STARTINGLBA_OFFSET
);
}
} else {
//
// GPT
//
Print(L"dumpbs: GPT Parition\n");
//
// Read the GPT Header
//
Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 1, BOOT_HEADER_SIZE, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Read boot sector error - %r\n", Status);
goto Done;
}
PartitionEntryLBA = *(UINT64 *)((UINT8 *)Buffer + GPT_PARTITIONENTRY_LBA);
TargetEntryLBA = (UINT64)(*(UINT32 *)((UINT8 *)Buffer + GPT_PARTITIONENTRY_SIZE) *
PartitionIndex);
TargetEntryOffset = ((UINT32)TargetEntryLBA & BOOT_HEADER_MASK);
TargetEntryLBA = PartitionEntryLBA + RShiftU64 (TargetEntryLBA, BOOT_HEADER_SHIFT);
//
// Read the GPT Entry
//
Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, TargetEntryLBA, BOOT_HEADER_SIZE, Buffer);
if (EFI_ERROR(Status)) {
Print(L"dumpbs: Read boot sector error - %r\n", Status);
goto Done;
}
LBAOffset = *(UINT64 *)((UINT8 *)Buffer + TargetEntryOffset + GPT_ENTRT_STARTING_LBA);
}
Print(L"dumpbs: BootSectorLBAOffset is 0x%lX\n", LBAOffset);
Done:
FreePool(Buffer);
return LBAOffset;
}
EFI_STATUS
WriteMbr (
IN CHAR16 *BlkIoName,
IN CHAR16 *FileName
)
{
EFI_BLOCK_IO_PROTOCOL *BlkIo;
EFI_FILE *FileHandle;
VOID *Buffer;
VOID *TempBuffer;
UINTN BufSize;
EFI_STATUS Status;
Status = GetBlkIOFromName (BlkIoName, &BlkIo);
if (EFI_ERROR(Status)) {
Print (L"dumpbs: GetBlkIOFromName fail - %s\n", BlkIoName);
return Status;
}
//
// Get the File from sector file name
//
Status = GetFileHandleFromName (FileName, &FileHandle);
if (EFI_ERROR(Status)) {
Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
return Status;
}
//
// Init
//
BufSize = BOOT_HEADER_SIZE;
Buffer = AllocatePool (BOOT_HEADER_SIZE);
ASSERT (Buffer != NULL);
TempBuffer = AllocatePool (BOOT_HEADER_SIZE);
ASSERT (TempBuffer != NULL);
//
// Write the boot sector to block device from a file
//
//
// Set file pointer to end start position
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?