前言
前后折腾了好几个月,终于把PCIe最最基本的功能做出来后,成就感相当的大!我把能踩的坑都踩了一遍, 总结下学习经验吧。半路出家学的嵌入式编程,一直抱着团队技术大牛大腿,然后摸索过河。希望自己将来能够独当一面。
环境
Linux 内核 6.10, 嗯大概。
yocto 编译
Cortex-A65, 自带gicv3, ITS, SMMU ( 之前只搞cortex M 或者 R, 看到做pcie需要用到这些辅助功能...san值都掉光了。 )尤其是ITS, 直接把我CPU干冒烟了。 看reference manual真的能减肥。
概述
这里就不介绍啥是PCIe了,站里好多博客讲的都相当详细。耐着心思看完,就能理解个大概了。我个菜鸟就不班门弄斧了。
这里总结的,都是我自己的开发经验,以及避坑指南。
正文
1 我写的PCIe驱动是什么鬼
为了让PCIe跑起来,我们需要好几种PCIe驱动. 新人容易混淆,我简单讲讲吧。
1. 1 PCIe controller (或PCIe Subsystem)的驱动。 很幸运, 你不用写,有现成。 都在linux drivers/pcie/controller 文件夹下。 这些底层驱动(直接修改PCIe寄存器)通常由PCIe 这个IP的供应商提供,例如synopsis 或者cadence。 如果大神你就是做IP的, 请留下你的联系方式,然后滑走。嗯,我还有很多不懂的地方, 将来找机会请教你。 对于这些驱动, 你可以直接拿来用。最基本的功能是有保障的,但是有可能不全面。 例如某些底层驱动竟然不支持自带的uDMA。(被我同事喷死了)
1. 2. PCIe 内核驱动。 嗯, Linux 代码开源, 自带PCIe驱动,你也不用写。 PCIe Device Enumeration,capabilities 的解析, inbound/outbound bar 地址的设置, Linux都替你搞定了。 如果以上这几步出错,90%的可能是你device tree的设置没搞清楚,5% 的可能是设备clock没有使能。4·99% 可能是你没搞懂你使用的EP。最后0.01% 可能是你家芯片有个隐藏的开关, 你看技术文档的时候漏掉了,或者你们的硬件工程师忘记跟你提了。 从自己身上找原因吧。
1. 3.