UEFI除标准应用程序工程模块外的其他工程模块--随记

Shell应用工程模块

标准应用程序工程模块,它 的 入参有很多系统参数需要处理,还有很多其他的命令行参数处理,很不方便。但一般的应用程序都需要在Shell下去执行,它就需要带命令行参数。edk2就提供了Shell应用程序工程模块

用户入口函数

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  UINTN  Index;
  if (Argc == 1) {
    Print (L"Argv[1] = NULL\n");
  }
  for (Index = 1; Index < Argc; Index++) {
    Print(L"Argv[%d]: \"%s\"\n", Index, Argv[Index]);
  }

  return 0;
}

Shell应用程序模块的入口函数都是INIT ShellAppMain函数,它 的入参里面没有了系统参数,我们要使用系统表这些系统参数,就需要gST这些全局量。

工程文件

Shell应用程序的工程文件和标准应用程序的工程文件有区别部分区别:
MODULE_TYPE和标准应用程序一样是UEFI_APPLICATION,但是它的ENTRY_POINT必须是ShellCEntryLib,并且必须要在源文件中实现ShellAppMain。必须要有MdePkg/MdePkg.dec和ShellPkg/ShellPkg.dec声明文件。必须要有ShellCEntryLib库,一般还要使用系统表,需要有UefiBootServicesTableLib库。

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = ShellCTestApp
  FILE_GUID                      = 7a6ca3b8-ee1b-489c-b300-24544a7bd418
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = ShellCEntryLib

[Sources]
  ShellCTestApp.c

[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec

[LibraryClasses]
  ShellCEntryLib
  UefiLib

UEFI入口函数ShellCEntryLib

Shell应用程序的入口函数是ShellCEntryLib,它的原型在ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c下面:

EFI_STATUS
EFIAPI
ShellCEntryLib (
 IN EFI_HANDLE        ImageHandle,
 IN EFI_SYSTEM_TABLE  *SystemTable
 )
{
 ###################################
 Status = SystemTable->BootServices->OpenProtocol(ImageHandle,
                            &gEfiShellParametersProtocolGuid,
                            (VOID **)&EfiShellParametersProtocol,
                            ImageHandle,
                            NULL,
                            EFI_OPEN_PROTOCOL_GET_PROTOCOL
                           );
 if (!EFI_ERROR(Status)) {
   //
   // use shell 2.0 interface
   //
   ReturnFromMain = ShellAppMain (
                      EfiShellParametersProtocol->Argc,
                      EfiShellParametersProtocol->Argv
                     );
 } else {
###################################
}
}

它的入参和标准应用程序的入参是一样的,它会去打开EFI_SHELL_PAEAMETERS_PROTOCOL,通过这个protocol获得ShellAppMain的入参,就是首先获取命令行参数,然后再调用用户的入口函数ShellAppMain去打开Shell。

使用main函数的应用程序工程模块

使用main函数的应用程序工程模块会使用StdLib,在StdLib中提供了ShellAppMain函数,我们自己实现main函数作为程序的入口函数供ShellAppMain去调用,真正的模块入口函数是ShellCEntryLib,调用过程是:ShellCEntryLib———>ShellAppMain——>main
使用main函数的应用程序工程模块要在AppPkg环境下才能编译成功,所以需要将main.inf添加到AppPkg.dsc文件的[Components]块下。

自己没遇到过这种,和shell应用程序工程模块用法一样

库模块

在开发uefi工程过程中,会使用到大量的库。库也有源文件、工程文件,其他模块要使用库,要将这个库添加到包的dsc声明文件中

UefiLib.inf:
[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = UefiLib
  MODULE_UNI_FILE                = UefiLib.uni
  FILE_GUID                      = 3a004ba5-efe0-4a61-9f1a-267a46ae5ba9
  MODULE_TYPE                    = UEFI_DRIVER
  VERSION_STRING                 = 1.0
  LIBRARY_CLASS                  = UefiLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
  CONSTRUCTOR                    = UefiLibConstructor

BaseDebugLibNull.inf:
[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = BaseDebugLibNull
  MODULE_UNI_FILE                = BaseDebugLibNull.uni
  FILE_GUID                      = 9ba1d976-0624-41a3-8650-28165e8d9ae8
  MODULE_TYPE                    = BASE
  VERSION_STRING                 = 1.0
  LIBRARY_CLASS                  = DebugLib

可以看到库的工程文件和其他应用程序有很大的区别。没有ENTRY_POINT;它会指定 MODULE_TYPE是BASE函数DRIVER等类型;通过LIBRARY_CLASS设定库名,指定库的适用范围,让它仅能被特定的模块调用
其他模块要使用这个库,就将库添加到自己的dsc文件中:
[LibraryClasses]
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
然后在自己的inf中添加这个库:
[LibraryClasses]
UefiLib
然后在源文件中就可以使用这个库了

库如果要在使用之前需要初始化,那要在库的工程文件中指定CONSTRUCTOR和DESTRUCTOR

驱动模块

驱动和应用程序的最大区别就是驱动会常驻内存,而应用程序在执行完毕之后就会从内存中清除。

驱动类型

1、符合UEFI驱动模型的驱动,驱动模型是UEFI_DRIVER,称为UEFI驱动
2、不遵循UEFI驱动模型的驱动,包括类型:DXE_DRIVER、DXE_SAL_DRIVER、DXE_SMM_DRIVER、DXE_RUNTIME_DRIVER,称为DXE驱动
驱动

工程文件

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = UefiLib
  MODULE_UNI_FILE                = UefiLib.uni
  FILE_GUID                      = 3a004ba5-efe0-4a61-9f1a-267a46ae5ba9
  MODULE_TYPE                    = UEFI_DRIVER
  VERSION_STRING                 = 1.0
  LIBRARY_CLASS                  = UefiLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
  CONSTRUCTOR                    = UefiLibConstructor

参考:UEFI原理与编程《戴正华》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值