它也会创建一个同名的sg device挂在自定义的”scsi_generic” class上(没有什么特别作用) 。
sg作用:
- Sg存在的唯一目的 , 是使用ioctl命令 , 例如rpmb的操作 , FFU固件升级等操作 , 都是通过ioctl方式完成 。
- 由于无论sg还是sd , 还是别的什么scsi外设驱动创建出来用户态设备节点 , 最终都是通过lun对应的request_queue来完成发送scsi命令 , 所以sg能做的事情 , 其它节点也能做 , 因此有的平台没有打开sg编译开关 。

文章插图
四、数据链表结构硬件拓扑结构是一个树形 。在linuxscsi子系统里面 , host , target , lun对应的scsi_host, scsi_target, scsi_device也是一个树形链表结构 , 如下图:
Linux scsi子系统中的所有list链表操作都是按照这张图中的数据结构处理的 。

文章插图
scsi.c代码很多是围绕这个结构体进行操作的 , 例如:
shost_for_each_device
starget_for_each_device
scsi_device_lookup_by_target
scsi_device_lookup
__scsi_iterate_devices
具体实现 , 大家可以自己研究 , 对照这张图 , 代码看起来不会很难 。
五、总结:
- Linux中复杂的驱动子系统的设计基本类似与scsi子系统 , 先有一个物理设备拓补模型 , 再设计对应的软件驱动模型 。
- 有时为了软件操作有条理 , 或者为了软件方便扩展 , 也或者为了代码解耦 , 可以把物理设备拓补模型进行虚拟扩展 。例如:1上述虚拟出的target设备. 2 pcie也会把抽象的bus信号线虚拟出一个pci_bus class设备等等 。目的就是软件上采用分级驱动形式 , 把复杂的操作简化 。
- 设备模型建好后 , 再实现设备扫描和PM相关的功能 , 各层驱动负责各层操作 , 尽量不越界操作 , 减少代码耦合 。例如sd.c不关心device是怎么放到scsi总线上来的(这个device可能是某个pcie插槽接的板卡 , 板卡再外接的一个外设;也可能是soc ufs控制器上的外设)sd.c驱动只管基于scsi command做好自己分内的操作就可以兼容这些设备 。
- 外部硬件的连接方式像搭积木 , 分级驱动也可以以最小代价像积木一样应对硬
推荐阅读
- linux之间传文件命令之Rsync傻瓜式教程
- 微软提交补丁,用Linux替代Hyper-V根分区的Win
- 借助 HTTP 通过 SSH 绕过 Linux 防火墙
- Linux或者Mac下命令行speedtest测试网络速度
- 硬盘有必要分区吗?MacOS、Linux都不分区
- linux中ELF格式二进制程序
- 利用这个 USB ID 仓库识别更多 Linux 上的设备
- Linux内核虚拟内存管理之匿名映射缺页异常分析
- 在Linux中使用Bashtop与Bpytop监管系统资源
- Linux驱动-互斥锁用法,建议先保存
