2. 开发环境准备:安装Ubuntu虚拟机、配置国内软件源、安装必要的开发工具
嵌入式Linux驱动开发的第一道门槛是搭建一个稳定、可复现的编译与调试环境。由于驱动模块与内核版本强绑定,且编译过程需要完整的Linux内核头文件与工具链,因此推荐在 Ubuntu 22.04 LTS 虚拟机中进行开发。本章将指导你完成从虚拟机安装到工具链验证的全流程。
为什么选择虚拟机而非WSL或双系统? 虚拟机支持快照回滚,可在实验内核崩溃时秒级恢复;同时便于模拟不同硬件平台(ARM、RISC-V)的交叉编译环境,是驱动开发初学者的最佳起点。
2.1 安装Ubuntu虚拟机
推荐使用 VMware Workstation Pro 或 VirtualBox 7.0+ 作为虚拟化平台。以下步骤以VirtualBox为例,VMware操作类似。
- 下载Ubuntu Server 22.04 LTS ISO(约2.5GB),选择64-bit (x86) 版本。
- 创建虚拟机:分配至少 2核CPU、4GB内存、40GB动态扩展磁盘。
- 安装系统:挂载ISO启动,选择“最小化安装”,不安装图形桌面以节省资源。
- 设置网络:使用 桥接模式 使虚拟机获得独立IP,便于后续SSH调试。
- 安装增强功能(Guest Additions):实现剪贴板共享、自适应窗口和更好的性能。
磁盘空间建议: 编译一次完整Linux内核(约6.5万源文件)需要至少15GB空闲空间。40GB磁盘可容纳3~4个不同版本的内核源码树。
2.2 配置国内软件源
Ubuntu默认使用官方源(archive.ubuntu.com),从国内下载速度较慢。更换为国内镜像源可将 apt update 和 apt install 的速度提升5~10倍。
2.2.1 备份原始源列表
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
2.2.2 替换为阿里云镜像源
使用 sed 命令一键替换:
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
2.2.3 更新软件包索引
sudo apt update
注意: 如果使用Ubuntu 24.04或更新版本,源格式已改为
deb.sury.org 或 ports.ubuntu.com,请根据版本选择对应镜像。建议始终使用 LTS版本(如22.04、24.04),非LTS版本内核更新过快,驱动兼容性较差。
2.3 安装必要的开发工具
驱动开发需要完整的编译工具链和版本管理工具。以下工具是内核模块编译的 最小必要集合:
| 工具 | 版本要求 | 用途 | 安装命令 |
|---|---|---|---|
| gcc | ≥ 11.4 | C语言编译器,编译内核模块 | sudo apt install gcc |
| make | ≥ 4.3 | 构建自动化,解析Kbuild/Makefile | sudo apt install make |
| git | ≥ 2.34 | 版本控制,管理内核源码与驱动代码 | sudo apt install git |
| vim | ≥ 8.2 | 代码编辑,查看内核源码 | sudo apt install vim |
| linux-headers | 与内核版本一致 | 提供内核符号表与头文件,编译模块必需 | sudo apt install linux-headers-$(uname -r) |
2.3.1 一键安装命令
sudo apt install -y gcc make git vim linux-headers-$(uname -r)
2.3.2 验证安装版本
gcc --version
make --version
git --version
vim --version | head -n 1
ls -l /lib/modules/$(uname -r)/build
关键检查点:
/lib/modules/$(uname -r)/build 必须是一个指向内核源码/头文件目录的符号链接。如果该目录不存在或为空,则无法编译任何内核模块。此时需要手动安装对应版本的内核头文件包。
2.4 验证开发环境
编写一个最简单的内核模块“Hello World”,验证整个工具链是否正常工作。这是驱动开发者的 “仪式感” 测试。
2.4.1 创建模块源码
mkdir -p ~/kernel-dev/hello && cd ~/kernel-dev/hello
cat > hello.c << 'EOF'
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init hello_init(void)
{
printk(KERN_INFO "Hello, Embedded Driver World!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, Embedded Driver World!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Hello World kernel module");
EOF
2.4.2 创建Makefile
cat > Makefile << 'EOF'
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
EOF
2.4.3 编译并测试
make
sudo insmod hello.ko
sudo rmmod hello.ko
dmesg | tail -n 2
如果dmesg输出显示 Hello, Embedded Driver World! 和 Goodbye, Embedded Driver World!,则说明开发环境搭建成功。
常见错误: 如果
make 报错 Cannot use CONFIG_CC_STACKPROTECTOR_STRONG,说明gcc版本与内核配置不匹配。解决方案:安装与当前内核版本完全一致的 linux-headers 包,或升级gcc到11.4以上版本。
2.5 环境检查清单
完成本章后,请逐项确认以下条件是否满足:
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| 虚拟机网络连通 | ping -c 3 8.8.8.8 |
0% packet loss |
| 国内源生效 | apt update 速度 |
≥ 1 MB/s |
| gcc可用 | gcc --version |
显示版本号 ≥ 11.4 |
| 内核头文件就绪 | ls /lib/modules/$(uname -r)/build |
目录存在且非空 |
| 模块编译成功 | make 无报错 |
生成 hello.ko |
| 模块加载/卸载 | insmod/rmmod + dmesg |
打印Hello/Goodbye消息 |