宏电脑uefi无法启动不系统 (win7系统uefi启动不了)


固件C字营·版权所有

---------------------------------------------------------------------------------------------


同一个UEFI driver可能需要管理多个设备,对于每一个设备我们需要为其分配单独的私有的数据,所以我们不能奢望用全局的数据在不同的设备之间共享数据的通道,并且我们还需要保持设计的driver是可重入的。

每一个设备或者说是控制器我们需要为其分配独立的私有数据,这些数据主要包括:

? A signature for the data structure

? The handle of the controller or the child that is being managed or produced

? The group of protocol interfaces that are being consumed

? The group of protocol interfaces that are being produced

? Private data fields and services that are used to manage a specific controller

已知结构的成员变量的地址,如果要访问结构里其他的成员,我们需要先找到整个结构的基地址,我们使用一个CR()的宏来完成这一过程,这个类似于面向对象语言C++中的This 指针,但是由于UEFI是用C来写的,缺少了面向对象的特性,所以就用这种方法来模拟面向对象的特性。

该宏只需要提供结构体类型定义,结构中成员变量的指针,通过计算出成员变量与结构基地址的偏移量,因为结构成员的存放地址是从低地址开始存放(小端模式),把成员变量指针减持偏移量就得到结构的基地址,然后通过强制了类型转换,就能获取到结构内部的所有私有数据的指针,我们亦可以把得到的指针当做是This指针。之后我们就可以使用这个This指针来索引私有数据结构里面的所有的数据了。

以下是HDD控制器示例:

1.定义一个HDD的控制器的简单示范,他包含三个数据项:

a>定义该设备私有数据的signature。我们定义个signature,这个是在前面没有提到的,这里的主 要作用的对我们的私有数据做一个标签,以此来方便diagnosis工具或者其他的工具代码来校验这个私有数据结构是否是我们需要的哪一个。在CR宏定义中我们一般会加入对这个signature的校验,如果校验结果不符合,就可以抛出异常

b>定义该设备产生的protocol

c>定义该设备需要消费的protocol,一般使用指针来表示

2.最后的是一个通过driver生产的protocol的指针来获取私有数据的宏定义.

其中DiskIo protocol是由driver自己生产的,使用BS service的allocate pool服务来申请内存,让后把servicecopy到每一个需要安装driver的设备或者说是控制器上.以下是一个示例:

1.前面的部分是包含一些 必备的头文件,包括UEFI头文件,三个protocol的定义头文件以及一个memory库头文件

2.第二部分定义了,我们的私有数据的模板,我们要在这里实现数据的signature,DiskIoReadDisk以及DiskIoWriteDisk这两个函数的实现及其定义声明,最后用一个NULL来结束。同时我们需要注意这里的模板是一个全局的数据变量。

3.第三部分在driver的DriverBinding protocol的start方法中我们会去申请一块内存,并且把我们的上面生成的数据模板拷贝到申请的内存块中,最后判断是否成功,是否需要抛出异常。

同理在DriverBinding protocol里面的stop方法中,我们需要释放申请的内存和销毁我们为每个设备或者是控制器绑定的私有数据。细节看下面的示例:这里使用到了CR()从DiskIo protocol指针来索引私有数据指针,然后使用memory 服务释放内存。


本文主要探讨了UEFI 驱动模型的driver中私有数据及driver的protocol生产消费模型中各个protocol是如何与设备绑定,以及如何释放资源的,非UEFI驱动电脑模型的设备也需要参考这个模式来执行,以此来保证一致性及易于处理。

敬请关注微信公众号:“固件C字营”

敬请关注今日头条号:”固件C字营“


电脑