常识 | 关于驱动....待续

26 篇文章 1 订阅
14 篇文章 0 订阅

PCI总线驱动的一个例子------

  • 各类驱动,大体都是硬件初始化配置,资源申请注册,核心是处理与硬件的交互(一般就是中断的处理),如果需要用户来交互的,则还需要注册设备文件,实现一堆file_operation操作函数集;

Linux内核建立了一个统一的设备模型,分别采用总线、设备、驱动三者进行抽象,其中设备与驱动都挂在总线上,当有新的设备注册或者新的驱动注册时,总线会去进行匹配操作(match函数),当发现驱动与设备能进行匹配时,就会执行probe函数的操作;

 PCI有设备树,用于描述硬件的信息,包含节点各类属性,在dts文件中定义,最终会被编译成dtb文件加载到内存中;内核会在启动过程中去解析dtb文件,解析成用设备节点描述的设备树。

根据设备节点,去总线上注册,完成创建设备

设备树关键字段描述:

  • compatible:用于匹配PCIe Host驱动
  • msi-controller:表示是一个MSI(Message Signaled Interrupt)控制器节点
  • device-type:必须是"pci"
  • interrupts:包含NWL PCIe控制器的中断号
  • interrupts-namemsi1, msi0用于MSI中断,intx用于旧式中断,与interrupts中的中断号对应;
  • reg:包含用于访问PCIe控制器操作的寄存器物理地址和大小
  • reg-name:分别表示Bridge registersPCIe Controller registers, Configuration space region,与reg中的值对应;
  • rangesPCIe地址空间转换到CPU的地址空间中的范围;
  • bus-range:PCIe总线的起始范围
  • interrupt-map-maskinterrupt-map:用于定义PCI接口到中断号的映射
  • legacy-interrupt-controller:旧式的中断控制器

1. 初始化配置、资源申请、注册:

初始化包括:数据结构的初始化以及设备的初始化等,设备的初始化则需要获取硬件的信息(比如寄存器基地址,长度,中断号等),这些信息都从DTS而来;

注册操作主要是包含中断处理函数的注册,以及通常的设备文件注册等;

具体:

  • devm_pci_alloc_host_bridge:分配并初始化一个基础的pci_hsot_bridge结构;
  • nwl_pcie_parse_dt获取DTS中的寄存器信息及中断信息,并设置intx中断号对应的中断处理函数,该处理函数用于中断的级联;
  • nwl_pcie_bridge_init硬件的Controller一堆设置,这部分需要去查阅Spec,了解硬件工作的细节。此外,通过devm_request_irq注册misc中断号对应的中断处理函数,该处理函数用于控制器自身状态的处理;
  • pci_parse_request_of_pci_ranges:用于解析PCI总线的总线范围和总线上的地址范围,也就是CPU能看到的地址区域;
  • nwl_pcie_init_irq_domainmwl_pcie_enable_msi中断级联相关,下个小节介绍;
  • pci_scan_root_bus_bridge:对总线上的设备进行扫描枚举,这个流程在Linux PCI驱动框架分析(二)中分析过。brdige结构体中的pci_ops字段,用于指向PCI的读写操作函数集,当具体扫描到设备要读写配置空间时,调用的就是这个函数,由具体的Controller驱动实现;

2. 中断处理

PCIe总线支持两种中断的处理方式:

  • Legacy Interrupt:总线提供INTA#, INTB#, INTC#, INTD#四根中断信号,PCI设备借助这四根信号使用电平触发方式提交中断请求;
  • MSI(Message Signaled Interrupt) Interrupt:基于消息机制的中断,也就是往一个指定地址写入特定消息,从而触发一个中断;

具体处理流程:

  1. 设备连接在PCI总线上,触发中断时,通过PCIe控制器充当的中断控制器路由到上一级控制器,最终路由到CPU;
  2. CPU在处理PCIe控制器的中断时,调用它的中断处理函数,也就是上文中提到过的nwl_pcie_leg_handlernwl_pcie_msi_handler_high,和nwl_pcie_leg_handler_low
  3. 在级联的中断处理函数中,调用chained_irq_enter进入中断级联处理;
  4. 调用irq_find_mapping找到具体的PCIe设备的中断号;
  5. 调用generic_handle_irq触发具体的PCIe设备的中断处理函数执行;
  6. 调用chained_irq_exit退出中断级联的处理;

linux字符设备驱动

register_chrdev 注册字符设备:把驱动程序的基本入口点指针存放在内核的字符设备地址表中,在用户进程对该设备执行系统调用时提供入口地址。

open() :确定硬件处在就绪状态、控制使用设备的进程数、根据执行情况返回状态码

release() :清理未结束的输入/输出操作、释放资源、用户自定义排他标志的复位

ioctl():通过它向设备传递控制信息或从设备取得状态信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值