BootOrder 변수는 Boot####옵션의 정렬된 목록을 구성하는 UINT16의 배열을 포함한다. 배열의 첫 번째 요소는 첫 번째 논리적 부팅 옵션의 값이고 두 번째 요소는 두 번째 논리적 부팅 옵션의 값 등이다. BootOrder 순서 목록은 펌웨어의 부팅 관리자를 기본 부팅 순서로 지정한다.
FS0:\> dmpstore BootOrder -s BootOrder.bin
Save variable to file: BootOrder.bin.
Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08
UEFI Shell에는 자체적으로 hexedit 명령이 포함되어 있기 때문에 이를 통해 생성된 파일의 내용을 볼 수 있다.
hexedit은 16진수 편집기이며 Ctrl+E 명령으로 도움말 메시지를 볼 수 있다.
Ctrl-W로 도움말을 종료할 수 있다.
dmpstore 명령은 파일에서 다음 구조체로 각 변수를 나타낸다.
{
UINT32 NameSize; // Size of the variable name in bytes
UINT32 DataSize; // Size of the variable data in bytes
CHAR16 Name[NameSize/2]; // Variable name in CHAR16
EFI_GUID Guid; // Variable GUID
UINT32 Attributes; // Variable attributes
UINT8 Data[DataSize]; // Variable data
UINT32 Crc; // CRC32 checksum for the record
}
다음은 구조체 각각의 필드에 대한 강조 표시가 된 파일이다.
부팅 순서를 다음으로 변경하여 파일 내용을 수정해 보자.
Boot0001
Boot0000
Boot0002
Boot0003
종료하려면 Ctrl+Q를 입력하고 우리의 수정 사항을 저장하기 위해 y를 입력하자.
만약 변경된 설정을 로드하려고 하면 오류가 발생한다.
FS0:\> dmpstore -l BootOrder.bin
Load and set variables from file: BootOrder.bin.
dmpstore: Incorrect file format.
dmpstore: No matching variables found. Guid 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
이는 레코드의 UINT32 Crc 필드가 현재 레코드 내용에 대해 더 이상 유효하지 않기 때문에 발생한다.
dmpstore 덤프에서 CRC 필드를 업데이트하기 위해 UpdateDmpstoreDump 애플리케이션을 만들어 보자.
다시 한 번 명령 Shell 인수를 파싱할 것이므로 Shell 애플리케이션을 만드는게 좋다. 우리는 파일을 읽고 쓸 것이므로 LibraryClasses에 ShellLib를 포함해준다.
여기서 CRC32 체크섬을 계산하기 위해 EFI_BOOT_SERVICES.CalculateCrc32() 함수를 사용한다.
EFI_BOOT_SERVICES.CalculateCrc32()
Summary:
Computes and returns a 32-bit CRC for a data buffer.
Prototype:
typedef
EFI_STATUS
(EFIAPI *EFI_CALCULATE_CRC32)
IN VOID *Data,
IN UINTN DataSize,
OUT UINT32 *Crc32
);
Parameters:
Data A pointer to the buffer on which the 32-bit CRC is to be computed.
DataSize The number of bytes in the buffer Data.
Crc32 The 32-bit CRC that was computed for the data buffer specified by Data and DataSize.
Description:
This function computes the 32-bit CRC for the data buffer specified by Data and DataSize. If the 32-bit CRC is computed, then it is returned in Crc32 and EFI_SUCCESS is returned.
CRC32 체크섬이 있으면 ShellWriteFile 함수를 사용하여 파일 내용을 업데이트할 수 있다.
UINTN ToWriteSize = sizeof(Crc32);
Status = ShellWriteFile(
FileHandle,
&ToWriteSize,
&Crc32
);
if (EFI_ERROR(Status) || (ToWriteSize != sizeof(Crc32))) {
Print(L"Error! Not all data was written\n");
FreePool(Buffer);
break;
}
FilePos += ToWriteSize;
애플리케이션을 빌드하고 dmpstore 덤프에 사용해보자.
FS0:\> UpdateDmpstoreDump.efi BootOrder.bin
파일 내용을 다시 보면 CRC 필드가 변경되었음을 알 수 있다.
이제 dmpstore -l은 오류 없이 완료되는 것을 확인할 수 있다.
FS0:\> dmpstore -l BootOrder.bin
Load and set variables from file: BootOrder.bin.
Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08