2. 开发环境搭建:交叉编译工具链配置、内核源码获取与编译、设备树基础

在瑞芯微平台进行显示驱动开发,首要任务是构建一个稳定、高效的交叉编译环境。本章将引导你完成从工具链安装到内核编译、设备树编写的完整流程,为后续的驱动开发打下坚实基础。

学习目标:掌握交叉编译工具链的配置方法;学会获取并编译瑞芯微平台Linux内核源码;理解设备树的基本语法与显示驱动相关的节点编写。

2.1 交叉编译工具链配置

交叉编译是指在宿主机(通常是x86架构的PC)上编译生成目标平台(ARM64架构的瑞芯微SoC)可执行代码的过程。瑞芯微官方推荐使用 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu 或更新版本的工具链。

2.1.1 工具链下载与安装

  1. 下载工具链:从ARM官方或瑞芯微Github仓库获取预编译的交叉编译工具链。
  2. 解压到指定目录:建议统一放置在 /opt/toolchains/ 目录下。
  3. 配置环境变量:将工具链的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流程图展示了从工具链安装到内核编译、设备树编写的完整开发环境搭建流程:

开发环境搭建流程 1. 安装交叉工具链 gcc-arm-10.3 2. 配置环境变量 PATH / ARCH / CROSS_COMPILE 3. 获取内核源码 git clone (rk3588分支) 4. 内核配置 make rockchip_linux_defconfig 5. 编译内核 make Image modules dtbs -j$(nproc) 6. 编写设备树 .dts / .dtsi 文件 7. 编译设备树 make dtbs → .dtb 8. 部署与测试 烧录Image + .dtb 关键说明: • 步骤1-2为一次性配置,后续开发只需重复步骤5、7、8。 • 显示驱动调试时,通常只需更新 .dtb 文件和对应的 .ko 模块。 • 设备树编写是显示驱动开发的核心环节,需熟悉显示接口的硬件连接。 • 建议使用 make dtbs 单独编译设备树,避免全量编译。

2.5 常见问题与避坑指南

避坑1:工具链版本不匹配
瑞芯微不同内核版本对工具链版本有要求。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 本章小结

本章完成了瑞芯微平台显示驱动开发环境的搭建,包括:

  • 交叉编译工具链的下载、安装与环境变量配置
  • 内核源码的获取、配置与编译流程
  • 设备树的基本语法、显示相关节点编写与路由配置