diff options
author | Konstantin Aladyshev <aladyshev22@gmail.com> | 2021-07-10 00:04:40 +0300 |
---|---|---|
committer | Konstantin Aladyshev <aladyshev22@gmail.com> | 2021-07-10 00:04:40 +0300 |
commit | 6064c1e48b622f53538f4df9bdd402c607a87d51 (patch) | |
tree | 93d3c937b9568568307fd2ff7053a30c538ad72a /Lesson_34 | |
parent | a9c375c80c3505be794ec2b5d5bb90de27ef0d42 (diff) | |
download | UEFI-Lessons-6064c1e48b622f53538f4df9bdd402c607a87d51.tar.gz UEFI-Lessons-6064c1e48b622f53538f4df9bdd402c607a87d51.tar.bz2 UEFI-Lessons-6064c1e48b622f53538f4df9bdd402c607a87d51.zip |
Move lessons to separate folder
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Diffstat (limited to 'Lesson_34')
-rw-r--r-- | Lesson_34/README.md | 352 | ||||
-rw-r--r-- | Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.c | 26 | ||||
-rw-r--r-- | Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf | 19 |
3 files changed, 0 insertions, 397 deletions
diff --git a/Lesson_34/README.md b/Lesson_34/README.md deleted file mode 100644 index 933237f..0000000 --- a/Lesson_34/README.md +++ /dev/null @@ -1,352 +0,0 @@ -Let's create a simple UEFI driver. - -Up until now we've created only UEFI applications. The main difference between application and a driver is a fact that application is unloaded from the memory after its execution. But the driver is a thing that stays in memory. And while it stays there it can provide usefull protocols for other applications to use. - - -Let's create a simplest driver UefiLessonsPkg/SimpleDriver/SimpleDriver.inf -``` -[Defines] - INF_VERSION = 1.25 - BASE_NAME = SimpleDriver - FILE_GUID = 384aeb18-105d-4af1-bf17-5e349e8f4d4c - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SimpleDriverEntryPoint - -[Sources] - SimpleDriver.c - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - UefiLib -``` -Things that have changed from our usual INF file: -- The `MODULE_TYPE` is `UEFI_DRIVER` (earlier we've always used `UEFI_APPLICATION`), -- The `ENTRY_POINT` is `SimpleDriverEntryPoint` (earlier we've always used `UefiMain`, but the driver operates with Entry/Unload functions, so it is better to start to give them proper names), -- `UefiDriverEntryPoint` library class is used (earlier we've always used `UefiApplicationEntryPoint`). In case you wonder about `UefiDriverEntryPoint` library internals take a look into https://github.com/tianocore/edk2/tree/master/MdePkg/Library/UefiDriverEntryPoint - -Now let's write *.c source file UefiLessonsPkg/SimpleDriver/SimpleDriver.c - -The only function that we need to implement is our entry function `SimpleDriverEntryPoint` that we've declared: -``` -#include <Library/UefiBootServicesTableLib.h> -#include <Library/UefiLib.h> - -EFI_STATUS -EFIAPI -SimpleDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - Print(L"Hello from driver!\n"); - - return EFI_SUCCESS; -} -``` - -Include this driver in the components section of our `UefiLessonsPkg/UefiLessonsPkg.dsc`: -``` -[Components] - ... - UefiLessonsPkg/SimpleDriver/SimpleDriver.inf -``` -If you try to build, the process would fail: -``` -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] -``` -As usually we need to find proper library implementation: -``` -$ grep UefiDriverEntryPoint -r ./ --exclude-dir=Build | grep LIBRARY_CLASS -./MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf: LIBRARY_CLASS = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER -``` -And place it in our DSC: -``` -[LibraryClasses] - ... - UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf -``` - -Build, copy file to our QEMU shared folder and run OVMF. - -First let's try to execute it as an app: -``` -FS0:\> SimpleDriver.efi -The image is not an application. -``` -As you see this action is not possible. - -To load driver we need to use `load` shell command: -``` -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 -``` - -Use this command to load our driver: -``` -FS0:\> load SimpleDriver.efi -Hello from driver! -Image 'FS0:\SimpleDriver.efi' loaded at 6646000 - Success -``` - -Now let's try to use `dh` command to look at our driver handle: -``` -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 -``` - -If you'll execute it without any parameters, you'll get all handles in the system. And our driver would be the last one: -``` -FS0:\> dh -... -C6: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -``` -You can print more verbose output for our handle: -``` -FS0:\> dh -d -v c6 -C6: 664C998 -ImageDevicePath(664A018) - PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)/\SimpleDriver.efi -LoadedImage(664A440) - Revision......: 0x00001000 - ParentHandle..: 6EE5D18 - SystemTable...: 79EE018 - DeviceHandle..: 6E36798 - FilePath......: \SimpleDriver.efi - PdbFileName...: /home/aladyshev/tiano/edk2/Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/SimpleDriver/SimpleDriver/DEBUG/SimpleDriver.dll - OptionsSize...: 0 - LoadOptions...: 0 - ImageBase.....: 6646000 - ImageSize.....: 16C0 - CodeType......: EfiBootServicesCode - DataType......: EfiBootServicesData - Unload........: 0 -``` - - -You can load more instanses of our driver, this is not a problem: -``` -FS0:\> load SimpleDriver.efi -Hello from driver! -Image 'FS0:\SimpleDriver.efi' loaded at 6619000 - Success -FS0:\> load SimpleDriver.efi -Hello from driver! -Image 'FS0:\SimpleDriver.efi' loaded at 6617000 - Success -FS0:\> load SimpleDriver.efi -Hello from driver! -Image 'FS0:\SimpleDriver.efi' loaded at 6613000 - Success -``` - -If you look at dh now, there would be multiple handles from our driver: -``` -FS0:\> dh -... -C6: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -C7: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -C8: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -C9: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -``` - -To unload driver from memory you can utilize `unload` command: -``` -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 -``` - -But it is now possible to use it now as our driver don't have an Unload function. If you'll look at the earlier output of `dh -d -v c6` command, you can see that `Unload........: 0`. - -Therefore if you'll try to unload our driver you'll get an error: -``` -FS0:\> unload c6 -Unload - Handle [664C998]. [y/n]? -y -Unload - Handle [664C998] Result Unsupported. -``` -If you'll execute `dh`, you would still see that our driver handle is still present in the system. - -# Add unload function - -Now let's try add unload function to our driver. Add it to the INF file UefiLessonsPkg/SimpleDriver/SimpleDriver.inf: -``` -[Defines] - ... - ENTRY_POINT = SimpleDriverEntryPoint -+ UNLOAD_IMAGE = SimpleDriverUnload -``` -And add some simple implementation to the *.c file UefiLessonsPkg/SimpleDriver/SimpleDriver.c: -``` -EFI_STATUS -EFIAPI -SimpleDriverUnload ( - EFI_HANDLE ImageHandle - ) -{ - Print(L"Bye-bye from driver!\n"); - - return EFI_SUCCESS; -} -``` - -If you try to execute `dh -d -v` on the handle from this driver you'll get something like: -``` -FS0:\> dh -d -v c6 -C6: 664CA98 -ImageDevicePath(664C618) - PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)/\SimpleDriver.efi -LoadedImage(664A240) - Revision......: 0x00001000 - ParentHandle..: 6EE5D18 - SystemTable...: 79EE018 - DeviceHandle..: 6E36798 - FilePath......: \SimpleDriver.efi - PdbFileName...: /home/aladyshev/tiano/edk2/Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/SimpleDriver/SimpleDriver/DEBUG/SimpleDriver.dll - OptionsSize...: 0 - LoadOptions...: 0 - ImageBase.....: 6646000 - ImageSize.....: 1780 - CodeType......: EfiBootServicesCode - DataType......: EfiBootServicesData - Unload........: 6647047 -``` -As you can see now `Unload` string is filled with a pointer to the driver unload function. - -Before preforming an unload take a look at the ImageBase address with `dmem`: -``` -FS0:\> dmem 6646000 A0 -Memory Address 0000000006646000 A0 Bytes - 06646000: 4D 5A 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *MZ..............* - 06646010: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646020: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646030: 00 00 00 00 00 00 00 00-00 00 00 00 80 00 00 00 *................* - 06646040: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646050: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646060: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646070: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* - 06646080: 50 45 00 00 64 86 02 00-00 00 00 00 00 00 00 00 *PE..d...........* - 06646090: 00 00 00 00 F0 00 2E 00-0B 02 00 00 40 14 00 00 *............@...* -``` -`MZ` signature signifies the header of a PE/COFF image (*.efi file). So our driver is actually there. - -Now perform unload: -``` -FS0:\> unload c6 -Unload - Handle [664CF18]. [y/n]? -y -Bye-bye from driver! -Unload - Handle [664CF18] Result Success. -``` - -Look at the memory again: -``` -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 *................* -``` -As you can see in was automatically freed. - - -One more notice. If you'll load your image again, it would have a handle with C7 number. Number C6 would be skipped: -``` -C5: ... -C7: ImageDevicePath(..F,0xFBFC1)/\SimpleDriver.efi) LoadedImage(\SimpleDriver.efi) -``` - diff --git a/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.c b/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.c deleted file mode 100644 index fd96d17..0000000 --- a/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.c +++ /dev/null @@ -1,26 +0,0 @@ -#include <Library/UefiBootServicesTableLib.h> -#include <Library/UefiLib.h> - - -EFI_STATUS -EFIAPI -SimpleDriverUnload ( - EFI_HANDLE ImageHandle - ) -{ - Print(L"Bye-bye from driver!\n"); - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -SimpleDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - Print(L"Hello from driver!\n"); - - return EFI_SUCCESS; -} diff --git a/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf b/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf deleted file mode 100644 index a6008c2..0000000 --- a/Lesson_34/UefiLessonsPkg/SimpleDriver/SimpleDriver.inf +++ /dev/null @@ -1,19 +0,0 @@ -[Defines] - INF_VERSION = 1.25 - BASE_NAME = SimpleDriver - FILE_GUID = 384aeb18-105d-4af1-bf17-5e349e8f4d4c - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SimpleDriverEntryPoint - UNLOAD_IMAGE = SimpleDriverUnload - -[Sources] - SimpleDriver.c - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - UefiLib - |