2. 开发环境搭建:交叉编译工具链配置、内核源码获取与编译、设备树基础
在瑞芯微平台进行显示驱动开发,首要任务是构建一个稳定、高效的交叉编译环境。本章将引导你完成从工具链安装到内核编译、设备树编写的完整流程,为后续的驱动开发打下坚实基础。
学习目标:掌握交叉编译工具链的配置方法;学会获取并编译瑞芯微平台Linux内核源码;理解设备树的基本语法与显示驱动相关的节点编写。
2.1 交叉编译工具链配置
交叉编译是指在宿主机(通常是x86架构的PC)上编译生成目标平台(ARM64架构的瑞芯微SoC)可执行代码的过程。瑞芯微官方推荐使用 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu 或更新版本的工具链。
2.1.1 工具链下载与安装
- 下载工具链:从ARM官方或瑞芯微Github仓库获取预编译的交叉编译工具链。
- 解压到指定目录:建议统一放置在
/opt/toolchains/目录下。 - 配置环境变量:将工具链的bin目录添加到
PATH环境变量中。
# 下载工具链(示例版本)
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 解压到 /opt/toolchains/
sudo mkdir -p /opt/toolchains
sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/toolchains/
# 配置环境变量(建议写入 ~/.bashrc 或 /etc/profile)
export PATH=/opt/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
# 验证安装
aarch64-none-linux-gnu-gcc --version
2.1.2 工具链验证
执行以下命令验证工具链是否正常工作:
# 编译一个简单的测试程序
echo '#include <stdio.h>
int main() { printf("Hello, RK Display Driver!\n"); return 0; }' > test.c
aarch64-none-linux-gnu-gcc -o test test.c
file test
# 输出应包含:ELF 64-bit LSB executable, ARM aarch64
常见问题:如果出现
command not found,请检查 PATH 变量是否包含正确的bin目录路径,并确认已执行 source ~/.bashrc 或重新打开终端。
2.2 内核源码获取与编译
瑞芯微官方维护了多个内核分支,显示驱动开发通常基于 Linux 5.10 或 Linux 6.1 内核。以下以RK3588平台为例,介绍内核源码的获取与编译流程。
2.2.1 获取内核源码
推荐使用Git从瑞芯微官方仓库克隆:
# 克隆RK3588 Linux 5.10内核
git clone https://github.com/rockchip-linux/kernel.git -b rk3588/linux-5.10-rkr12
# 进入内核源码目录
cd kernel
# 查看当前分支
git branch -a
2.2.2 内核配置与编译
瑞芯微平台使用 defconfig 配置文件,针对不同板型有对应的默认配置。
| 板型 | 默认配置文件 | 设备树文件 |
|---|---|---|
| RK3588 EVB1 | rockchip_linux_defconfig | rk3588-evb1-lp4.dts |
| RK3588 EVB7 | rockchip_linux_defconfig | rk3588-evb7-lp4.dts |
| RK3568 EVB | rockchip_linux_defconfig | rk3568-evb.dts |
| RK3399 EVB | rockchip_linux_defconfig | rk3399-evb.dts |
# 加载默认配置
make rockchip_linux_defconfig
# 可选:使用menuconfig进行自定义配置(显示驱动相关选项在 Device Drivers -> Graphics support)
make menuconfig
# 编译内核镜像与设备树
make Image modules dtbs -j$(nproc)
# 编译完成后,生成的文件位于:
# 内核镜像:arch/arm64/boot/Image
# 设备树:arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4.dtb
2.2.3 编译输出文件说明
| 文件 | 路径 | 说明 |
|---|---|---|
| Image | arch/arm64/boot/Image | 压缩后的内核镜像 |
| *.dtb | arch/arm64/boot/dts/rockchip/ | 编译后的设备树二进制文件 |
| *.ko | 各驱动目录下 | 内核模块(如显示驱动模块) |
| vmlinux | 源码根目录 | 未压缩的内核镜像(用于调试) |
提示:显示驱动开发过程中,通常只需要更新
.dtb 文件和对应的驱动模块 .ko 文件,无需每次都重新编译整个内核,可以大幅节省时间。
2.3 设备树基础
设备树(Device Tree)是一种描述硬件资源的数据结构,用于将硬件信息从内核代码中分离出来。在瑞芯微平台显示驱动开发中,设备树用于描述显示控制器(VOP)、HDMI、DP、MIPI DSI等显示接口的硬件连接与配置参数。
2.3.1 设备树基本语法
设备树文件采用 .dts 格式,编译后生成 .dtb 二进制文件。以下是一个简化的显示节点示例:
// 设备树源文件示例:rk3588-display.dtsi
/dts-v1/;
/ {
model = "Rockchip RK3588 EVB1";
compatible = "rockchip,rk3588";
// 显示控制器节点
vop: vop@fdd90000 {
compatible = "rockchip,rk3588-vop";
reg = <0x0 0xfdd90000 0x0 0x200>;
interrupts = <0 148 4>;
clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
clock-names = "aclk", "hclk";
status = "disabled";
// VOP输出端口
ports {
#address-cells = <1>;
#size-cells = <0>;
vop_out: port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
vop_hdmi: endpoint@0 {
reg = <0>;
remote-endpoint = <&hdmi_in_vop>;
};
};
};
};
// HDMI控制器节点
hdmi: hdmi@fde80000 {
compatible = "rockchip,rk3588-hdmi";
reg = <0x0 0xfde80000 0x0 0x20000>;
interrupts = <0 167 4>;
clocks = <&cru PCLK_HDMI>;
clock-names = "pclk";
status = "disabled";
ports {
hdmi_in: port@0 {
reg = <0>;
hdmi_in_vop: endpoint@0 {
remote-endpoint = <&vop_hdmi>;
};
};
};
};
};
2.3.2 显示驱动相关设备树节点
瑞芯微平台显示子系统涉及的主要设备树节点包括:
| 节点名称 | 功能描述 | 关键属性 |
|---|---|---|
| vop | 视频输出处理器(显示控制器) | compatible, reg, interrupts, clocks, ports |
| hdmi | HDMI接口控制器 | compatible, reg, interrupts, clocks, ports |
| dp | DisplayPort接口控制器 | compatible, reg, interrupts, clocks, ports |
| mipi_dsi | MIPI DSI接口控制器 | compatible, reg, clocks, phys, panel |
| edp | eDP接口控制器 | compatible, reg, clocks, panel |
| lvds | LVDS接口控制器 | compatible, reg, clocks, panel |
| route | 显示路由配置(VOP到显示接口的映射) | connect, status |
2.3.3 显示路由配置
显示路由(Display Route)用于将VOP的输出连接到具体的显示接口。以下是一个典型的显示路由配置:
// 显示路由配置示例
&route_hdmi {
status = "okay";
connect = <&vop_out_hdmi>;
};
&route_dp0 {
status = "okay";
connect = <&vop_out_dp0>;
};
&route_mipi_dsi0 {
status = "disabled"; // 未使用的路由可以关闭
};
开发建议:在调试显示驱动时,建议先确认设备树中对应节点的
status 属性是否为 "okay",以及 connect 属性是否正确指向了VOP的输出端点。这是最常见的配置错误来源。
2.4 开发环境搭建流程总结
以下SVG流程图展示了从工具链安装到内核编译、设备树编写的完整开发环境搭建流程:
2.5 常见问题与避坑指南
避坑1:工具链版本不匹配
瑞芯微不同内核版本对工具链版本有要求。Linux 5.10内核推荐使用gcc 10.3及以上版本,Linux 4.19内核可使用gcc 8.3。版本过低可能导致编译错误或运行时异常。
瑞芯微不同内核版本对工具链版本有要求。Linux 5.10内核推荐使用gcc 10.3及以上版本,Linux 4.19内核可使用gcc 8.3。版本过低可能导致编译错误或运行时异常。
避坑2:设备树语法错误
设备树文件对语法非常敏感,常见的错误包括:缺少分号、括号不匹配、属性值类型错误。建议使用
设备树文件对语法非常敏感,常见的错误包括:缺少分号、括号不匹配、属性值类型错误。建议使用
dtc -I dts -O dtb -o output.dtb input.dts 命令单独检查语法。
调试技巧:在设备树中,可以使用
status = "okay"; 和 status = "disabled"; 来控制节点的启用与禁用。在调试显示驱动时,建议先关闭不相关的显示接口,只保留正在调试的接口,以减少干扰。
2.6 本章小结
本章完成了瑞芯微平台显示驱动开发环境的搭建,包括:
- 交叉编译工具链的下载、安装与环境变量配置
- 内核源码的获取、配置与编译流程
- 设备树的基本语法、显示相关节点编写与路由配置