驱动开发环境搭建:交叉编译工具链安装、Linux内核源码获取与配置、设备树基础与编译、TFTP/NFS网络文件系统搭建
说实话,座舱芯片驱动开发的第一步,往往不是写代码,而是搭环境。我见过太多新手一上来就急着敲键盘,结果编译报错、烧录失败、板子起不来,折腾半天才发现是工具链没装对。嗯,咱们先把地基打牢。
交叉编译工具链安装
座舱芯片通常是ARM或RISC-V架构,你的PC是x86架构。说白了,你得在PC上编译出能在芯片上跑的程序。这就是交叉编译。
工具链的选择,我个人习惯用Linaro提供的GCC工具链,稳定且社区活跃。比如针对ARM Cortex-A系列:
# 下载ARM64工具链
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/
# 配置环境变量
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin
~/.bashrc 或 /etc/profile,避免每次开终端都要重新 export。我一般写在 /etc/profile.d/cross_compile.sh 里,方便多用户使用。
验证安装是否成功:
aarch64-linux-gnu-gcc --version
如果看到版本号输出,恭喜你,第一步走通了。
Linux内核源码获取与配置
内核源码怎么拿?我建议直接从官方仓库clone,或者用芯片厂商提供的BSP包。以高通SA8155为例:
# 从官方仓库获取
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout v5.10.120 # 选择一个LTS版本
# 或者使用厂商BSP
# 通常厂商会提供一个 .tar.gz 包,解压即可
tar -xvf sa8155_linux_kernel_5.10.tar.gz
内核配置是重头戏。你想想看,一个完整的内核有上万种配置选项,但座舱芯片只需要其中一小部分。怎么做?
- 使用默认配置:芯片厂商通常会提供
defconfig文件 - 基于默认配置修改:运行
make menuconfig进行图形化配置 - 保存配置:修改后保存为
.config文件
# 加载厂商默认配置
make ARCH=arm64 defconfig # 或者使用厂商提供的配置文件
# 例如:make ARCH=arm64 sa8155_defconfig
# 图形化配置
make ARCH=arm64 menuconfig
# 编译内核
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
核心要点:配置内核时,重点关注这几类选项:
- CPU架构和特性(ARMv8、NEON、GIC等)
- 内存管理(DMA、CMA、ION等)
- 显示驱动(DRM/KMS、MIPI DSI、HDMI等)
- 音频驱动(ALSA、I2S、TDM等)
- 网络协议栈(TCP/IP、CAN、Ethernet等)
- 电源管理(PM、DVFS、Suspend/Resume等)
我在项目中遇到过最坑的事:忘了开启CMA(连续内存分配器),结果显示驱动申请不到大块连续内存,屏幕死活点不亮。排查了两天才找到原因。所以,配置完一定要仔细检查关键选项。
设备树基础与编译
设备树(Device Tree)是什么?说白了,它就是描述硬件信息的配置文件。以前的内核把硬件信息硬编码在代码里,换一块板子就要改代码。设备树把硬件描述和内核代码解耦了。
一个简单的设备树节点示例:
/dts-v1/;
/ {
model = "Qualcomm SA8155 EVB";
compatible = "qcom,sa8155";
chosen {
bootargs = "console=ttyMSM0,115200n8 root=/dev/nfs rw";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x80000000>;
};
soc {
#address-cells = <2>;
#size-cells = <2>;
uart@a84000 {
compatible = "qcom,msm-uart";
reg = <0x0 0x00a84000 0x0 0x1000>;
interrupts = <0 113 4>;
clock-frequency = <7372800>;
status = "okay";
};
i2c@a88000 {
compatible = "qcom,i2c-qup";
reg = <0x0 0x00a88000 0x0 0x1000>;
interrupts = <0 114 4>;
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
status = "okay";
touch@38 {
compatible = "goodix,gt9271";
reg = <0x38>;
interrupt-parent = <&tlmm>;
interrupts = <67 2>;
reset-gpios = <&tlmm 66 0>;
};
};
};
};
设备树编译:
# 编译设备树源文件(.dts)为二进制文件(.dtb)
dtc -I dts -O dtb -o sa8155-evb.dtb sa8155-evb.dts
# 反编译查看
dtc -I dtb -O dts -o sa8155-evb.dts sa8155-evb.dtb
dtc -I dtb -O dts 反编译看看实际加载的设备树是什么样。有时候你写的dts和实际加载的不一样,可能是bootloader做了修改。
设备树的核心语法要点:
/dts-v1/;是版本声明,必须写在文件开头- 根节点
/包含所有硬件信息 compatible属性用于匹配驱动reg属性描述地址和大小interrupts属性描述中断信息status属性控制设备是否启用(okay/disabled)
TFTP/NFS网络文件系统搭建
开发阶段,你不可能每次修改都烧录整个镜像。太慢了。我一般用TFTP下载内核和设备树,用NFS挂载根文件系统。这样改完代码,编译、重启、测试,几分钟一轮。
TFTP服务器搭建:
# 安装TFTP服务器
sudo apt-get install tftpd-hpa
# 配置TFTP目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
# 修改配置文件 /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create"
# 重启服务
sudo systemctl restart tftpd-hpa
NFS服务器搭建:
# 安装NFS服务器
sudo apt-get install nfs-kernel-server
# 创建根文件系统目录
sudo mkdir -p /srv/nfs/rootfs
# 解压根文件系统
sudo tar -xvf sa8155_rootfs.tar.gz -C /srv/nfs/rootfs
# 配置 /etc/exports
/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
# 重启NFS服务
sudo systemctl restart nfs-kernel-server
U-Boot启动参数设置:
# 设置IP地址
setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10
# 通过TFTP下载内核和设备树
tftp 0x80000000 Image
tftp 0x83000000 sa8155-evb.dtb
# 设置NFS根文件系统
setenv bootargs console=ttyMSM0,115200n8 root=/dev/nfs rw nfsroot=192.168.1.10:/srv/nfs/rootfs,v3,tcp ip=192.168.1.100:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off
# 启动内核
booti 0x80000000 - 0x83000000
busybox 的某些命令,或者 /dev 目录下没有必要的设备节点,导致系统启动到一半就卡住了。建议先用完整的根文件系统验证网络启动流程,再逐步裁剪。
网络文件系统搭建完成后,你的开发效率会提升一个量级。改驱动 -> 编译 -> 重启板子 -> 看效果,整个过程不超过5分钟。这才是座舱芯片驱动开发的正确节奏。
本章小结:
- 交叉编译工具链是基础,版本匹配很重要
- 内核配置要关注关键子系统,不要贪多
- 设备树是硬件描述语言,学会看和改dts是基本功
- TFTP+NFS是开发阶段的利器,能大幅缩短迭代周期