61.dmpstore 명령을 사용하여 변수를 파일에 저장/로드하기
dmpstore 변수 덤프에서 CRC32 체크섬을 재계산하는 애플리케이션 작성하기
UEFI Shell에는 UEFI 변수의 내용을 확인하는 데 도움이 되는 dmpstore 명령이 있다.
이 dmpstore 명령의 도움말을 보면 이 명령이 제공하는 유용한 기능을 하나 더 볼 수 있다. 이 명령을 사용하면 UEFI 변수를 파일에 저장하고 해당 파일에서 다시 로드할 수 있다.
FS0:\> dmpstore -?
...
DMPSTORE [-all | ([variable] [-guid guid])] [-s file]
DMPSTORE [-all | ([variable] [-guid guid])] [-l file]
...
-s - Saves variables to a file.
-l - Loads and sets variables from a file.
...이 메커니즘을 사용하여 기존 UEFI 변수의 내용을 수정해보자. 이것은 디버그에 유용한 기능이 될 수 있다.
이전 레슨에서는 UEFI 부팅 변수의 내용을 기반으로 부팅 소스를 표시하는 ShowBootVariables.efi 애플리케이션을 만들었었다.
FS0:\> ShowBootVariables.efi
Boot0000
UiApp
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331)
Boot0001
UEFI QEMU DVD-ROM QM00003
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Boot0002*
EFI Internal Shell
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1)
Boot0003
UEFI QEMU HARDDISK QM00001
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)이 애플리케이션에서 구문 분석된 변수 중 하나는 BootOrder 변수였다.
잊어버린 경우에는 아래의 개념을 보자.
BootOrder 변수의 내용을 출력해보자.
현재 순서는 다음과 같다.
모든 것이 ShowBootVariables 애플리케이션이 보여주는 것과 같다.
dmpstore 명령을 사용하여 BootOrder 변수의 내용을 파일로 덤프할 수 있다.
UEFI Shell에는 자체적으로 hexedit 명령이 포함되어 있기 때문에 이를 통해 생성된 파일의 내용을 볼 수 있다.

hexedit은 16진수 편집기이며 Ctrl+E 명령으로 도움말 메시지를 볼 수 있다.

Ctrl-W로 도움말을 종료할 수 있다.
dmpstore 명령은 파일에서 다음 구조체로 각 변수를 나타낸다.
다음은 구조체 각각의 필드에 대한 강조 표시가 된 파일이다.

부팅 순서를 다음으로 변경하여 파일 내용을 수정해 보자.

종료하려면 Ctrl+Q를 입력하고 우리의 수정 사항을 저장하기 위해 y를 입력하자.
만약 변경된 설정을 로드하려고 하면 오류가 발생한다.
이는 레코드의 UINT32 Crc 필드가 현재 레코드 내용에 대해 더 이상 유효하지 않기 때문에 발생한다.
dmpstore 덤프에서 CRC 필드를 업데이트하기 위해 UpdateDmpstoreDump 애플리케이션을 만들어 보자.
다시 한 번 명령 Shell 인수를 파싱할 것이므로 Shell 애플리케이션을 만드는게 좋다. 우리는 파일을 읽고 쓸 것이므로 LibraryClasses에 ShellLib를 포함해준다.
UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c에서 명령 인수에서 덤프 파일 이름을 읽고 읽기 및 쓰기 속성으로 파일을 여는 것부터 시작한다.
덤프 파일은 자체적으로 많은 레코드를 가질 수 있으며 레코드의 크기는 일정하지 않지만 레코드 필드에 따라 다르다. 따라서 모든 레코드 CRC를 수정하는 유일한 방법은 파일이 끝날 때까지 파일 레코드를 단계별로 실행하는 것이다.
다음은 레코드 데이터를 읽고 CRC32를 계산하는 코드이다. dmpstore 명령에 LoadVariablesFromFileFunction이 있는 것과 매우 유사하다. (https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c)
여기서 CRC32 체크섬을 계산하기 위해 EFI_BOOT_SERVICES.CalculateCrc32() 함수를 사용한다.
CRC32 체크섬이 있으면 ShellWriteFile 함수를 사용하여 파일 내용을 업데이트할 수 있다.
애플리케이션을 빌드하고 dmpstore 덤프에 사용해보자.
파일 내용을 다시 보면 CRC 필드가 변경되었음을 알 수 있다.

이제 dmpstore -l은 오류 없이 완료되는 것을 확인할 수 있다.
또한 변수 내용이 수정된 것을 볼 수 있다.
ShowBootVariables.efi 애플리케이션을 사용하여 변경 사항을 확인할 수도 있다.
덤프 파일에 여러 변수가 있는 경우 프로그램이 작동하는지 확인할 수도 있다.
이전 레슨에 따라 일부 영구 변수가 있는 경우에 대비하여 dmpstore -d -guid 명령을 사용하여 GUID 아래의 모든 변수를 삭제해준다.
새 변수를 생성하고 파일에 저장한다.
hexedit를 사용하여 덤프 파일의 두 레코드에서 World 문자열을 수정해준다. 여기에서는 각 문자 코드에 1을 더했다.
전:
후:
우리의 프로그램을 사용해서 체크섬을 업데이트해준다.
이제 새 덤프가 실제로 두 변수 콘텐츠 내용을 모두 변경했는지 확인할 수 있다.
여기서는 해당이 안되지만 데이터의 크기를 변경하면 UINT32 DataSize 필드도 변경해줘야 된다는 것을 명심해야 한다.
Last updated