UEFI 개발 및 디 버 깅 - edk 2 의 기본 구성 요소
29066 단어 UEFI 개발 및 디 버 깅
시스템 테이블 (시스템 테이블)
시스템 표 는 edk 2 가 제공 하 는 가장 중요 하고 기본 적 인 데이터 구조 중 하나 로 커 널 과 응용 / 구동 을 소통 하 는 다리 이다.시스템 표를 통 해 응용 프로그램 과 구동 을 통 해 커 널 과 하드웨어 자원 에 접근 할 수 있 습 니 다.시스템 표 에는 다음 과 같은 정보 가 포함 되 어 있 습 니 다.
///
/// EFI System Table
///
typedef struct {
///
/// The table header for the EFI System Table.
///
EFI_TABLE_HEADER Hdr;
///
/// A pointer to a null terminated string that identifies the vendor
/// that produces the system firmware for the platform.
///
CHAR16 *FirmwareVendor;
///
/// A firmware vendor specific value that identifies the revision
/// of the system firmware for the platform.
///
UINT32 FirmwareRevision;
///
/// The handle for the active console input device. This handle must support
/// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
///
EFI_HANDLE ConsoleInHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
/// associated with ConsoleInHandle.
///
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
///
/// The handle for the active console output device.
///
EFI_HANDLE ConsoleOutHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with ConsoleOutHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
///
/// The handle for the active standard error console device.
/// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
///
EFI_HANDLE StandardErrorHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with StandardErrorHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
///
/// A pointer to the EFI Runtime Services Table.
///
EFI_RUNTIME_SERVICES *RuntimeServices;
///
/// A pointer to the EFI Boot Services Table.
///
EFI_BOOT_SERVICES *BootServices;
///
/// The number of system configuration tables in the buffer ConfigurationTable.
///
UINTN NumberOfTableEntries;
///
/// A pointer to the system configuration tables.
/// The number of entries in the table is NumberOfTableEntries.
///
EFI_CONFIGURATION_TABLE *ConfigurationTable;
} EFI_SYSTEM_TABLE;
UEFI 에 서 는 초기 화 된 System Table 을 정의 합 니 다. MdeModulePkg / Core / Dxe / DxeMain / DxeMain. c:
EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
{
EFI_SYSTEM_TABLE_SIGNATURE, // Signature
EFI_SYSTEM_TABLE_REVISION, // Revision
sizeof (EFI_SYSTEM_TABLE), // HeaderSize
0, // CRC32
0 // Reserved
},
NULL, // FirmwareVendor
0, // FirmwareRevision
NULL, // ConsoleInHandle
NULL, // ConIn
NULL, // ConsoleOutHandle
NULL, // ConOut
NULL, // StandardErrorHandle
NULL, // StdErr
NULL, // RuntimeServices
&mBootServices, // BootServices
0, // NumberOfConfigurationTableEntries
NULL // ConfigurationTable
};
UEFI 가 DXE 단계 로 실 행 될 때 UEFI 커 널 은 이 를 통 해 System Table 을 구축 하고 구체 적 으로 실현 하 는 것 도 MdeModulePkg / Core / Dxe / DxeMain / DxeMain. c:
//
// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
//
gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
ASSERT (gDxeCoreST != NULL);
위의 복사 동작 을 통 해 알 수 있 듯 이 UEFI 커 널 은 System Table 을 구축 하여 응용 과 구동 에 제공 하 는 인터페이스 로 서 구 축 된 코드 에서 알 수 있 듯 이 DXE 단계 가 시 작 된 후에 만 사용 할 수 있다.주의해 야 할 것 은 BootServices 는 mEfi System TableTemplate 에서 정적 으로 설 정 된 & mBootServices 이 고 Runtime Services 는 NULL 로 초기 화 되 어 있 기 때문에 뒤에 코드 를 구축 해 야 합 니 다.이 부분 은 우리 가 뒤에서 소개 할 것 이다.
서비스 시트 시작 (BootServices)
System Table 과 마찬가지 로 구조 체 도 MdePkg / Include / Uefi / UefiSpec. h 로 정 의 됩 니 다.
/// EFI Boot Services Table.
///
typedef struct {
///
/// The table header for the EFI Boot Services Table.
///
EFI_TABLE_HEADER Hdr;
//
// Task Priority Services
//
EFI_RAISE_TPL RaiseTPL;
EFI_RESTORE_TPL RestoreTPL;
//
// Memory Services
//
EFI_ALLOCATE_PAGES AllocatePages;
EFI_FREE_PAGES FreePages;
EFI_GET_MEMORY_MAP GetMemoryMap;
EFI_ALLOCATE_POOL AllocatePool;
EFI_FREE_POOL FreePool;
//
// Event & Timer Services
//
EFI_CREATE_EVENT CreateEvent;
EFI_SET_TIMER SetTimer;
EFI_WAIT_FOR_EVENT WaitForEvent;
EFI_SIGNAL_EVENT SignalEvent;
EFI_CLOSE_EVENT CloseEvent;
EFI_CHECK_EVENT CheckEvent;
//
// Protocol Handler Services
//
EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
EFI_HANDLE_PROTOCOL HandleProtocol;
VOID *Reserved;
EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
EFI_LOCATE_HANDLE LocateHandle;
EFI_LOCATE_DEVICE_PATH LocateDevicePath;
EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
//
// Image Services
//
EFI_IMAGE_LOAD LoadImage;
EFI_IMAGE_START StartImage;
EFI_EXIT Exit;
EFI_IMAGE_UNLOAD UnloadImage;
EFI_EXIT_BOOT_SERVICES ExitBootServices;
//
// Miscellaneous Services
//
EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
EFI_STALL Stall;
EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
//
// DriverSupport Services
//
EFI_CONNECT_CONTROLLER ConnectController;
EFI_DISCONNECT_CONTROLLER DisconnectController;
//
// Open and Close Protocol Services
//
EFI_OPEN_PROTOCOL OpenProtocol;
EFI_CLOSE_PROTOCOL CloseProtocol;
EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
//
// Library Services
//
EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
EFI_LOCATE_PROTOCOL LocateProtocol;
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
//
// 32-bit CRC Services
//
EFI_CALCULATE_CRC32 CalculateCrc32;
//
// Miscellaneous Services
//
EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem;
EFI_CREATE_EVENT_EX CreateEventEx;
} EFI_BOOT_SERVICES;
위의 주석 을 보면 다음 과 같은 내용 을 포함 하고 있 음 을 알 수 있다.
//
// DXE Core Module Variables
//
EFI_BOOT_SERVICES mBootServices = {
{
EFI_BOOT_SERVICES_SIGNATURE, // Signature
EFI_BOOT_SERVICES_REVISION, // Revision
sizeof (EFI_BOOT_SERVICES), // HeaderSize
0, // CRC32
0 // Reserved
},
(EFI_RAISE_TPL) CoreRaiseTpl, // RaiseTPL
(EFI_RESTORE_TPL) CoreRestoreTpl, // RestoreTPL
(EFI_ALLOCATE_PAGES) CoreAllocatePages, // AllocatePages
(EFI_FREE_PAGES) CoreFreePages, // FreePages
(EFI_GET_MEMORY_MAP) CoreGetMemoryMap, // GetMemoryMap
(EFI_ALLOCATE_POOL) CoreAllocatePool, // AllocatePool
(EFI_FREE_POOL) CoreFreePool, // FreePool
(EFI_CREATE_EVENT) CoreCreateEvent, // CreateEvent
(EFI_SET_TIMER) CoreSetTimer, // SetTimer
(EFI_WAIT_FOR_EVENT) CoreWaitForEvent, // WaitForEvent
(EFI_SIGNAL_EVENT) CoreSignalEvent, // SignalEvent
(EFI_CLOSE_EVENT) CoreCloseEvent, // CloseEvent
(EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent
(EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface
(EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface
(EFI_UNINSTALL_PROTOCOL_INTERFACE) CoreUninstallProtocolInterface, // UninstallProtocolInterface
(EFI_HANDLE_PROTOCOL) CoreHandleProtocol, // HandleProtocol
(VOID *) NULL, // Reserved
(EFI_REGISTER_PROTOCOL_NOTIFY) CoreRegisterProtocolNotify, // RegisterProtocolNotify
(EFI_LOCATE_HANDLE) CoreLocateHandle, // LocateHandle
(EFI_LOCATE_DEVICE_PATH) CoreLocateDevicePath, // LocateDevicePath
(EFI_INSTALL_CONFIGURATION_TABLE) CoreInstallConfigurationTable, // InstallConfigurationTable
(EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage
(EFI_IMAGE_START) CoreStartImage, // StartImage
(EFI_EXIT) CoreExit, // Exit
(EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage
(EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices
(EFI_GET_NEXT_MONOTONIC_COUNT) CoreEfiNotAvailableYetArg1, // GetNextMonotonicCount
(EFI_STALL) CoreStall, // Stall
(EFI_SET_WATCHDOG_TIMER) CoreSetWatchdogTimer, // SetWatchdogTimer
(EFI_CONNECT_CONTROLLER) CoreConnectController, // ConnectController
(EFI_DISCONNECT_CONTROLLER) CoreDisconnectController, // DisconnectController
(EFI_OPEN_PROTOCOL) CoreOpenProtocol, // OpenProtocol
(EFI_CLOSE_PROTOCOL) CoreCloseProtocol, // CloseProtocol
(EFI_OPEN_PROTOCOL_INFORMATION) CoreOpenProtocolInformation, // OpenProtocolInformation
(EFI_PROTOCOLS_PER_HANDLE) CoreProtocolsPerHandle, // ProtocolsPerHandle
(EFI_LOCATE_HANDLE_BUFFER) CoreLocateHandleBuffer, // LocateHandleBuffer
(EFI_LOCATE_PROTOCOL) CoreLocateProtocol, // LocateProtocol
(EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
(EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
(EFI_CALCULATE_CRC32) CoreEfiNotAvailableYetArg3, // CalculateCrc32
(EFI_COPY_MEM) CopyMem, // CopyMem
(EFI_SET_MEM) SetMem, // SetMem
(EFI_CREATE_EVENT_EX) CoreCreateEventEx // CreateEventEx
};
여기 서 정 의 된 mBootServices 주 소 를 초기 화하 면 SystemTable 에 직접 전 달 됩 니 다.
EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
......
&mBootServices, // BootServices
......
};
런 타임 서비스 (RunTime Services)
ExitBootServices 가 실 행 된 후에 Boot Service 의 함 수 는 더 이상 사용 할 수 없 지만 Runtime Service Table 의 함 수 는 사용 할 수 있 습 니 다. DXE 단계 부터 운영 체제 가 끝 날 때 까지 Runtime Service 는 계속 존재 하고 OS 에서 도 사용 할 수 있 습 니 다.
구조 체 역시 MdePkg / Include / Uefi / UefiSpec. h 로 정 의 됩 니 다.
///
/// EFI Runtime Services Table.
///
typedef struct {
///
/// The table header for the EFI Runtime Services Table.
///
EFI_TABLE_HEADER Hdr;
//
// Time Services
//
EFI_GET_TIME GetTime;
EFI_SET_TIME SetTime;
EFI_GET_WAKEUP_TIME GetWakeupTime;
EFI_SET_WAKEUP_TIME SetWakeupTime;
//
// Virtual Memory Services
//
EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
EFI_CONVERT_POINTER ConvertPointer;
//
// Variable Services
//
EFI_GET_VARIABLE GetVariable;
EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
EFI_SET_VARIABLE SetVariable;
//
// Miscellaneous Services
//
EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
EFI_RESET_SYSTEM ResetSystem;
//
// UEFI 2.0 Capsule Services
//
EFI_UPDATE_CAPSULE UpdateCapsule;
EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
//
// Miscellaneous UEFI 2.0 Service
//
EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
} EFI_RUNTIME_SERVICES;
기본 초기 화 변 수 는 MdeModulePkg / Core / Dxe / DxeMain / DxeMain. c 로 정 의 됩 니 다.
EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
{
EFI_RUNTIME_SERVICES_SIGNATURE, // Signature
EFI_RUNTIME_SERVICES_REVISION, // Revision
sizeof (EFI_RUNTIME_SERVICES), // HeaderSize
0, // CRC32
0 // Reserved
},
(EFI_GET_TIME) CoreEfiNotAvailableYetArg2, // GetTime
(EFI_SET_TIME) CoreEfiNotAvailableYetArg1, // SetTime
(EFI_GET_WAKEUP_TIME) CoreEfiNotAvailableYetArg3, // GetWakeupTime
(EFI_SET_WAKEUP_TIME) CoreEfiNotAvailableYetArg2, // SetWakeupTime
(EFI_SET_VIRTUAL_ADDRESS_MAP) CoreEfiNotAvailableYetArg4, // SetVirtualAddressMap
(EFI_CONVERT_POINTER) CoreEfiNotAvailableYetArg2, // ConvertPointer
(EFI_GET_VARIABLE) CoreEfiNotAvailableYetArg5, // GetVariable
(EFI_GET_NEXT_VARIABLE_NAME) CoreEfiNotAvailableYetArg3, // GetNextVariableName
(EFI_SET_VARIABLE) CoreEfiNotAvailableYetArg5, // SetVariable
(EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1, // GetNextHighMonotonicCount
(EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem
(EFI_UPDATE_CAPSULE) CoreEfiNotAvailableYetArg3, // UpdateCapsule
(EFI_QUERY_CAPSULE_CAPABILITIES) CoreEfiNotAvailableYetArg4, // QueryCapsuleCapabilities
(EFI_QUERY_VARIABLE_INFO) CoreEfiNotAvailableYetArg4 // QueryVariableInfo
};
Runtime Services 도 DxeMain. c 에서 System Table 에 가입 되 었 습 니 다.
//
// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
//
gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
ASSERT (gDxeCoreST != NULL);
gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
ASSERT (gDxeCoreRT != NULL);
gDxeCoreST->RuntimeServices = gDxeCoreRT;
//
위의 초기 화 정의 에서 많은 리 셋 함수 가 CoreEfi NotAvailable Yet * 로 설정 되 어 있 습 니 다. 이것 은 이 함수 가 아직 사용 할 수 없 음 을 설명 합 니 다. DXE 실행 단계 에서 동적 으로 추가 해 야 합 니 다.