1. SDK初探
1.1 到底什么是嵌入式Linux SDK?
说实话,我刚入行那会儿,也被「SDK」这个词搞得云里雾里的。听着挺高大上,其实说白了——嵌入式Linux SDK就是一套让你能在PC上开发、编译、调试嵌入式设备的工具集合。
你想想看,嵌入式设备(比如路由器、机顶盒、智能摄像头)的CPU架构通常是ARM、MIPS或者RISC-V。你的PC是x86架构。直接在PC上编译出来的程序,设备跑不了。怎么办?
SDK就是来解决这个问题的。它包含:
- 交叉编译工具链(编译器、链接器、调试器)
- 目标系统的头文件和库
- 构建脚本和配置文件
- 一些实用工具(比如烧录工具、调试工具)
核心理解:SDK = 交叉编译工具链 + 目标系统根文件系统 + 构建系统。缺一不可。
我个人习惯把SDK比作「翻译官」。你在PC上写代码,SDK帮你翻译成设备能听懂的语言。没有它,你写的程序就是一堆废纸。
1.2 SDK的典型目录结构
不同芯片厂商的SDK长得不太一样,但骨架基本一致。我拿一个典型的全志/瑞芯微SDK举例:
sdk_root/
├── build/ # 构建脚本和配置文件
│ ├── configs/ # 板级配置(板子型号、内核配置)
│ └── toolchain/ # 工具链构建脚本
├── kernel/ # Linux内核源码
│ ├── arch/ # 架构相关代码(arm64、riscv等)
│ └── drivers/ # 设备驱动
├── u-boot/ # 引导加载程序
├── buildroot/ # 根文件系统构建工具(或Yocto)
├── output/ # 编译输出目录
│ ├── images/ # 最终镜像文件(boot.img、rootfs.img)
│ └── staging/ # 目标系统的头文件和库
├── tools/ # 主机端工具(烧录、调试)
├── external/ # 第三方软件包
└── docs/ # 文档(嗯,通常比较简陋)
这里我特别想强调output/staging这个目录。很多新手会忽略它,但它其实是你交叉编译时最常打交道的地方。里面放着目标系统的usr/include和usr/lib——说白了,就是你在PC上编译程序时,需要链接的那些库和头文件。
我的经验:拿到一个陌生SDK,先看build/configs/目录。里面通常有defconfig文件,记录了板子的硬件配置。我当年接手一个项目,板子死活起不来,最后发现是DDR配置参数写错了。嗯,从那以后我养成了先看配置文件的习惯。
1.3 如何获取和安装SDK
获取SDK的途径,我总结下来就三种:
- 芯片厂商官方提供(最常见)—— 比如全志的Tina SDK、瑞芯微的RK SDK。去官网注册开发者账号,下载即可。
- 开发板厂商提供—— 比如树莓派、BeagleBone。通常在官网的「Downloads」或「Resources」页面。
- 自己从开源社区构建—— 用Buildroot或Yocto自己定制。适合有特殊需求的团队。
安装SDK,我建议按这个步骤来:
# 1. 解压SDK(通常是个tar.gz包)
tar -xzf sdk_xxx.tar.gz -C ~/workspace/
# 2. 安装依赖(不同发行版略有差异)
sudo apt-get install build-essential git libncurses-dev flex bison
# 3. 设置环境变量(我习惯写在~/.bashrc里)
export SDK_PATH=~/workspace/sdk_root
export PATH=$SDK_PATH/tools:$PATH
# 4. 验证安装
arm-linux-gnueabihf-gcc --version
注意:我曾经在一个Ubuntu 22.04系统上装了个老旧的SDK,结果编译报错——因为新系统的glibc版本太高,和老工具链不兼容。解决办法是用Docker创建一个Ubuntu 18.04的环境。所以,SDK的安装环境最好和厂商推荐的保持一致。
1.4 搭建交叉编译环境
交叉编译环境,说白了就是让你的PC能编译出目标设备能运行的程序。核心就三步:
1.4.1 确认工具链前缀
不同架构的工具链前缀不一样:
| 目标架构 | 工具链前缀 | 示例 |
|---|---|---|
| ARM 32位 | arm-linux-gnueabihf- | arm-linux-gnueabihf-gcc |
| ARM 64位 | aarch64-linux-gnu- | aarch64-linux-gnu-gcc |
| MIPS | mips-linux-gnu- | mips-linux-gnu-gcc |
| RISC-V 64位 | riscv64-linux-gnu- | riscv64-linux-gnu-gcc |
1.4.2 编写一个简单的测试程序
我习惯先写个Hello World验证环境:
// hello.c
#include <stdio.h>
int main() {
printf("Hello from Embedded Linux!\n");
return 0;
}
# 交叉编译
arm-linux-gnueabihf-gcc -o hello hello.c
# 查看生成的文件信息
file hello
# 输出:ELF 32-bit LSB executable, ARM, version 1 (SYSV)
看到ARM字样,说明编译成功了。如果显示x86-64,那就是用了本机编译器——嗯,我刚开始也犯过这个错。
1.4.3 配置环境变量(一劳永逸)
每次编译都敲一长串前缀太麻烦。我建议这样:
# 在~/.bashrc中添加
export CROSS_COMPILE=arm-linux-gnueabihf-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export AR=${CROSS_COMPILE}ar
export LD=${CROSS_COMPILE}ld
# 然后
source ~/.bashrc
# 之后编译就可以直接用$CC了
$CC -o hello hello.c
避坑指南:我曾经在一个项目里,直接用了gcc而不是$CC,结果编译出来的程序在板子上跑不了。查了半天才发现是用了本机编译器。所以,每次编译前,确认一下$CC指向的是交叉编译器。养成习惯,能省很多时间。
1.5 本章知识体系
下面这张图,是我自己总结的SDK核心逻辑。你看一眼,就能把整章内容串起来:
这张图把SDK的整个工作流讲清楚了:PC上开发 → SDK编译 → 生成镜像 → 设备运行。你只要记住这个流程,后面学起来就顺了。
好了,这一章就到这里。SDK的安装和交叉编译环境搭建,是后续所有优化的基础。别嫌麻烦,把这一步走稳了,后面才能跑得快。
可可精品资料库