UEFI学习笔记(六):EDK II Modules:Libraries,Application&Drivers
一、模块(Modules)的概念
模块是一个最小的可编译单元,在放在Package里面的(Package是EDK II 最小的对外发布的单元)。模块包括Library、Driver、Application等类型。每一个模块都有一个INF文件。
1、Library模块
Library和Library之间可以互相依赖。
[LibraryClasses.common]
## <LibraryClassName>|<LibraryInstancePathToInf/Name.inf>
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
(p.s. 可以用Doxygen根据代码生成CHM文件,方便查找Libary的功能)
MdePkg(Specs) —>SerialPort(Class)—>DebugLibSerialPort(Instance)—>DebugLib
LibraryClass应的是头文件, Library Intance对应的是一个模块(INF)
LibraryClass主要在include/Library/目录下面找,Libray Instance主要在Libary目录下找
2、Application模块
作用: 调试device、平台分析、工具开发、显示变量、显示设备等
(os loader 是一种特殊的application,执行完成后不会return或者exit,相反会调用EFI boot service gBS->ExitBootServices()来将控制权从fireware 传递给os)
3、Driver模块
Driver可以依赖Library,Driver可以生产protocols,主要用于支持硬件。
4、Application和Driver的区别
Application相当于是一次性的,一执行完就结束,而Driver是一直存在的。App是被UEFI loader加载的,不会装protocols。
二、EDK II 实现UEFI Application
实现一个简单的HelloWorld应用程序
1)HelloWorld.inf
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = HelloWorld
FILE_GUID = 67A6DE6D-XXXX-XXXX-XXXX-XXXXXXXXXXXX
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = HelloWorldEntry
[Sources]
HelloWorld.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
[Guids]
[Ppis]
[Protocols]
2)HelloWorld.c
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
EFI_STATUS
EFIAPI
HelloWorldEntry(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
Print (L" HelloWorld!\n");
return EFI_SUCCESS;
}
三、EDK II 实现UEFI Driver
1)MyDriver.inf
实现一个简单的MyDriver驱动
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MyDriver
FILE_GUID = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MyDriverEntry
[Sources]
MyDriver.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
[Guids]
[Ppis]
[Protocols]
2)MyDriver.c
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
EFI_STATUS
EFIAPI
MyDriverEntry(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//在此实现内容
return EFI_SUCCESS;
}