UEFI Application
来源:互联网 发布:js汉字转unicode编码 编辑:程序博客网 时间:2024/06/04 21:34
UEFI Application是一种EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION类型的EFI Image。os loader 是一种特殊的application,执行完成后不会return或者exit,相反会调用EFI boot service gBS->ExitBootServices()来将控制权从fireware 传递给os。
下面是一个名为HelloWorld的UEFI Application的inf文件,从MODULE_TYPE可以明显的看出这是一个UEFI_APPLICATION,和pei/dxe/uefi driver 不同的是UEFI_APPLICATION没有dependency relationship section
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = HelloWorld
MODULE_UNI_FILE = HelloWorld.uni
FILE_GUID = 6987936E-ED34-44db-AE97-1FA5E4ED2116
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
HelloWorld.c
HelloWorldStr.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
PcdLib
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString || gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes || gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## SOMETIMES_CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
HelloWorldExtra.uni
UEFI_APPLICATION的入口函数的原型必须是
EFI_STATUS EFIAPI UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable);
其中ImageHandle 表示当前执行的uefi application 也就是自己。SystemTable则是指向EFI System Table的一个指针。
在UefiMain 中可以通过gST得到system table,通过gBS得到boot service,通过gRT得到runtime service
通过LocateProtocol()/HandleProtocol()/ OpenProtocol() 来得到其他UEFI driver提供的protocol
还可以同GetVariable() and SetVariable()来读和写全局变量
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT32 Index;
Index = 0;
//
// Three PCD type (FeatureFlag, UINT32 and String) are used as the sample.
//
if (FeaturePcdGet (PcdHelloWorldPrintEnable)) {
for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) {
//
// Use UefiLib Print API to print string to UEFI console
//
Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString));
}
}
return EFI_SUCCESS;
}
可以看到在UEFI_APPLICATION 中可以使用pcd,而pcd定义的字符串或者值一般是定义在dec中
这个程序会输出PcdHelloWorldPrintString
而这个字符串的定义如下:
./MdeModulePkg/MdeModulePkg.dec:1255: gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
从helloworld.map 文件中可以看到_gPcd_FixedAtBuild_PcdHelloWorldPrintString 是被放在rodata段.
.rodata._gPcd_FixedAtBuild_PcdHelloWorldPrintString
0x0000000000001968 0x28 /home//uefi/uefi/Build/RELEASE_GCC49/AARCH64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/HelloWorld.lib(AutoGen.obj)
0x0000000000001968 _gPcd_FixedAtBuild_PcdHelloWorldPrintString
例如在这个例子中,就直接使用gBS 提供的HandleProtocol
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &Gop
);
}
因为gBS本来就是全局变量,所以可以直接用,但是也可以通过下面的方式从SystemTable中得到BootServices
EFI_STATUS
EFIAPI
PrintLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = SystemTable->BootServices->LocateProtocol (
&gEfiPrint2ProtocolGuid,
NULL,
(VOID**) &mPrint2Protocol
);
ASSERT_EFI_ERROR (Status);
ASSERT (mPrint2Protocol != NULL);
return Status;
}
下面是一个名为HelloWorld的UEFI Application的inf文件,从MODULE_TYPE可以明显的看出这是一个UEFI_APPLICATION,和pei/dxe/uefi driver 不同的是UEFI_APPLICATION没有dependency relationship section
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = HelloWorld
MODULE_UNI_FILE = HelloWorld.uni
FILE_GUID = 6987936E-ED34-44db-AE97-1FA5E4ED2116
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
HelloWorld.c
HelloWorldStr.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
PcdLib
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString || gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes || gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable ## SOMETIMES_CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
HelloWorldExtra.uni
UEFI_APPLICATION的入口函数的原型必须是
EFI_STATUS EFIAPI UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable);
其中ImageHandle 表示当前执行的uefi application 也就是自己。SystemTable则是指向EFI System Table的一个指针。
在UefiMain 中可以通过gST得到system table,通过gBS得到boot service,通过gRT得到runtime service
通过LocateProtocol()/HandleProtocol()/ OpenProtocol() 来得到其他UEFI driver提供的protocol
还可以同GetVariable() and SetVariable()来读和写全局变量
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT32 Index;
Index = 0;
//
// Three PCD type (FeatureFlag, UINT32 and String) are used as the sample.
//
if (FeaturePcdGet (PcdHelloWorldPrintEnable)) {
for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) {
//
// Use UefiLib Print API to print string to UEFI console
//
Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString));
}
}
return EFI_SUCCESS;
}
可以看到在UEFI_APPLICATION 中可以使用pcd,而pcd定义的字符串或者值一般是定义在dec中
这个程序会输出PcdHelloWorldPrintString
而这个字符串的定义如下:
./MdeModulePkg/MdeModulePkg.dec:1255: gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
从helloworld.map 文件中可以看到_gPcd_FixedAtBuild_PcdHelloWorldPrintString 是被放在rodata段.
.rodata._gPcd_FixedAtBuild_PcdHelloWorldPrintString
0x0000000000001968 0x28 /home//uefi/uefi/Build/RELEASE_GCC49/AARCH64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/HelloWorld.lib(AutoGen.obj)
0x0000000000001968 _gPcd_FixedAtBuild_PcdHelloWorldPrintString
例如在这个例子中,就直接使用gBS 提供的HandleProtocol
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &Gop
);
}
因为gBS本来就是全局变量,所以可以直接用,但是也可以通过下面的方式从SystemTable中得到BootServices
EFI_STATUS
EFIAPI
PrintLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = SystemTable->BootServices->LocateProtocol (
&gEfiPrint2ProtocolGuid,
NULL,
(VOID**) &mPrint2Protocol
);
ASSERT_EFI_ERROR (Status);
ASSERT (mPrint2Protocol != NULL);
return Status;
}
阅读全文
0 0
- UEFI Application
- 5.UEFI Application
- How to implement an UEFI Shell Application
- UEFI
- How to Write a simple UEFI EDKII Application:如何编写一个UEFI简单的应用程序[5]
- 如何写一个UEFI EDKII的应用:how to write a UEFI EDKII application
- UEFI结构
- UEFI GPT
- UEFI Images
- UEFI HOB
- UEFI Events
- UEFI Images
- UEFI HOB
- 初识UEFI
- UEFI Introduction
- UEFI实战
- 关于UEFI
- HiKey - UEFI
- unity 拖动物体移动
- spring事务的传播属性,数据库事务特征,隔离级别
- JAVA使用、配置相关基础知识
- 启动tomcat 总提示“Publishing to Tomcat v6.0 Server at localhost ...错误
- Python模块:bisect二分算法模块
- UEFI Application
- loss和accuracy的关系
- GitHub访问速度慢的解决方法
- python结合redis的部分操作
- No result defined for action result input
- 数据库集群技术漫谈
- 四。初探CSS
- C#通过websevice发布到IIS 上传到服务器(转载)
- 要将"China"译成密码,密码规律是: 用原来的字母后面第 4 个字母代替原来的字母