Linux os 下PCIe字符设备驱动开发记录 1 PCI/PCIe基本概念 PCI/PCIe规范->协议->标准硬件->标准软件->规范化的开发流程 连接(ARM/x86/MIPS/POWERPC…)主板与外部设备的总线标准,由电路接口和一个编程接口组成,PCI/PCIe设备的配置寄存器依据PCI/PCIe规范而设定,固件和操作系统正是通过枚举设备树们才能发现绝大多数即插即用(PNP)设备的。 2 PCI 与PCIe 差异 PCI 并行 配置空间256B 典型topology
PCIe 串行 配置空间由256B扩展到4K 典型topology
共通 配置空间、IO空间、memory 空间分离 linux os下驱动框架通用 PCIe传输规格
3 PCIe 设备枚举 系统boot阶段,firmware或者是linux kerel(取决kernel config配置)针对PCI(PCIe)设备进行枚举(访问PCIe配置空间),为每一个设备分配安全的IO空间与存储空间。 如果枚举成功,那么进入到linux os可以通过lspci工具查看PCIe设备信息,如下图所示:
通过显示可以得到如下信息:设备的vendor id 是ebed ,device id是0109应用的PCIe配置空间的bar0 与bar1 kernel给其分配的两片存储器空间起始地址分别是0x,0x5a000000,大小分别是32M与64K总线上暂时未有与之匹配的设备驱动 4 PCIe字符设备驱动开发 PCIe设备驱动开发基础 具体PCIe设备类型,是网络设备、存储设备、显示设备、块设备还是字符设备,针对本文中的案例就是一个自研串口设备,是一个字符设备 PCIe配置空间信息,我们应用了前64B,具体应用了如下图的红色方框部分,绿色方框部分硬件未进行连接
PCI标准配置空间分为type0和type1两种, type0主要是针对PCI的endpoint设备(参见kernel源码),type1主要是针对PCI bridge, switch(参见kernel源码),(还有type2:CardBus bridges,参见kernel源码的注释)。
其中command寄存器,在PCI设备使能pci_enable_device时会配置该寄存器。主要是负责使能或是关闭pci设备的I/O访问,memeory访问和INTx中断等。 BAR地址寄存器负责PCI设备内部空间的映射。 每一个bar地址对应一个地址空间,在bar寄存器中有些bar是只读的,是PCI设备出厂前就固定好的bit。针对某些bit位写全1进去,如果值保持不变,说明这些bit是厂家固化好的,这些固化好的bit提供了PCI/PCIe内部空间的相关信息。重点:CPU可以通过访问BAR地址读取PCIe的设备空间(IO/mem空间),前提是读取到配置空间。 Linux PCIe驱动架构
linux kernel相关PCIe接口与数据结构
linux kernel字符设备驱动模型
5 PCIe字符设备驱动调试 编译 根据实际开发条件选择编译方式静态编译 直接编译进内核,作为内核的一部分编译进内核镜像,需要有相应的内核源码动态加载 编译成可动态加载的模块 本方案采用动态加载模块,原因就是没有kylin os的相应的内核源码,那么就采用kylin os运行时编译及加载驱动 编译方法编写Makefile文件,通过make工具编译PCIe驱动模块,基本步骤(视Makefile而定)makemake loadmake install 加载 加载步骤 编译后的make load&make install加载成功与否判断 核对驱动加载日志 cat /var/log/syslog
dmesg | grep zynq
未加载驱动时显示异常
正常
同时可以通过cat /proc/iomem查看针对PCIe设备的系统 RAM空间分布情况判断字符设备节点生成情况
userspace调试 userspace基本读写测试 在做具体业务逻辑前,我们编写PCIe设备memeory空间读写工具,判断驱动加载的正确性与可应用型,简单调试示例如下:
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/81988.html