第2章:开发环境搭建
好,咱们正式开始动手了。这一章,我带你把开发环境搭起来。
说实话,很多初学者把精力都花在写代码上,结果环境没配好,编译都过不了,白白浪费一整天。我当年就吃过这个亏——记得第一次搞嵌入式Linux,光交叉编译工具链就折腾了两天,最后发现是路径写错了。嗯,咱们今天就把这些坑提前填上。
2.1 Linux开发环境配置
做SoC驱动开发,我建议你直接用Ubuntu。为什么?因为社区支持最好,遇到问题随便一搜就有答案。我个人习惯用Ubuntu 20.04 LTS或22.04 LTS,长期支持版,稳定。
你需要装的东西其实不多,但一个都不能少:
- 基础开发工具:build-essential、gcc、g++、make、cmake
- 版本管理:git(这个必须装,后面你会频繁用到)
- 文本编辑:vim或vscode,看个人喜好
- 调试工具:gdb、strace、ltrace
安装命令很简单,一行搞定:
sudo apt update
sudo apt install build-essential git vim gdb cmake
2.2 交叉编译工具链安装
交叉编译,说白了就是在一台电脑上编译出另一台电脑能跑的程序。你的开发机是x86架构,但SoC通常是ARM或RISC-V,所以需要交叉编译工具链。
以ARM Cortex-A系列为例,我常用的是gcc-arm-none-eabi或gcc-arm-linux-gnueabihf。区别在哪?前者用于裸机或RTOS,后者用于Linux用户态程序。
安装方式有两种:
- apt直接装(简单,但版本可能旧)
- 从ARM官网下载(推荐,版本新且稳定)
我个人习惯用第二种,因为我在项目中遇到过apt版本太旧导致编译报错的情况。下载后解压,配置环境变量:
# 解压到 /opt 目录
sudo tar -xjf gcc-arm-9.2-2019.12-x86_64-arm-none-eabi.tar.bz2 -C /opt/
# 配置环境变量(加到 ~/.bashrc 里)
export PATH=$PATH:/opt/gcc-arm-none-eabi-9-2019-q4-major/bin
# 验证是否安装成功
arm-none-eabi-gcc --version
2.3 设备树(Device Tree)基础
设备树,英文叫Device Tree,简称DT。它是干什么用的?说白了,就是告诉内核你的硬件长什么样。
以前没有设备树的时候,内核里全是板级文件,每个板子一个.c文件,维护起来简直是噩梦。后来社区引入了设备树,把硬件描述从内核代码里剥离出来,变成了一个文本文件。你想想看,改硬件配置只需要改一个.dts文件,多方便。
2.3.1 设备树的基本结构
设备树文件以.dts为后缀,编译后生成.dtb文件。它的结构是树形的,根节点是"/",下面挂各种外设节点。
看一个最简单的例子:
/dts-v1/;
/ {
model = "MySoC Board";
compatible = "vendor,myboard";
cpu@0 {
compatible = "arm,cortex-a7";
reg = <0x0>;
};
uart0: serial@10000000 {
compatible = "vendor,uart";
reg = <0x10000000 0x1000>;
interrupts = <0 33 4>;
clock-frequency = <24000000>;
};
};
这里每个节点都有compatible属性,内核就是靠这个字符串来匹配驱动。reg属性描述地址和大小,interrupts描述中断号。
2.3.2 常用属性与节点
我整理了一张表,把最常用的属性和节点列出来,你以后查起来方便:
| 属性/节点 | 说明 | 示例 |
|---|---|---|
| compatible | 驱动匹配字符串 | "vendor,device" |
| reg | 寄存器地址和大小 | <0x10000000 0x1000> |
| interrupts | 中断描述 | <0 33 4> |
| clocks | 时钟引用 | <&clk 1> |
| status | 设备状态 | "okay" 或 "disabled" |
2.3.3 编译设备树
设备树源文件(.dts)需要编译成二进制(.dtb),内核启动时加载。编译工具是dtc(Device Tree Compiler)。
# 编译单个dts文件
dtc -I dts -O dtb -o myboard.dtb myboard.dts
# 反编译dtb文件(调试时很有用)
dtc -I dtb -O dts -o myboard.dts myboard.dtb
2.4 本章小结
这一章我们做了三件事:配好了Linux开发环境、装好了交叉编译工具链、了解了设备树的基本用法。这些都是后面写驱动的基础,别嫌麻烦,一步一个脚印来。
下一章,咱们开始写第一个字符设备驱动。到时候你会发现,环境搭好了,写代码其实挺痛快的。