Linux --- 泰山派RK3566驱动开发 --- 环境搭建+内核编译
目录
前言
早些时候,我拿到了泰山派2+16G版本,中间学习了一些相关应用,用2K0300做了车赛,最近才开始正式使用这块板子,拿来学习驱动开发。
官方资料站:立创开发板技术文档中心
一、获取官方资料
开发驱动我们需要完整的软硬件资料才行,立创官方则是提供了完整的资料。
- 本次板子上是Ubuntu系统
- 使用WSL2作为开发机,Ubuntu18.04
二、环境准备
1.内核源码获取及编译
1.0 源码获取
首先我们需要从官方SDK中获取内核源码kernel,我是在官方SDK -Linux \tspi那个无repo压缩包中找到kernel文件夹。1.1 配置交叉编译环境
开发arm64架构,安装如下工具链即可,若是其他的比如龙芯的架构,需要下载解压官方提供的工具链。
检查1.2 编译内核(至少编译一次)
这时需要. config文件来确保我们编译出的东西放到板子上不会出问题甚至导致板子变砖。此时可以去板子上查找这个文件,并获取我们需要的东西
通过如下命令获取配置文件到编译板子上运行的内核时所用到的配置文件。
然后需要配置一些编译所需的软件。官方教程在编译SDK时也提到了所需的包,也可以参考那个。如果忘了自己安装了什么,查看apt日志即可
开始编译,接下来就是export创建临时环境,然后写入配置、开始编译。编译时间会长一些,需耐心等待
最后我出现了如下内容
检查编译结果
2.完成一个驱动
此处涉及的方面较多且复杂,本人边学边做,记录时也是多个文章同时进行的。建议首先学一些语言和工具。
首先是git,每当进入新阶段时一定要保存好自己的代码,用于管理内核源码、自己的驱动代码、实验版本。。
然后是TFTP,NFS,SSH等等 ,网络传输能极大提高开发效率,不用反复烧写存储介质。
学一些shell脚本和Makefile基础,方便进行一些重复操作,更快捷有效,也方便借鉴学习内核中的Makefile等等。
然后需要掌握设备树语法和C/C++语言,必须掌握。为使使驱动与硬件匹配,需要在设备树中添加一个节点,设备树相关信息可以查看官方的胖妞手机的实战案例,其中涉及了详细的设备树开发教程。至于C/C++语言则是重中之重,编写驱动代码需要用到,要能熟练阅读内核中复杂的宏定义和链表操作。
2.0 第一个无硬件的驱动
我们尝试写一个驱动版本的hello world,它本身不控制任何硬件,确保硬件安全,也不提供用户空间交互接口,但能通过内核日志让我们知道,这个模块代码被正确执行了。它如果还未掌握设备树语法或者想先尝试一下看看自己搭建的环境对不对也可以写一个简单的驱动,其中只包含一些调试用的内核函数。
一个驱动需要许多文件,总结如下
首先是编写一个内核模块源代码.c文件实现驱动的核心逻辑:初始化、退出、文件操作接口(如 open/read/write)、中断处理、与硬件交互等。定义驱动与设备树的匹配表(of_device_id),声明驱动支持的设备兼容字符串。注册 platform 驱动或其他总线驱动(如 I2C、SPI)。
其次是Makefile文件利用内核构建系统将.c文件编译成内核模块.ko。指定模块名称、源文件、依赖的内核源码路径等。
设备树源文件(.dts 或 .dtsi->独立文件),此处不控制硬件,不需要,但也给一个示例,保证流程的完整性,且一般是修改板子的主设备树文件。描述硬件在系统中的连接方式:寄存器地址、中断号、使用的 GPIO 引脚、时钟、电源等。为驱动提供硬件配置信息,使驱动代码不依赖硬编码,提高可移植性。
设备树覆盖文件,(.dts 编译为 .dtbo)若不希望修改主设备树,创建这个如果不希望修改主设备树,可以创建设备树覆盖(overlay),动态加载设备节点。适用于模块化硬件或实验性开发,避免反复烧写整个设备树。
编译为.dtbo,并在板子上通过configfs 加载覆盖
Kconfig文件(Kconfig,可选,用于内核配置菜单)如果希望将驱动集成到内核的配置系统中(例如可以通过make menuconfig选择是否编译),需要编写 Kconfig 条目。定义驱动的名称、依赖、帮助信息等。
在源码目录的Kconfig中source该文件,并在Makefile中添加条件编译:
内核配置文件(.config)内核编译时的全局配置文件,用于启用或禁用驱动、子系统等。如果你在 Kconfig 中添加了驱动,需要确保.config中对应的CONFIG_MY_LED被设置为y(内置)或m(模块)。
使用make menuconfig或直接编辑.config来设置。2.1 部署到板卡
完成以上操作后,可以尝试将.ko文件通过U盘或者网络(ssh等工具)传输到泰山派上,并在存放.ko文件的目录下加载卸载内核模块,通过内核日志来查看效果。注意这时需要管理员权限。
# 加载内核模块
# 查看内核模块列表
# 查看内核日志
# 卸载内核模块
我们已经成功运行了第一个模块,接下来可以:添加参数传递:学习module_param让模块接受参数。创建 /proc 或 /sys 文件:用proc_create或device_create与用户空间交互。操作 GPIO:结合设备树,用 GPIO 子系统点个灯。编写 Makefile 进阶:支持多文件模块、条件编译等。
总结
从零到第一个驱动,核心步骤就是:准备好内核源码并编译一次(生成 Module.symvers 等)。编写模块代码(遵循内核 API)。编写 Makefile 利用内核构建系统。交叉编译生成 .ko 文件。传输到开发板并加载测试。