ARM Linux 完整介绍 + 实操教程
一、ARM Linux 是什么
ARM Linux = 运行在 ARM 架构CPU上的 Linux 操作系统
- x86:电脑、服务器(Intel/AMD,复杂指令集CISC)
- ARM:移动设备、嵌入式、单板机(树莓派、RK3568、STM32MP1、手机芯片,精简指令集RISC)>
注意:Linux 内核本身不分 x86/ARM,内核是跨平台的,通过架构相关代码支持ARM。我们常说的 ARM Linux 是【Linux内核 + ARM设备驱动 + rootfs根文件系统】整套。
ARM Linux 分类
- 嵌入式ARM Linux:RK3568、IMX6ULL、STM32MP1,无显示器,多用于工控、网关
- 单板机ARM Linux:树莓派、香橙派,带桌面系统
- 手机Android:底层也是ARM Linux,但加了安卓框架,不属于通用ARM Linux
核心组件(必须4样齐全才能启动)
- Bootloader(引导程序):U-Boot最常用,类似电脑BIOS,初始化硬件、加载内核
- Linux Kernel(内核):管理内存、进程、驱动,针对ARM芯片编译
- Device Tree 设备树(dts):描述硬件资源(引脚、I2C、SPI),代替旧版硬编码内核
- Rootfs 根文件系统:/ 目录,存放命令、库、配置(busybox、ubuntu、debian)
ARM Linux 和 PC Linux 的关键差异
| 项目 | PC(x86) Linux | ARM Linux |
|---|---|---|
| 编译 | 本机直接编译 | 大多需要交叉编译(x86电脑编译ARM程序) |
| 硬件 | 标准化主板 | 芯片差异巨大,驱动需要适配 |
| 启动 | BIOS+GRUB | U-Boot + 设备树 + 内核 |
| 根文件系统 | 完整发行版 | 可极简busybox,也可用Debian/Ubuntu ARM版 |
二、学习路线(推荐顺序)
新手建议顺序:使用现成单板机 → 交叉编译 → U-Boot → 内核编译 → 设备树 → 根文件系统 → 驱动开发
- 阶段1:上手现成ARM Linux(树莓派/香橙派),熟悉Linux基础命令
- 阶段2:搭建交叉编译环境,编译简单C程序在ARM板运行
- 阶段3:U-Boot 编译、烧录、命令操作
- 阶段4:Linux内核编译,修改设备树,替换内核镜像
- 阶段5:制作根文件系统(Busybox)
- 阶段6:字符设备驱动开发(ARM平台)
三、实操教程
前置准备
环境
- 宿主机:Ubuntu 22.04(x86_64虚拟机或实体机,推荐,兼容性最好)
- 开发板(可选):新手推荐 树莓派4B(开箱即用ARM Linux);想深入底层选 IMX6ULL / RK3568>
没有开发板也可以用 QEMU 模拟器跑ARM Linux,不需要硬件!下文会有QEMU教程。
1. 基础:ARM Linux 发行版体验(树莓派举例)
树莓派系统是预编译好的ARM Linux,直接烧录SD卡就能跑。
- 下载 Raspberry Pi OS(Debian ARM64)
- Raspberry Pi Imager 烧录SD卡
- 上电,SSH登录,和普通Linux命令基本一致
# 查看架构,确认是ARM
uname -m
# aarch64 = ARM64(64位ARM);armv7l = ARM32
ARM64:aarch64;ARM32:armhf
2. 交叉编译环境搭建(核心重点)
交叉编译:在x86电脑上编译出可以在ARM芯片运行的程序。
原生编译:在ARM板子上本地编译(板子性能弱,编译很慢)
安装交叉编译器(Ubuntu宿主机)
# ARM64 (aarch64) 交叉编译器
sudo apt update
sudo apt install aarch64-linux-gnu-gcc aarch64-linux-gnu-g++
# ARM32 (armhf) 交叉编译器
sudo apt install arm-linux-gnueabihf-gcc arm-linux-gnueabihf-g++
测试交叉编译
新建 test.c
#include <stdio.h>
int main(){
printf("Hello ARM Linux!\n");
return 0;
}
编译ARM64版本:
aarch64-linux-gnu-gcc test.c -o test_arm64
查看文件架构:
file test_arm64
# 输出:ELF 64-bit LSB executable, ARM aarch64
把 test_arm64 传到ARM板子(scp),板子执行:./test_arm64
⚠️ 坑:交叉编译程序依赖的glibc库版本必须和开发板rootfs保持一致,否则会报
not found。静态编译规避:
aarch64-linux-gnu-gcc test.c -o test_arm64_static -static
3. QEMU 模拟器:无开发板跑ARM Linux(强烈推荐新手)
QEMU可以在x86电脑模拟ARM板子,不需要硬件,用来学习U-Boot、内核、设备树。
安装QEMU
sudo apt install qemu-system-aarch64
下载预编译内核+rootfs(ARM64)
# 下载busybox根文件系统,内核镜像
wget [https://github.com/](https://github.com/)... (也可以自己编译)
启动QEMU ARM64命令示例:
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-m 1G \
-kernel Image \
-initrd rootfs.cpio \
-nographic
启动后直接进入ARM Linux终端。
4. U-Boot 编译与基础命令
U-Boot是ARM Linux最主流引导程序。
编译U-Boot
git clone [https://github.com/u-boot/u-boot.git](https://github.com/u-boot/u-boot.git)
cd u-boot
# 指定开发板配置,例如rk3568
make CROSS_COMPILE=aarch64-linux-gnu- rk3568_defconfig
make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
输出:u-boot.bin、u-boot.img,烧录到开发板存储(SD卡/eMMC)
U-Boot 常用命令
# 查看环境变量
printenv
# 设置bootargs(内核启动参数)
setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk1p2 rootwait rw'
# 从SD卡读取内核镜像到内存
load mmc 1:1 0x40800000 Image
# 读取设备树
load mmc 1:1 0x48000000 rk3568.dtb
# 启动内核
booti 0x40800000 - 0x48000000
bootargs 是传给Linux内核的参数:串口、根文件系统位置。
5. Linux 内核编译(ARM)
git clone [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git)
cd linux
# 加载开发板默认配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3568_defconfig
# 图形化配置内核(开关驱动)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
# 编译内核镜像+设备树
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image dtbs -j$(nproc)
输出文件位置:
arch/arm64/boot/Image:ARM64内核镜像arch/arm64/boot/dts/rockchip/rk3568.dtb:编译后的设备树二进制文件
设备树简单说明
.dts:源码,描述硬件(I2C、GPIO、串口).dtb:编译后的二进制,U-Boot传给内核
修改dts可以添加外设,不用重新编译整个内核,是现代ARM Linux核心。
6. Busybox 制作极简根文件系统 rootfs
Busybox 把ls、cat、mkdir等几百个Linux命令打包成单个程序,做最小rootfs。
git clone [https://git.busybox.net/busybox](https://git.busybox.net/busybox)
cd busybox
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
# 勾选:Build static binary(静态编译,不需要依赖库)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install
安装后在 _install 目录生成最小根文件系统,需要手动创建必要目录:
cd _install
mkdir -p dev proc sys tmp etc
打包成cpio镜像,可给QEMU或者烧录到eMMC。
7. ARM Linux 驱动入门(字符设备)
ARM驱动本质和x86驱动逻辑一致,差异主要是:寄存器地址、中断号在设备树里定义。
简单流程:
- 在dts中添加设备节点,分配寄存器、中断
- 内核模块代码:probe函数读取设备树资源,注册字符设备
- 交叉编译内核模块
.ko - 在ARM板子
insmod xxx.ko加载驱动
四、常见坑总结
- 交叉编译运行提示 No such file or directory
最常见:glibc版本不匹配,或者32/64位混淆。优先静态编译-static。 - 内核启动卡在 Starting kernel ...
U-Boot传递的设备树dtb和内核不匹配;bootargs错误;内存地址写错。 - 设备树修改不生效
没有重新编译dtb;U-Boot还是加载旧dtb文件。 - 开发板无法ssh
rootfs缺少ssh服务,或者文件系统权限问题。
五、推荐学习资源
书籍
- 《嵌入式Linux开发实战》(韦东山)——国内嵌入式ARM Linux入门经典
- 《Linux Device Drivers》(LDD3,驱动圣经)
- 《设备树内幕》Device Tree for Dummies
开源项目
- U-Boot:https://github.com/u-boot/u-boot
- Linux内核:kernel.org
- Busybox:busybox.net
开发板推荐
- 入门学习底层:IMX6ULL(资料极多,韦东山配套)
- 性能强:RK3568
- 快速体验:树莓派4B/5
六、下一步,你可以选一个方向深入
- 只想应用开发:用树莓派,ARM64 Debian,直接在板子写程序,不用折腾U-Boot/内核
- 想做嵌入式底层:内核、设备树、U-Boot、驱动(IMX6ULL/RK3568)
- 没有硬件:用 QEMU ARM64 纯模拟器学习整套启动流程
你想从哪一块开始实操?我可以给你对应的完整可复制脚本:
- A:QEMU模拟器一键跑ARM Linux脚本(无硬件)
- B:交叉编译C语言demo
- C:U-Boot完整编译脚本
- D:Busybox最小根文件系统制作脚本