37. Shell에 acpiview 명령을 추가하는 방법 조사
ShellPkg 라이브러리(https://github.com/tianocore/edk2/tree/master/ShellPkg/Library)를 검색하면, UefiShellAcpiViewCommandLib
(https://github.com/tianocore/edk2/tree/master/ShellPkg/Library/UefiShellAcpiViewCommandLib) 폴더가 있다.
이 폴더는 in-shell acpiview
명령을 지원하는 라이브러리를 제공한다. INF 파일을 확인하면, https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf 가 표시된다.
# Provides Shell 'acpiview' command functions
하지만, 지금의 OVMF 빌드에서 acpiview
를 실행하려고 하면, 다음 명령이 인식되지 않는다.
FS0:\> acpiview
'acpiview' is not recognized as an internal or external command, operable program, or script file.
이 'acpiview' 명령 기능을 사용하는 데는 세 가지 방법이 있다.
acpiview
를 별도의 애플리케이션으로 컴파일하고, 일반 UEFI shell 애플리케이션으로 실행한다.자체적으로 'acpiview' 명령을 사용하여 shell을 컴파일하고 OVMF에서 실행한다.
'acpiview' 명령이 포함된 shell로 OVMF 이미지 업데이트
Compile acpiview
as a separate app
acpiview
as a separate app짐작컨대 이 방법이 가장 쉬운 방법이라고 생각한다.
https://github.com/tianocore/edk2/tree/master/ShellPkg/Application/AcpiViewApp 도움을 받아 이 작업을 수행할 수 있다.
소스 파일을 보면 매우 간단하다는 것을 알 수 있다. 기본 기능은 ShellCommandRunAcpiView
함수에서 라이브러리 호출을 수행한다.
EFI_STATUS
EFIAPI
AcpiViewAppMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return ShellCommandRunAcpiView (gImageHandle, SystemTable);
}
애플리케이션 빌드실행
build --platform=ShellPkg/ShellPkg.dsc --module=ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC5
이 이미지를 QEMU 공유 폴더에 옮기고,
cp Build/Shell/RELEASE_GCC5/X64/AcpiViewApp.efi ~/UEFI_disk/
해당된 애플리케이션을 실행하면,
FS0:\> AcpiViewApp.efi -?
Display ACPI Table information.
ACPIVIEWAPP.EFI [[-?] | [[[[-l] | [-s AcpiTable [-d]]] [-q] [-h]] [-r Spec]]]
-l - Display list of installed ACPI Tables.
-s - Display only the specified AcpiTable type and only support single
invocation option.
AcpiTable : The required ACPI Table type.
-d - Generate a binary file dump of the specified AcpiTable.
-q - Quiet. Suppress errors and warnings. Disables consistency checks.
-h - Enable colour highlighting.
-r - Validate that all required ACPI tables are installed
Spec : Specification to validate against.
For Arm, the possible values are:
0 - Server Base Boot Requirements v1.0
1 - Server Base Boot Requirements v1.1
2 - Server Base Boot Requirements v1.2
-? - Show help.
This program is provided to allow examination of ACPI table values from the
UEFI Shell. This can help with investigations, especially at that stage
where the tables are not enabling an OS to boot.
The program is not exhaustive, and only encapsulates detailed knowledge of a
limited number of table types.
Default behaviour is to display the content of all tables installed.
'Known' table types (listed in NOTES below) will be parsed and displayed
with descriptions and field values. Where appropriate a degree of
consistency checking is done and errors may be reported in the output.
Other table types will be displayed as an array of Hexadecimal bytes.
To facilitate debugging, the -s and -d options can be used to generate a
binary file image of a table that can be copied elsewhere for investigation
using tools such as those provided by acpica.org. This is especially
relevant for AML type tables like DSDT and SSDT.
NOTES:
1. The AcpiTable parameter can match any installed table type.
Tables without specific handling will be displayed as a raw hex dump (or
dumped to a file if -d is used).
2. -s option supports to display the specified AcpiTable type that is present
in the system. For normal type AcpiTable, it would display the data of the
AcpiTable and AcpiTable header. The following type may contain header type
other than AcpiTable header. The actual header can refer to the ACPI spec
6.3
Extra A. Particular types:
APIC - Multiple APIC Description Table (MADT)
BGRT - Boot Graphics Resource Table
DBG2 - Debug Port Table 2
DSDT - Differentiated System Description Table
FACP - Fixed ACPI Description Table (FADT)
GTDT - Generic Timer Description Table
IORT - IO Remapping Table
MCFG - Memory Mapped Config Space Base Address Description Table
PPTT - Processor Properties Topology Table
RSDP - Root System Description Pointer
SLIT - System Locality Information Table
SPCR - Serial Port Console Redirection Table
SRAT - System Resource Affinity Table
SSDT - Secondary SystemDescription Table
XSDT - Extended System Description Table
EXAMPLES:
* To display a list of the installed table types:
fs0:\> acpiviewapp.efi -l
* To parse and display a specific table type:
fs0:\> acpiviewapp.efi -s GTDT
* To save a binary dump of the contents of a table to a file
in the current working directory:
fs0:\> acpiviewapp.efi -s DSDT -d
* To display contents of all ACPI tables:
fs0:\> acpiviewapp.efi
* To check if all Server Base Boot Requirements (SBBR) v1.2 mandatory
ACPI tables are installed (Arm only):
fs0:\> acpiviewapp.efi -r 2
이 프로그램을 사용하면 시스템의 ACPI 테이블을 나열할 수 있다.
FS0:\> AcpiViewApp.efi -l
Installed Table(s):
1. RSDP
2. XSDT
3. FACP
4. FACS
5. DSDT
6. APIC
7. HPET
8. BGRT
테이블의 내용 표시
FS0:\> AcpiViewApp.efi -s BGRT
--------------- BGRT Table ---------------
Address : 0x7B77000
Length : 56
00000000 : 42 47 52 54 38 00 00 00 - 01 C5 49 4E 54 45 4C 20 BGRT8.....INTEL
00000010 : 45 44 4B 32 20 20 20 20 - 02 00 00 00 20 20 20 20 EDK2 ....
00000020 : 13 00 00 01 01 00 01 00 - 18 30 8B 06 00 00 00 00 .........0......
00000030 : 2F 01 00 00 0F 01 00 00 /.......
Table Checksum : OK
BGRT :
Signature : BGRT
Length : 56
Revision : 1
Checksum : 0xC5
Oem ID : INTEL
Oem Table ID : EDK2
Oem Revision : 0x2
Creator ID :
Creator Revision : 0x1000013
Version : 0x1
Status : 0x1
Image Type : 0x0
Image Address : 0x68B3018
Image Offset X : 303
Image Offset Y : 271
Table Statistics:
0 Error(s)
0 Warning(s)
혹은 ACPI 테이블의 덤프
FS0:\> AcpiViewApp.efi -s APIC -d
Dumping ACPI table to : .\APIC0000.bin ... DONE.
이 이미지는 우리가 이전에 했던 것처럼, iasl -d <file>
로 disassemble을 해낼 수 있다.
자체적으로 'acpiview' 명령을 사용하여 Shell을 컴파일하고 OVMF 실행
이 방법은 좀 의아하긴 하지만, shell 애플리케이션 내부에서 shell 애플리케이션을 실행할 수 있다.
일반적인 경우는 아니지만, 프로젝트에서 실제로 사용할 수 있는 shell 이미지를 컴파일하는 방법을 아는 데 도움이 될 것이다.
https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.dsc 보면, ShellPkg
를 빌드하면 Shell.inf
의 두 가지 버전이 빌드된다는 것을 알 수 있다.
general command가 있을 것이다.
다른 하나는 모든 명령어가 있을 것이다.
ShellPkg/Application/Shell/Shell.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
<LibraryClasses>
NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
fndef $(NO_SHELL_PROFILES)
NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
ndif #$(NO_SHELL_PROFILES)
}
#
# Build a second version of the shell with all commands integrated
#
ShellPkg/Application/Shell/Shell.inf {
<Defines>
FILE_GUID = EA4BB293-2D7F-4456-A681-1F22F42CD0BC
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
<LibraryClasses>
NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf <------- acpiview is present in this Shell version
}
UefiShellAcpiViewCommandLib.inf
가 새 명령을 등록하는 방법이 궁금한 경우, 해당 소스를 살펴보는 것을 추천한다.
https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
[Defines]
INF_VERSION = 0x00010019
BASE_NAME = UefiShellAcpiViewCommandLib
FILE_GUID = FB5B305E-84F5-461F-940D-82D345757AFA
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
LIBRARY_CLASS = AcpiViewCommandLib|UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = UefiShellAcpiViewCommandLibConstructor
DESTRUCTOR = UefiShellAcpiViewCommandLibDestructor
...
EFI_STATUS
EFIAPI
UefiShellAcpiViewCommandLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
...
// Install our Shell command handler
ShellCommandRegisterCommandName (
L"acpiview",
ShellCommandRunAcpiView,
ShellCommandGetManFileNameAcpiView,
0,
L"acpiview",
TRUE,
gShellAcpiViewHiiHandle,
STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
);
return EFI_SUCCESS;
}
별로 복잡한 명령어가 아니기 때문에, 해당 명령어는 Shell에 추가해 줄 수도 있다. 이후 장에서 작성해 둘 생각이다.
이제 다음 명령어를 실행해 Shell 애플리케이션을 빌드 해보자.
build --platform=ShellPkg/ShellPkg.dsc --module=ShellPkg/Application/Shell/Shell.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC5
빌드 이후에 build 폴더에는 다음 두 파일들이 존재하게 될 것이다.
$ ls Build/Shell/RELEASE_GCC5/X64/Shell*.efi
Build/Shell/RELEASE_GCC5/X64/Shell_7C04A583-9E3E-4f1c-AD65-E05268D0B4D1.efi
Build/Shell/RELEASE_GCC5/X64/Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
ShellPkg.dsc
코드를 유심히 살펴보면, 우리가 필요로 하는 이미지가 EA4BB293-2D7F-4456-A681-1F22F42CD0BC
를 GUID 값으로 하는 이미지 라는 것을 알 수 있다.
이를 QEMU 공유 폴더에 복사한다.
$ cp Build/Shell/RELEASE_GCC5/X64/Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi ~/UEFI_disk/
기본 shell에는 acpiview
명령이 없으나, Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
로 이동할 때는 acpiview
명령이 Shell에 존재한다.
FS0:\> acpiview -l
'acpiview' is not recognized as an internal or external command, operable program, or script file.
FS0:\> Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
FS0: Alias(s):HD0a1:;BLK1:
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
BLK2: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Press ESC in 4 seconds to skip startup.nsh or any other key to continue.
FS0:\> acpiview -l
Installed Table(s):
1. RSDP
2. XSDT
3. FACP
4. FACS
5. DSDT
6. APIC
7. HPET
8. BGRT
acpiview 명령어가 포함된 Shell로 OVMF image 업데이트
이번 섹션에서는 OvmfPkgX64.dsc
를 수정한다. UefiShellAcpiViewCommandLib.inf
를 Shell.inf
라이브러리 클래스를 추가한다.
[Components]
...
ShellPkg/Application/Shell/Shell.inf {
<LibraryClasses>
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf <-----------
!if $(NETWORK_IP6_ENABLE) == TRUE
NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
!endif
HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
<PcdsFixedAtBuild>
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
}
수정을 마친 뒤, OVMF를 다시 빌드 한다.
build --platform=OvmfPkg/OvmfPkgX64.dsc --arch=X64 --buildtarget=RELEASE --tagname=GCC5
그리고 해당 OVMF 이미지 자체에 acpiview
명령어가 포함되었는지 테스트 해본다.
FS0:\> acpiview -l
Installed Table(s):
1. RSDP
2. XSDT
3. FACP
4. FACS
5. DSDT
6. APIC
7. HPET
8. BGRT
Last updated