이제 UefiLessonsPkg/SimpleDriver/SimpleDriver.c 소스 파일을 생성한다.
구현해야 할 유일한 함수는 entry 함수인 SimpleDriverEntryPoint 이다.
#include<Library/UefiBootServicesTableLib.h>#include<Library/UefiLib.h>EFI_STATUSEFIAPISimpleDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ){Print(L"Hello from driver!\n");return EFI_SUCCESS;}
드라이버를 생성하기 위해 UefiLessonsPkg/UefiLessonsPkg.dsc의 Components에 추가한다.
build.py...
/home/aladyshev/tiano/edk2/UefiLessonsPkg/UefiLessonsPkg.dsc(...): error 4000: Instance of library class [UefiDriverEntryPoint] is not found
in [/home/aladyshev/tiano/edk2/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf] [X64]
consumed by module [/home/aladyshev/tiano/edk2/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf]
애플리케이션을 만들 때와 마찬가지로 필요한 라이브러리를 찾아야 한다. 2개의 결과가 나오지만 필요한 라이브러리는 MdePkg의 것이므로 이것을 사용한다.
빌드 후 SimpleDriver.efi를 실행하면 아래와 같이 애플리케이션이 아니라는 메시지를 확인할 수 있다.
FS0:\> SimpleDriver.efi
The image is not an application.
위 메시지를 통해서 알 수 있듯이 드라이버는 실행이 불가능하다. 그래서 드라이버를 로드하기 위해서 Shell에서 load명령어를 사용해야 한다.
FS0:\> load -? -b
Loads a UEFI driver into memory.
LOAD [-nc] file [file...]
-nc - Loads the driver, but does not connect the driver.
File - Specifies a file that contains the image of the UEFI driver (wildcards are
permitted).
NOTES:
1. This command loads a driver into memory. It can load multiple files at
one time. The file name supports wildcards.
2. If the -nc flag is not specified, this command attempts to connect the
driver to a proper device. It might also cause previously loaded drivers
to be connected to their corresponding devices.
3. Use the 'UNLOAD' command to unload a driver.
EXAMPLES:
* To load a driver:
fs0:\> load Isabus.efi
* To load multiple drivers:
fs0:\> load Isabus.efi IsaSerial.efi
* To load multiple drivers using file name wildcards:
fs0:\> load Isa*.efi
* To load a driver without connecting it to a device:
fs0:\> load -nc IsaBus.efi
load 명령어를 사용해 드라이버를 로드한다.
FS0:\> load SimpleDriver.efi
Hello from driver!
Image 'FS0:\SimpleDriver.efi' loaded at 6646000 - Success
이제 dh 명령어로 드라이버 핸들을 살펴본다.
FS0:\> dh -? -b
Displays the device handles in the UEFI environment.
DH [-l <lang>] [handle | -p <prot_id>] [-d] [-v]
-p - Dumps all handles of a protocol specified by the GUID.
-d - Dumps UEFI Driver Model-related information.
-l - Dumps information using the language codes (e.g. ISO 639-2).
-sfo - Displays information as described in Standard-Format Output.
-v - Dumps verbose information about a specific handle.
handle - Specifies a handle to dump information about (a hexadecimal number).
If not present, then all information will be dumped.
NOTES:
1. When neither 'handle' nor 'prot_id' is specified, a list of all the
device handles in the UEFI environment is displayed.
2. The '-d' option displays UEFI Driver Model related information including
parent handles, child handles, all drivers installed on the handle, etc.
3. The '-v' option displays verbose information for the specified handle
including all the protocols on the handle and their details.
4. If the '-p' option is specified, all handles containing the specified
protocol will be displayed. Otherwise, the 'handle' parameter has to be
specified for display. In this case, the '-d' option will be enabled
automatically if the '-v' option is not specified.
EXAMPLES:
* To display all handles and display one screen at a time:
Shell> dh -b
* To display the detailed information on handle 0x30:
Shell> dh 30
* To display all handles with 'diskio' protocol:
Shell> dh -p diskio
* To display all handles with 'LoadedImage' protocol and break when the screen is
full:
Shell> dh -p LoadedImage -b
매개변수 없이 dh 명령어를 실행하면 시스템의 모든 핸들을 얻을 수 있다. 우리가 만든 드라이버는 맨 마지막에 확인할 수 있다.
FS0:\> unload -?
Unloads a driver image that was already loaded.
UNLOAD [-n] [-v|-verbose] Handle
-n - Skips all prompts during unloading, so that it can be used
in a script file.
-v, -verbose - Dumps verbose status information before the image is unloaded.
Handle - Specifies the handle of driver to unload, always taken as hexadecimal number.
NOTES:
1. The '-n' option can be used to skip all prompts during unloading.
2. If the '-v' option is specified, verbose image information will be
displayed before the image is unloaded.
3. Only drivers that support unloading can be successfully unloaded.
4. Use the 'LOAD' command to load a driver.
EXAMPLES:
* To find the handle for the UEFI driver image to unload:
Shell> dh -b
* To unload the UEFI driver image with handle 27:
Shell> unload 27
unload 명령은 드라이버에 Unload 함수가 없기
때문에 지금은 사용할 수 없다.
dh -d -v c0을 사용하면 Unload........: 0 부분을 확인할 수 있다.
따라서 드라이버를 언로드하려고 하면 오류가 발생한다.
FS0:\> unload c0
Unload - Handle [664C998]. [y/n]?
y
Unload - Handle [664C998] Result Unsupported.
dh 명령어를 실행하면 시스템에 드라이버 핸들이 여전히 존재하는 것을 볼 수 있다.
Unload 함수 추가
이제 언로드 함수를 드라이버에 추가한다. 아래 설정을 UefiLessonsPkg/SimpleDriver/SimpleDriver.inf에 추가한다.
MZ 시그니처는 PE/COFF 이미지(*.efi 파일)의 헤더를 나타낸다. 그래서 실제 드라이버는 ImageBase에 존재한다.
이제 드라이버를 언로드 한다.
FS0:\> unload c6
Unload - Handle [664CF18]. [y/n]?
y
Bye-bye from driver!
Unload - Handle [664CF18] Result Success.
메모리를 다시 확인하면 아래와 같이 비어진 것을 확인할 수 있다.
FS0:\> dmem 6646000 A0
Memory Address 0000000006646000 A0 Bytes
06646000: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646010: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646020: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646030: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646040: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646050: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646060: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646070: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646080: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
06646090: AF AF AF AF AF AF AF AF-AF AF AF AF AF AF AF AF *................*
드라이버를 새로 로드하면 기존에 사용했던 C0은 넘어가고 C1으로 핸들이 존재하는 것을 볼 수 있다.