Cstyle的UEFI导读之Mass Storage Driver Stack

来源:互联网 发布:淘宝店美人药妆害死人 编辑:程序博客网 时间:2024/04/30 03:01
    聊完了各种存储设备接口之后咱们来看下Mass Storage,Mass Storage主要有硬盘,U盘,光盘等等,对应的我们就需要ATA driver,USB driver来完成对底层硬件的最基本的访问,但是仅仅是能访问硬件是远远不够的我们UEFI的最终目的是引导操作系统或者是我们还可以用来运行EFI shell,那么就需要使用到我们今天要提到的Mass Storage Driver Stack。
    通常来说我们只需要实现Block I/O Protocol/Block I/O 2 Protocol(支持non-blocking操作)就可以了,如果设备支持the SPC-4 /ATA8-ACS security commands的话那么我们还需要Storage Security Command Protocol,他们一起完成如下的工作(大概就是5个,读,写,block大小检测,容量检测,热插拔检测):
1.Read blocks of data from the mass storage device.
2.Write blocks of data to the mass storage device.
3. Determine the size of the blocks on the mass storage device.
4. Determine the total number of blocks on the mass storage device.
5.If the mass storage device supports removable media, then methods must exist to determine if media is present/ not present, and if the media has been changed.

Block I/O Protocol的实现:
它的实现在UDK里面有例子,以下是它要完成的任务:
1.Add global variable for the EFI_BLOCK_IO_PROTOCOL instance to BlockIo.c.
2.Add global variable for the EFI_BLOCK_IO2_PROTOCOL instance to BlockIo.c.
3.Add global variable for the EFI_BLOCK_IO_MODE structure to BlockIo.c.
4. Implement the Block I/O Protocol and Block I/O 2 Protocol services inBlockIo.c.


Block I/O Protocol的数据结构(Block.c):


Block I/O Protocol:Reset()
    reset外设,默认假设不需要特别等待外设reset完毕,如果参数ExtendedVerification ==TRUE,那么就可能需要等待设备reset完成。

Block I/O Protocol:ReadBlocks() /ReadBlocksEx()
    由以下的一系列步骤来完成:
1.检查设备是否存在。
2.如果侦测到media change event这通常包括设备移除或者重新插入,那么就需要使用BS的ReinstallProtocolInterface()服务重新install Block I/O Protocols。BlockSize不允许为0不管有没有外接设 
     备,如果没有侦测到设备就返回EFI_NO_MEDIA;如果设备改变了就返回EFI_MEDIA_CHANGED.
3.检查输入参数:主要是看看输入读取的地址和大小是否超过设备本身的大小和地址。
    • The Buffer, sized BufferSize, must be a whole number of blocks
    • The read does not start past the end of the media
    • The read does not extend past the end of the media
    • The Buffer is aligned as required
4.从设备读取指定的扇区,分两种情况,一个是阻塞的方式,一个是非阻塞的方式。后者需要有timer event去周期的侦测读操作是否完成,当完成后悔signal调用者去完成后续操作。
5.If needed, copy the appropriate portion of the buffer to a location visible to the mass storage device.

Block I/O Protocol:WriteBlocks()/WriteBlockEx()
    由以下的一系列步骤来完成:
1.检查设备是否存在。
2.如果侦测到media change event这通常包括设备移除或者重新插入,那么就需要使用BS的ReinstallProtocolInterface()服务重新install Block I/O Protocols。BlockSize不允许为0不管有没有外接设 
     备,如果没有侦测到设备就返回EFI_NO_MEDIA;如果设备改变了就返回EFI_MEDIA_CHANGED.
3.检查设备的私有数据结构Media structure的BlockSize字段,不允许为0不管有没有外接设备
4.检查输入参数
    • The Buffer, sized BufferSize, is a whole number of blocks.
    • The write does not start past the end of the media.
    • The write does not extend past the end of the media.
    • The Buffer is aligned as required.
5.If needed, copy the appropriate portion of the buffer to a location visible to the mass storage device.
6.把数据写入到扇区
7.把数据写入到指定的扇区,分两种情况,一个是阻塞的方式,一个是非阻塞的方式。后者需要有timer event去周期的侦测读操作是否完成,当完成后悔signal调用者去完成后续操作。
8.(Optional) Update the driver’s cache for better performance.

Block I/O Protocol:FlushBlocks()/FlushBlocksEx():
    这两个服务是用来确保所有的挂起写操作都能最终完成写入到存储设备的扇区上去。它可以作为侦查设备移除之前的操作的一部分来保证数据的完整性。同时当使用非阻塞的方式的时候我们也需要使用timer event来周期的侦测写完成,然后signal调用者。

EFI_STORAGE_SECURITY_COMMAND_PROTOCOL 的实现:
    只有设备支持SPC-4 or ATA8-ACS security commands的时候才需要,下面是简单示例,详细请参考UDK中的MdeModulePkg/Bus/Ata/AtaBusDxe

OK,大功告成,这部分就先到这里。

转载请注明出处Cstyle.z.zhou@gmail.com//http://blog.csdn.net/CStyle_0x007

原创粉丝点击