UEFI开发探索34 – Option ROM前传1

下面开始进入系列博客的主线-Option ROM的开发。

我预备用3篇将这个问题说清楚。包括Legacy BIOS下的Oprom,以及如何搭建UEFI下Oprom,包含为了开发Oprom我所自制的几个工具。

我曾经有很长一段时间与Legacy BIOS的Option ROM打交道,在没有示例程序、没有人指点的情况下,苦苦探索,痛苦而又充实。

一切都从这个文档开始:

图1 pnp bios spec

1 起源

刚毕业两年左右,公司计划开发一款物理隔离的主板。我们总工只有板卡类的开发经验,从来没有开发过这么复杂的产品,而且产品目标之一是修改ACPI的流程,一群人都没有相关经验,大眼瞪小眼。

硬件的工作暂时不论,软件都是由我负责。大概包括:

1) 作为协议中心的MCU固件代码,提供windows App与板块的通信通道,提供PCI Option ROM与板块的通信通道;
2) windows App,提供操作系统层的用户使用接口;
3) PCI Option ROM,提供底层的用户使用接口。

再深入讨论的结果,不能使用PCI Option ROM,因为需要增加一个近20块钱的WCH365,而且发现驱动代码不稳定。

最终只能考虑将Option ROM嵌入到BIOS中,同时用一款Cypress的芯片同时打通两个通信通道。

就这样,完全不具备相关知识(当时汇编语言也没学)的我,一头扎入了这个巨大无比的问题旋涡,一点点攻克路上遇到的各种问题,直到奇迹般地做出了第一个打印“Hello,world!”的Oprom。

2 探索和思考

我翻遍了南京的大小图书馆,以及我能找到的一切参考书。最终在母校图书馆的一本计算机杂志上看到,可以通过Cbrom.exe把BIOS文件提取出来。

我如获至宝,把那篇文章读了又读。而后在网络上找到一款名为bfdisk的工具,在介绍此工具的文章中,有这么一句话(图中标红处):

图2 嵌入到BIOS中的分区工具

就是这句话,让我找到了如何编写Oprom格式的依据。

当然,即便知道格式,也有非常多的问题需要解决。比如用汇编写代码、转换编译后的文件为ROM文件、图像编程的知识、各种外设访问的方法等等。

这个UEFI探索博客,其实与我当年做的事情是类似的,只是我现在知识比当时丰富得多,能很快进入UEFI的各种开发。

我像疯了一样拼命吸收新知识,那种灵魂燃烧的感觉现在都记忆犹新。真希望能一生都保持对新知识的渴望。

3 Option ROM格式

所谓Option ROM就是在位于PCI或者ISA设备上的只读存储器,因为这个存储器不是总线标准规定一定要实现的,所以叫Option ROM(可选实现的ROM)。

Option ROM里面通常存放着用于初始化该设备的数据和代码。显卡和网卡等设备上通常带有Option ROM。简单来说,在它的开始处,总是一个固定结构的头结构,称为PnP Option ROM Header。

在头结构的偏移18h和1Ah处可以指向另外两个结构,分别称为PCI数据结构和PnP扩展头结构(PnP Expansion Header),简称为PEH。PEH中有一个起到链表作用的Next字段(偏移06h,长度为WORD)用来描述下一个扩展结构的偏移。如图:

图3 Option ROM 头结构

ISA ROM结构不需要完全按照以上的结构来编写。其中要注意的有两点:

1) 偏移2h处填写Option ROM的长度,其以2k为一个单位。即如果整个ROM代码为20k的话,填写0ah即可。
2) 整个ROM代码必须校验和为0。即从ROM的第一个字节直至最后一个字节,这些字节相加后的和必须为0。

如果BIOS检测到ROM代码符合pnp BIOS的规范,将使用FAR CALL调用偏移3h处的入口向量,控制权将转交给Oprion ROM代码。当然,为了正常将控制权返回给BIOS,在Option ROM代码的最后必须使用RETF,将控制权交出。

4 代码结构

了解到Option ROM的结构后,就可以进行编程了。需要注意,Option ROM在运行的时候,只能调用BIOS的中断。

考虑到结构的控制,以及库的链接问题和文件大小,最好使用汇编语言进行编写。使用汇编编译器将其编译成执行文件,并使用工具转换为符合要求的BIN文件。

典型的程序结构如下:

.MODEL TINY                                                   
.486
.CODE
ORG 0H
START:
DW 0AA55h                 ;扩展BIOS标志
DB 40h  
Call Main                  ;Main为主程序入口
Retf                        ;控制权返回给BIOS

在Main函数中实现所需要的功能即可。

编译器使用MASM6.11,采用上述 ISA ROM模块的代码,并用Link /T链接obj文件,生成COM文件。然后按照PNP BIOS的要求,编写COM文件转换为字节校验和为0的BIN文件的工具程序,使用此工具程序将COM文件转换为BIN 文件。

之后,将bin文件嵌入到BIOS中,就完成了Option ROM的开发过程。

(待续…)

6,082 total views, 6 views today

发表评论

电子邮件地址不会被公开。