UEFI开发探索70- YIE001PCIe开发板(06 UEFI驱动)_luobing4365的博客-程序员秘密

技术标签: UEFI开发  底层应用开发  UEFI  BIOS  UEFI驱动  EDK2  

(请保留-> 作者: 罗冰   https://blog.csdn.net/luobing4365)

前两篇中,我们了解了UEFI驱动模型的基本架构。 在此基础上,本篇将以一个有趣的UEFI驱动GopRotate,配合自己编写的测试用UEFI应用TestGopRotate,演示UEFI驱动的运行和测试过程。

1 UEFI驱动GopRotate

此示例由apop2提供,源码仓库为https://github.com/apop2/GopRotate。工程GopRotate包含5个源文件:ComponentName.c、GopRotate.c、GopRotate.h、GopRotateBlt.c和GopRotate.inf。这几个文件的作用分别如下:

1) ComponentName.c。实现了EFI_COMPONENT_NAME_PROTOCOL的接口函数,提供UEFI驱动的名称;
2)GopRotate.c。实现EFI_DRIVER_BINDING_PROTOCOL及其接口函数,安装EFI_DRIVER_BINDING_PROTOCOL和EFI_COMPONENT_NAME_PROTOCOL,以及实现UEFI Shell界面旋转功能的Protocol;
3) GopRotate.h。定义了驱动所需数据结构以及Protocol接口函数原型;
4) GopRotateBlt.c。实现UEFI Shell界面旋转的函数,以及提供此功能的Protocol接口函数的实现;
5) GopRotate.inf,编译UEFI驱动的INF文件。

为实现UEFI Shell界面的旋转,示例工程GopRotate主要做了以下工作:

  • 找到安装了EFI_GRAPHICS_OUTPUT_PROTOCOL的控制器,并且不能是虚拟设备;
  • 对EFI_GRAPHICS_OUTPUT_PROTOCOL的Blt()接口函数进行替换,更换为GopRotate中实现旋转显示的函数BltRotate();
  • Shell界面旋转多少度,由内部私有结构体的成员变量Rotation决定。实现控制此变量的GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL,此Protocol提供了两个接口函数,用来获取Rotation值和设置Rotation的值。

示例工程GopRotate的私有结构体如示例1所示。

【示例1】GopRotate的私有结构体

typedef struct
{
  UINTN                                       Signature;  //私有数据结构体签名
  EFI_HANDLE                                  Handle;     //管理设备的句柄
  EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT            Blt;    //原始的Blt()接口函数   
  EFI_GRAPHICS_OUTPUT_PROTOCOL                *Gop;   //Gop实例     
  GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL GopRotate;//用户使用的Protocol
  ROTATE_SCREEN                               Rotation;    //控制屏幕旋转角度
} GRAPHICS_OUTPUT_ROTATE_PRIVATE;
typedef enum
{
    Rotate0 = 0,     //不旋转
    Rotate90 = 1,    //旋转90度
    Rotate180 = 2,   //旋转180度
    Rotate270 = 3,   //旋转270度
    RotateMax = 4
} ROTATE_SCREEN;

GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL用来设置和获取屏幕旋转的角度,它提供了两个接口函数,如示例2所示。

【示例2GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL函数接口

typedef struct _GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL \
GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL;
struct _GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL
{
  GRAPHICS_OUTPUT_PROTOCOL_ROTATE_GET_ROTATION GetRotation; //获取旋转角度
  GRAPHICS_OUTPUT_PROTOCOL_ROTATE_SET_ROTATION SetRotation; //设置旋转角度
};
typedef EFI_STATUS (EFIAPI *GRAPHICS_OUTPUT_PROTOCOL_ROTATE_GET_ROTATION)(
  IN  GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL  *This, //Protocol实例
  IN  ROTATE_SCREEN                             *Rotation   //旋转的角度
  );
typedef EFI_STATUS (EFIAPI *GRAPHICS_OUTPUT_PROTOCOL_ROTATE_SET_ROTATION)(
  IN  GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL  *This, //Protocol实例
  IN  ROTATE_SCREEN                             Rotation    //旋转的角度
  );

为了实现旋转UEFI Shell界面的功能,示例工程GopRotate中实现了大量的代码,这些代码主要是围绕私有结构体GRAPHICS_OUTPUT_ROTATE_PRIVATE来构建逻辑的。核心逻辑有两处:一是替换原有Blt()函数,使得其他UEFI应用或驱动在调用Blt()接口时,实际上是调用了我们准备的函数BltRotate();二是根据用户指定的旋转角度,实现UEFI Shell界面的转换显示,此功能主要由BltRotate()函数实现。

替换接口函数Blt()的操作,在驱动的Start()函数中实现,代码就不贴出来了。

经过Start()函数的操作后,当用户调用Blt()接口函数时,实际上调用的是BltRotate()函数。在BltRotate()函数中,调用了PerformTranslations()函数,它针对不同的旋转角度,对显示进行了处理。

在GopRotate的代码中,能够清楚地看出处理逻辑,函数根据用户设定的旋转角度,对显示进行了变换处理。完成了上述两个核心逻辑后,实现设置旋转角度和获取旋转角度两个接口函数,以及其他管理驱动的代码就可以了。这些编写过程,与框架驱动BlankDrv的编写过程很类似,并不难理解,直接查看代码很容易明白。

2 UEFI应用TestGopRotate

GopRotate提供了GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL,以及此Protocol的两个接口函数,供用户设定UEFI Shell界面旋转的角度,以及获取旋转的角度。为了测试GopRotate,我编写了应用程序TestGopRotate,可通过命令行指定旋转的角度,源代码地址在文末提供。

TestGopRotate可以读取当前设定的旋转角度,设定旋转角度是通过不同的命令行参数来实现的,其用法如示例3所示。

【示例3】TestGopRotate的用法

FS0:\> TestGopRotate   //不带参数,获取当前旋转角度
Rotate90                 //旋转90度
FS0:\> TestGopRotate 3//可选择参数0,1,2,3,分别表示旋转0度,90度,180度和270度

代码的编写方法,与67篇示例工程TestServiceDrv的编写方法类似。将需要访问的Protocol的头文件GopRotate.h拷贝到TestGopRotate的文件夹下,编写访问Protocol及接口函数的代码就可以了。代码的核心部分如示例4所示。

【示例4】设置旋转的角度

EFI_STATUS      Status; 
GRAPHICS_OUTPUT_PROTOCOL_ROTATE_PROTOCOL *GopRotate = NULL;
  …… //代码略
Status=gBS->LocateProtocol(&gGraphicsOutputProtocolRotateProtocolGuid,
NULL, (VOID **)&GopRotate);//获取Protocol实例
  …… //代码略
if(Argc == 2) 
{
    switch(Argv[1][0])
    {
      case ‘0’:    
        GopRotate->SetRotation(GopRotate, Rotate0); //不旋转
        break;
      case ‘1’:
        GopRotate->SetRotation(GopRotate, Rotate90); //旋转90度
        break;
      case ‘2’:
        GopRotate->SetRotation(GopRotate, Rotate180); //旋转180度
        break;
      case ‘3’:
        GopRotate->SetRotation(GopRotate, Rotate270); //旋转270度
        break;
      default:
        break;
   }
}
return EFI_SUCCESS;

3 测试

编译这两个示例的方法,和前几篇中的方法是一样的。

编译驱动:

C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc \
-m RobinPkg\Drivers\GopRotate\GopRotate.inf -a IA32

编译UEFI应用:

C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc \
-m RobinPkg\Applications\TestGopRotate\TestGopRotate.inf -a IA32

运行效果:

图1 测试GopRotate

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目代码位于:/FF RobinPkg/ RobinPkg /Applications/TestGopRotate
              /FF RobinPkg/ RobinPkg /Drivers/GopRotate

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luobing4365/article/details/112740167

智能推荐

awk初学_chengxuefei_bj的博客-程序员秘密

[[email protected] dsg]# more 2.txtcurrentProfile = {"urls":"false","skin":"skin-color-green","HAOTOPLIST_NEW":"top2_topmsg","navigate":"0"},[[email protected] dsg]# [[email protected] dsg]# more 2.txt

LiteOS内核源码分析:静态内存Static Memory_华为云开发者联盟的博客-程序员秘密

摘要:本文带领大家一起剖析了LiteOS静态内存模块的源代码,包含静态内存的结构体、静态内存池初始化、静态内存申请、释放、清除内容等。

jquery获取不到checkbox,checkbox的checked属性没用_qq_39082099的博客-程序员秘密

本来直接用$(this).attr(“checked”)是能返回值true/false。可是却来了个undefined看元素才知道checkbox没有添加checked属性,可是已经选中了啊看到https://blog.csdn.net/brucecheng22/article/details/50408199这个帖子才知道。用prop才能解决。$(this).prop(“checked”...

(ZJU-2007复试)-HDOJ-1860-统计字符_lovelyloulou的博客-程序员秘密

统计字符Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2532    Accepted Submission(s): 1564Problem Description统计一个给定字符串中指定的字符出现的次数 In

Rsa 签名前置处理器_Radioman-lhq的博客-程序员秘密

一.Rsa 签名前置处理器截图:二.Rsa 签名前置处理器使用说明:私钥:RSA加密私钥字符串;明文:需要签名的文本内容;签名算法:MD5、SHA-1、SHA-256、SHA-512,默认为MD5;目标变量名:如上图会将RSA签名结果存放到sign变量中,使用时,以${sign}这种形式引用即可。三.示例需求:对字符串aaaa进行RSA签名,私钥为:MIICdQIBADANBgkq...

用户管理命令useradd等的深入理解及手动创建用户_Wentasy的博客-程序员秘密

当然本文只是对理解useradd命令所做的实验,生产环境中肯定不会这样操作。其实学习的过程中使用这种方式可以让你理解命令的背后到底做了什么。

随便推点

XML DOM nextSibling 属性_cerq214的博客-程序员秘密

nextSibling 属性可返回某个元素之后紧跟的元素(处于同一树层级中)。如果无此节点,则属性返回 null。语法:  nodeObject.nextSibling NodeTypes - 有名常数NodeTypeNamed Constant1ELEMENT_NODE2ATT

利用公网IP访问部署在阿里云服务器的spring boot项目(二)_轩轩馒头铺的博客-程序员秘密

前提是有了阿里云服务器和spring boot项目,详情见: 利用公网IP访问部署在阿里云服务器的spring boot项目(一).打包环境选择自己的计算机随便一个盘(比如G:\,选择哪一个都无所谓),把当时在自己计算机部署环境的时候用的东西打包,如下:获取.jar文件JAR 文件非常类似 ZIP 文件——准确的说,它就是 ZIP 文件,所以叫它文件包,所以就是要把我们的项目打包成一个文件(毕竟一个项目是很大的):成功以后,在target下面会有两个新的文件,把他们也放到G:盘下面,待会儿一起

java web实现手机短信验证码登录实例_XXX美琳的博客-程序员秘密

运行环境jdk7+tomcat7项目技术(必填)Servlet+Ajax+Bootstrap数据库文件我这里没用到数据库,比较简单,如果需要用到数据库不会的话可以私信我或者加我QQjar包文件jar包只有一个,在项目的lib文件夹下运行截图项目描述这个小案例呢大家可以在项目中小小的装个逼,本人在校生,反正在项目答辩的时候,看大家的反应还不错,哈哈。本次案例呢大家不仅可以在登录的时候使用,另外注册的时候也可以用,大家自行决定,反正我在注册的时候用了,这次的案例没

网络编程指南_jickding的博客-程序员秘密

Beej's 网络编程指南 Internet SocketsVersion 1.5.5 (13-Jan-1999)[http://www.ecst.csuchico.edu/~beej/guide/net]原著:Brian "Beej" Hall翻译:Wilbur Lang介绍Hey! Socket 编程让你沮丧吗?从 man pages 中很难得到有用的信息吗?你

platform驱动模型一_weixin_30938149的博客-程序员秘密

主要参考:http://blog.chinaunix.net/uid-26285146-id-3307147.htmlhttp://blog.chinaunix.net/uid-26285146-id-3307147.html重要的结构体<1>struct device <linux/device.h>//用于描述设备相关的信息设备之间的...

mql查询_乐之巽的博客-程序员秘密

一、内连接查询只连接匹配的行,即A表与B表相连接,能够匹配的记录查询出来等值连接 例:查询员工的名称和员工所对应的部门名称 select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno;非等值连接 例:查询员工的工资等级 select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and

推荐文章

热门文章

相关标签