EFI Driver Model(下)-SCSI 驱动设计

1、SCSI简介

  SCSI是Small Computer System Interface(小型计算机系统接口)的缩写,使用50针接口,外观和普通硬盘接口有些相似。SCSI硬盘和普通IDE硬盘相比有很多优点:接口速度快,并且由于主要用于服务器,因此硬盘本身的性能也比较高,硬盘转速快,缓存容量大,CPU占用率低,扩展性远优于IDE硬盘,并且支持热插拔。

2、SCSI驱动设计

  在EFI Driver Model中,UEFI驱动程序是重要的组成部分,它们与UEFI应用程序有所区别。对于UEFI驱动程序来说,EFI System Table、Memory、Handles、Images和Events等对象的管理至关重要。在初始化驱动程序时,有些驱动程序可能不会产生任何Handle,也不会向Handle Database增加任何Protocol,它们主要进行初始化操作,并在执行完毕后从系统内存中卸载。

  具体到SCSI驱动设计,它在Linux系统中通常被划分为三个层次:top level、middle level和lower level。Top level为具体的scsi设备驱动,例如常用的磁盘设备驱动。这些驱动与具体的scsi设备相关,因此通常由设备开发者提供。对于标准类设备,驱动可以通用。Middle level实际上是scsi总线层驱动,它负责按照scsi协议进行设备枚举、数据传输和出错处理。而在lower level层,驱动可能并不直接对硬件进行操作,例如可以做虚拟的scsi host。

  在SCSI驱动设计中,scsi_driver结构体和scsi磁盘驱动实例(如sd_template,定义在文件drivers/scsi/sd.c)是关键部分。PCI子系统和SCSI子系统的工作模式也是设计过程中需要考虑的重要因素。PCI子系统会注册PCI总线类型,扫描PCI总线以获取所有PCI设备。而SCSI子系统则注册SCSI总线类型,其较高层注册SCSI设备驱动,较低层(如SCSI HBA驱动)负责扫描SCSI总线以获取所有SCSI设备。

  总的来说,EFI Driver Model下的SCSI驱动设计是一个复杂而精细的过程,需要考虑到各种设备、总线和协议的特性,以确保驱动的稳定性和高效性。对于开发者来说,深入理解EFI Driver Model以及SCSI的工作原理是设计高质量驱动的基础。

驱动类别描述
SCSI host controllerConsumes PCI I/O Protocol on the SCSI host controller handle and produces the Ext SCSI Pass Thru Protocol,如果需要一个驱动程序与EFI 1.10规范兼容,则必须生成SCSI通过协议。
SCSI bus driverConsumes the Ext SCSI Pass Thru Protocol and produces a child handle for SCSI targets on the SCSI bus. Installs the Device Path Protocol and SCSI I/O Protocol onto each child handle.
SCSI 设备驱动使用SCSI I/O协议,并生成一个I/O抽象,它为启动符合EFI的操作系统所需的控制台设备和引导设备提供服务。

   EFI 1.10规范定义了SCSIPass Thru Protocol.用于SCSI host controller的UEFI驱动程序被需要符合EFI 1.10规范的平台上正常工作,生成SCSI通过协议,并为SCSI host controller管理的物理驱动器和逻辑驱动器生成BLOCK I/O协议。这意味着需要一个用于EFI 1.10平台中的SCSI主机控制器的UEFI Driver来执行上表中描述的SCSI驱动程序堆栈的所有功能。UEFI 2.0及以上规范要求平台固件为大容量存储设备提供SCSI总线驱动程序和SCSI设备驱动程序。

2.1 SCSI Host Controller Driver

  SCSI主机控制器驱动程序管理包含一个或多个SCSI通道的SCSI主机控制器,它为每个SCSI通道创建句柄,并安装扩展的SCSI Pass Thru Protocol和Device Path Protocol到每一个驱动产生的handle上。有关EFI_EXT_SCSI_PASS_THRU_PROTOCOL的详细信息,请参阅UEFI规范中的SCSI驱动程序模型和总线支持章节。

struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL {////// A pointer to the EFI_EXT_SCSI_PASS_THRU_MODE data for this SCSI channel.///EFI_EXT_SCSI_PASS_THRU_MODE                *Mode;EFI_EXT_SCSI_PASS_THRU_PASSTHRU            PassThru;EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN GetNextTargetLun;EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH   BuildDevicePath;EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN      GetTargetLun;EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL       ResetChannel;EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN    ResetTargetLun;EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET     GetNextTarget;
};

  一个SCSI主机控制器驱动程序遵循UEFI驱动程序模型。根据其管理的适配器,SCSI主机控制器驱动程序可以被归类为设备驱动程序或混合驱动程序。它为每个SCSI通道创建子句柄(如果有多个1),它还可以在自己的句柄上安装协议。通常,SCSI主机控制器驱动器是特定于芯片的,因为需要初始化和管理当前绑定的SCSI主机控制器。

  由于在一个平台中可能存在多个可能由一个SCSI主机控制器驱动程序管理的SCSI主机适配器,因此建议将SCSI主机控制器驱动程序设计为重新进入,并为每个SCSI主机控制器分配不同的私有上下文数据结构。

2.2 Single-Channel SCSI Adapters

如果SCSI适配器支持一个通道,则SCSI主机控制器驱动程序将执行以下操作:

  • 将扩展的SCSI Pass Thru Protocol安装到控制器句柄上的SCSI host controller的controller handle上。
  • 在模式结构中设置SCSI通道的逻辑属性。
  • 在模式结构中设置SCSI通道的物理属性

  下图显示了一个在单通道SCSI适配器上的实现示例。绿色的图层表示SCSI主机控制器驱动程序。
在这里插入图片描述
  因为只有一个SCSI通道,所以SCSI驱动程序可以简单地实现扩展SCSI通过协议的一个实例。平台固件提供了SCSI总线驱动程序和SCSI磁盘驱动程序,它们通过执行以下操作来完成驱动程序堆栈:

  • 扫描SCSI通道上的SCSI目标并创建子句柄。
  • 向每个子句柄安装设备路径协议
  • 向每个子句柄上安装SCSI I/O协议
  • 向每个子句柄安装I/O抽象,例如Block I/O协议

2.2 Multi-Channel SCSI Adapters

  如果SCSI适配器提供多个SCSI通道,则SCSI主机控制器驱动程序会更加复杂。下图显示了在双通道SCSI适配器上可能实现的SCSI驱动程序实现。
在这里插入图片描述
  在这种情况下,SCSI适配器通过执行以下操作产生两个物理SCSI通道:

  • 为每个物理SCSI通道创建一个子句柄。
  • 向每个子句柄安装设备路径协议。
  • 在每个子句柄上安装扩展的SCSI传递协议
  • 在每个子句柄上的模式结构中设置SCSI通道的逻辑属性。
  • 在每个子句柄上的模式结构中设置SCSI通道的物理属性。

  平台固件提供了SCSI总线驱动程序和SCSI磁盘驱动程序,通过执行以下操作,可以完成上述每个扩展SCSI通过协议上的两个驱动程序堆栈:

  • 扫描每个SCSI通道上的SCSI目标,并创建子句柄。
  • 向每个子句柄安装设备路径协议。
  • 向每个子句柄上安装SCSI I/O协议
  • 向每个子句柄安装I/O抽象,如Block I/O协议。

2.3 SCSI Adapters with RAID

  SCSI主机控制器驱动程序也可以支持具有RAID功能的SCSI适配器。下图显示了一个具有两个物理SCSI通道和一个逻辑通道的示例实现。这两个物理通道是在SCSI适配器上实现的,然后,RAID组件配置这两个通道,以生成一个逻辑SCSI通道。两个物理通道都安装了扩展SCSI通过通道,但除了用于诊断外,不使用这些通道。对于逻辑通道,SCSI主机控制器驱动程序根据RAID配置生成另一个扩展SCSI通过协议(关闭物理位)实例。发送到逻辑通道的扩展SCSI传递协议的请求由SCSI主机控制器驱动程序处理,并转换为物理SCSI通道上的请求,平台固件必须只枚举并从逻辑SCSI通道上存在的SCSI目标启动。
在这里插入图片描述
  在实现RAID时,SCSI适配器硬件可能无法将物理SCSI通道)暴露给上层软件。如果物理SCSI通道不能暴露于上层软件,则SCSI主机控制器驱动程序只需要为RAID生成单个逻辑通道。
  虽然基本理论与物理通道上的理论相同,但从制造和诊断的角度是不同的。如果物理SCSI通道暴露,任何SCSI命令,包括诊断命令,都可以发送到单个通道,这对生产线非常有帮助。此外,可以使用扩展SCSI传递协议支持的非阻塞模式同时将诊断命令发送到所有物理通道。诊断过程可能会从性能的增益中显著获益。总之,建议尽可能公开物理SCSI通道。
  当然,有许多可能的设计来实现SCSI RAID功能。关键是,SCSI主机控制器驱动程序可以为各种SCSI适配器类型设计和实现,并且这些SCSI主机控制器驱动程序可以生成包含可作为UEFI引导设备使用的SCSI目标的扩展SCSI通过协议。

3、源码分析

ScsiDiskDriverBindingSupported 用于检测该SCSI磁盘驱动程序是否支持特定的控制器设备

EFI_STATUS
EFIAPI
ScsiDiskDriverBindingSupported (IN EFI_DRIVER_BINDING_PROTOCOL  *This,IN EFI_HANDLE                   Controller,IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath   OPTIONAL);

ScsiDiskDriverBindingStart 这个函数是用来启动指定的驱动程序并将其绑定到指定的ControllerHandle上的。它是EFI_DRIVER_BINDING_PROTOCOL协议的一部分,是UEFI(统一可扩展固件接口)引导过程中重要的一环,用于初始化和启动设备驱动程序。

EFI_STATUS
EFIAPI
ScsiDiskDriverBindingStart (IN EFI_DRIVER_BINDING_PROTOCOL  *This,IN EFI_HANDLE                   Controller,IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath   OPTIONAL);

ScsiDiskDriverBindingStop 用于停止指定控制器上的驱动程序。这个函数属于EFI_DRIVER_BINDING_PROTOCOL协议,该协议定义了驱动程序如何绑定到控制器、启动和停止服务。

EFI_STATUS
EFIAPI
ScsiDiskDriverBindingStop (IN  EFI_DRIVER_BINDING_PROTOCOL  *This,IN  EFI_HANDLE                   Controller,IN  UINTN                        NumberOfChildren,IN  EFI_HANDLE                   *ChildHandleBuffer   OPTIONAL);

ScsiIo使用

 Status = gBS->OpenProtocol (Controller,&gEfiScsiIoProtocolGuid,(VOID **)&ScsiIo,This->DriverBindingHandle,Controller,EFI_OPEN_PROTOCOL_BY_DRIVER);if (EFI_ERROR (Status)) {FreePool (ScsiDiskDevice);return Status;}ScsiDiskDevice->Signature                         = SCSI_DISK_DEV_SIGNATURE;ScsiDiskDevice->ScsiIo                            = ScsiIo;ScsiDiskDevice->BlkIo.Revision                    = EFI_BLOCK_IO_PROTOCOL_REVISION3;ScsiDiskDevice->BlkIo.Media                       = &ScsiDiskDevice->BlkIoMedia;ScsiDiskDevice->BlkIo.Media->IoAlign              = ScsiIo->IoAlign;ScsiDiskDevice->BlkIo.Reset                       = ScsiDiskReset;ScsiDiskDevice->BlkIo.ReadBlocks                  = ScsiDiskReadBlocks;ScsiDiskDevice->BlkIo.WriteBlocks                 = ScsiDiskWriteBlocks;ScsiDiskDevice->BlkIo.FlushBlocks                 = ScsiDiskFlushBlocks;ScsiDiskDevice->BlkIo2.Media                      = &ScsiDiskDevice->BlkIoMedia;ScsiDiskDevice->BlkIo2.Reset                      = ScsiDiskResetEx;ScsiDiskDevice->BlkIo2.ReadBlocksEx               = ScsiDiskReadBlocksEx;ScsiDiskDevice->BlkIo2.WriteBlocksEx              = ScsiDiskWriteBlocksEx;ScsiDiskDevice->BlkIo2.FlushBlocksEx              = ScsiDiskFlushBlocksEx;ScsiDiskDevice->StorageSecurity.ReceiveData       = ScsiDiskReceiveData;ScsiDiskDevice->StorageSecurity.SendData          = ScsiDiskSendData;ScsiDiskDevice->EraseBlock.Revision               = EFI_ERASE_BLOCK_PROTOCOL_REVISION;ScsiDiskDevice->EraseBlock.EraseLengthGranularity = 1;ScsiDiskDevice->EraseBlock.EraseBlocks            = ScsiDiskEraseBlocks;ScsiDiskDevice->UnmapInfo.MaxBlkDespCnt           = 1;ScsiDiskDevice->BlockLimitsVpdSupported           = FALSE;ScsiDiskDevice->Handle                            = Controller;Status = gBS->InstallMultipleProtocolInterfaces (&Controller,&gEfiBlockIoProtocolGuid,&ScsiDiskDevice->BlkIo,&gEfiBlockIo2ProtocolGuid,&ScsiDiskDevice->BlkIo2,&gEfiDiskInfoProtocolGuid,&ScsiDiskDevice->DiskInfo,NULL);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/572418.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通往荣耀之路! 在 The Sandbox 中种植树木,拯救真正的森林

The Sandbox 团队祝你国际森林日快乐! 我们相信,在创造一个更美好、更包容、更友善的地球的过程中,我们每个人都有责任采取具有影响力和目的性的行动。这就是为什么我们平台的核心支柱是利用元宇宙来推动公益事业。 国际森林日是我们践行这一…

数据分析之POWER Piovt透视表分析与KPI设置

将几个数据表之间进行关联 生成数据透视表 超级透视表这里的字段包含子字段 这三个月份在前面的解决办法 1.选中这三个月份,鼠标可移动的时候移动到后面 2.在原数据进行修改 添加列获取月份,借助month的函数双击日期 选择月份这列----按列排序-----选择月…

2024年目前阿里云服务器一个月收费价格表多少钱?

阿里云服务器一个月多少钱?最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年,折合5元一个月,2核4G服务器30元3个月,2核2G3M带宽服务器99元12个月,轻量应用服务器2核4G4M带宽165元12个月,4核16G服务…

Django开发复盘

一、URL 对于一个不会写正则表达式的蒟蒻来说,在urls.py中就只能傻傻的写死名字,但是即便这样,还会有很多相对路径和绝对路径的问题(相对ip端口的路径),因为我们网页中涉及到页面跳转,涉及到发送…

机器学习复习手册

机器学习的要素 基本概念 泛化: The ability to predict accurately the target for new examples that differ from those used in the training set is known as generalization.监督学习:The training data comprises examples of the input variab…

python在运行时控制台以表格形式输出结果prettytable.PrettyTable()

使用prettytable库按表格的形式美化输出结果 效果如图: 表格中可接收列表格式的数据,列表中装字符串 # 引入模块 import prettytable as pt# 创建表格与表头,包含五列,分别为train-epoch,class,precisio…

【进程控制】超详细讲解wait和waitpid的原理(结合代码)

文章目录 前言waitpid函数参数option什么叫非阻塞等待?参数status wait 函数 前言 在了解了进程状态这一概念之后,我们明白了什么叫做僵尸进程:子进程退出,父进程“不管不顾”。而一旦存在僵尸进程,势必也会存在内存泄…

SpringBoot整合Redis:面试必考题-缓存击穿--逻辑过期解决

🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

如何解决Modbus转Profinet网关通信不稳定或数据丢失问题

接到现场反映,在配置Modbus转Profinet网关时,出现Modbus转Profinet网关(XD-MDPN100)通信不稳定或数据丢失的问题,就这个问题特做出答疑。 解决Modbus转Profinet网关(XD-MDPN100)通信不稳定或数据…

【Java.mysql】——数据删改(DU) 附加数据库约束

目录 🚩更新(Update) 🚩删除(Delete) 🚩数据库约束 🎈约束类型 ✅NULL约束 ✅NNIQUE 唯一约束 ✅DEFAULT:默认值约束 ✅PRIMARY KEY:主键约束 ✅FOREIGN KEY:外键…

python Flask扩展:如何查找高效开发的第三方模块(库/插件)

如何找到扩展以及使用扩展的文档 一、背景二、如何寻找框架的扩展?三、找到想要的扩展四、找到使用扩展的文档五、项目中实战扩展 一、背景 刚入门python的flask的框架,跟着文档学习了一些以后,想着其实在项目开发中,经常会用到发…

jenkins配置源码管理的git地址时,怎么使用不了 credential凭证信息

前提 Jenkins使用docker部署 问题 (在jenlins中设置凭证的方式)在Jenkins的任务重配置Git地址,并且设置了git凭证,但是验证不通过,报错; 无法连接仓库:Command "git ls-remote -h -- http://192.1XX.0.98:X02/…