UEFI开发探索23 – File IO(文件读写)

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中给的参数一致,具体参考百度云中的代码吧。

原文地址:
http://yiiyee.cn/blog/2019/06/11/uefi%e5%bc%80%e5%8f%91%e6%8e%a2%e7%b4%a223-file-io%e6%96%87%e4%bb%b6%e8%af%bb%e5%86%99/

百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
代码在 15 FileIo 下。

126 total views, 1 views today

发表评论

电子邮件地址不会被公开。 必填项已用*标注