(请保留-> 作者: 罗冰 luobing4365的博客_CSDN博客-UEFI开发,汇编语言探索,嵌入式开发领域博主)
Option ROM的开发中,很少用到文件读写。因此,在最早开发的过程中,我没有仔细研究过文件处理相关的Protocol。
倒是在编写显示图片例程的时候,涉及到了一些。我直接使用了UDK中的例子,改造了显示BMP的函数,函数内部封装了文件读取。
接下来我准备用几篇博客,演示如何显示图片。UEFI画图的程序,在之前的博客中已经讨论演示过了。下面需要做的,是解析图像格式,解压数据,并通过画图函数将其显示在屏幕上。
预备要处理的图像格式包括BMP、PCX,有时间的话研究下Jpeg。
当然,首先还得搞清楚UEFI下怎么进行文件读写。
1 UEFI对文件系统的支持
UEFI相比于Legacy BIOS而言,除了提供对硬盘访问的支持,还对文件系统进行了支持。主要是对FAT格式的支持。
这实在是件好事。我在开发Foxdisk的过程中,打交道最多的就是硬盘访问,大部分时间在调试的,除了图像,就是硬盘访问。
而且在Foxdisk中,使用的是int 13h的扩展功能对磁盘访问,只能使用C嵌汇编的形式来编写。我是借鉴了linux下硬盘驱动的设计,但也得小心各种硬盘的参数,特别是在虚拟机下调试时,磁头、磁柱完全不是常规的。
Foxdisk中也实现了对硬盘分区以及格式化功能,对Fat32格式提供了有限的支持。代码编写的时候,纠缠在各种细节上,那滋味…一言难尽。UEFI很好的解决了这些问题,可以花更多的时间来思考,用UEFI去干点什么了。
(UEFI下文件访问,我主要参考UEFI Spec和《UEFI原理与编程》)
如图1,展示了文件系统构建的各级栈的结构。各层不断的屏蔽硬盘读写的细节,最终构建出对文件系统访问的Protocol。
图1 文件系统Protocol的栈结构
其他层的Protocol暂时不用关注,需要的时候再去研究。目前主要关注FileSystemIo这层,它提供了完整的文件访问的能力。
UEFI中访问文件与两个Protocol有关,EFI_SIMPLE_FILE_SYSTEM_PROTOCOL和EFI_FILE_PROTOCOL。如图:
图2 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL (UEFI Spec 2.8 Page 504)
图3 EFI_FILE_PROTOCOL (UEFI Spec 2.8 Page 507)
在UEFI Spec中,为EFI_SIMPLE_FILE_SYSTEM_PROTOCOL提供了GUID,可以通过LocateProtocol等函数找到其实例。而EFI_FILE_PROTOCOL的实例不是由GUID来定位的,而是通过EFI_SIMPLE_FILE_SYSTEM_PROTOCOL的函数OpenVolume获取的。
2 编程
UEFI提供的文件访问比较简洁,分为同步访问和异步访问。我在实现的时候,只实现了同步访问的代码,异步访问的代码(带有“Ex”字样的函数,如OpenEx)可以参照书中的例子改造。
需要注意的是,在程序访问文件的时候,有“文件读写位置”的概念。每次读写,读写位置会根据读写情况自动更新。我开始的时候就犯了这个错,对文件写入数据后,直接去读,一直读出来的数据都是0个。当把读写位置定位到文件开始,才把需要的数据读出来了。
图4 函数编写
根据需要,我编写了几个访问函数,包括打开文件、读文件、写文件、设置读写位置和获取读写位置。
3 编译运行
程序读取readme.txt,并向其中写入数据,再读出来。
运行效果如下:
图5 运行效果
在编写的过程中,需要注意各种函数参数中的指针,最好与Spec中给的参数一致,具体参考百度云中的代码吧。
Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目代码位于:/15 FileIo 下。