文章插图
- 实例:

文章插图

文章插图

文章插图
可以看到我本地电脑有
- 6个shost_gendev和6个shost_dev设备 , 对应着硬件上的6个host控制器 。
- 这6个控制器是sata控制器 , 并且都是一个同一个pcie外设扩展出来的 , 共享一个pcie设备带宽 。
- sata驱动创建了ata1-ata6无总线挂靠的虚拟设备,Sata驱动不是这里讨论的内容 。但是sata在扫描完port之后 , 对每个port通过下面的函数创建了硬件host对应的struct device:Pci_dev添加到pci_bus
---->ahci扫描port个数(这里有6个)之后为每个port在scsi内部申请对应的host的structdevice
ahci_init_one-->ahci_host_activate-->ata_host_register-->ata_scsi_add_hosts
-->scsi_host_alloc和scsi_add_host_with_dma
这里用到了两个scsi子系统重要的对外接入函数 。
(2) target
- 在scsi内部针对每个target创建了一个名字为“targetk:m:n”的device结构体 , 其中k是host编号 , m是channel编号 , n是id编号 。

文章插图

文章插图
- 这个targe device也被挂在到”scsi”bus总线上 。“scsi” bus的match函数(scsi_bus_match)不允许target不有driver , 所以目前只有一些attribute可以在用户空间使用 。

文章插图
(3) lun
- Scsi子系统针对每个lun创建了两个device对象 , 分别是sdev_gendev和sdev_dev 。

文章插图
- 它们的名字都是k:m:n:lunN , 其中k是host编号 , m是channel编号 , n是id编号 , lunN是lun编号 。例如

文章插图
- sdev_gendev挂在”scsi” bus上 , 它会触发bus驱动 , 驱动会通过sdev_gendev->type字段 , 来判断该device是否和自己匹配 。例如ufs , ssd的device会触发名为“sd”的驱动 。sd驱动会给匹配上的lun , 在用户空间创建对应的block设备节点 , 类似于sda , sdb这些(sda1,sda2是sda上GPT或者MBR搞出来的逻辑分区 , 不属于scsi内容) 。例如

文章插图
【Linux Scsi子系统框架介绍】

文章插图
- sdev_dev是挂在名为”scsi_device”的class上 , 用作它用 。其中比较重要的sg.c驱动 , 它在这个class上注册了interface(callback) , 当有device挂在这个class上时 , interface会被调用 , 从而间接的创建对应的char设备 。sg比较特殊 , 它会不加区分的给所有进来的lun创建一个对应的字符设备到用户空间 , 类似于sg0 , sg1 。

文章插图
(4) 公版驱动在”scsi”bus上挂着很多驱动:

文章插图
- 这些驱动都通过scsi_register_driver注册到”scsi” bus上 , 如果我们写一个自定义设备驱动 , 也可以这样放置到scsi子系统里 。
- 这些公版驱动有针对硬盘的 , 磁带的 , 光驱的 , 扫描仪 , ROM等等各种设备的驱动 。
- 基本上这些驱动都会在自己的probe里面去查看sdev_gendev->type字段 , 判断该device是否和自己匹配 。例如:

文章插图
推荐阅读
- linux之间传文件命令之Rsync傻瓜式教程
- 微软提交补丁,用Linux替代Hyper-V根分区的Win
- 借助 HTTP 通过 SSH 绕过 Linux 防火墙
- Linux或者Mac下命令行speedtest测试网络速度
- 硬盘有必要分区吗?MacOS、Linux都不分区
- linux中ELF格式二进制程序
- 利用这个 USB ID 仓库识别更多 Linux 上的设备
- Linux内核虚拟内存管理之匿名映射缺页异常分析
- 在Linux中使用Bashtop与Bpytop监管系统资源
- Linux驱动-互斥锁用法,建议先保存
