RK3568 Linux驱动开发实战:从SDK环境搭建到模块编译全流程
1. RK3568 Linux驱动开发环境搭建
第一次接触RK3568驱动开发时,我被官方SDK的庞大规模震撼到了——整整35GB的源码包!不过别担心,跟着我的步骤走,30分钟就能搞定基础环境。我用的是一台16核32G内存的Ubuntu 20.04主机,实测8G内存的虚拟机也能跑,但编译时间会翻倍。
核心依赖安装是第一步,这个命令集合了瑞芯微官方推荐和我的经验补充:
sudo apt-get install -y git ssh make gcc libssl-dev liblz4-tool expect \
g++ patchelf chrpath gawk texinfo diffstat binfmt-support \
qemu-user-static live-build bison flex fakeroot cmake \
unzip device-tree-compiler python3-pip libncurses-dev
特别注意Python版本问题:RK3568 SDK对Python2.7有强依赖,但Ubuntu 20.04默认只有Python3。我的解决方案是:
sudo apt-get install python2.7
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
2. SDK获取与初始化
正点原子提供的SDK压缩包(约15GB)解压后,关键目录结构是这样的:
rk3568_linux_sdk/
├── .repo/ # 多仓库管理元数据
├── buildroot/ # 根文件系统构建
├── device/ # 板级配置文件
├── kernel/ # Linux 4.19内核
├── prebuilts/ # 交叉编译工具链
└── u-boot/ # Bootloader源码
初始化SDK时容易卡在repo sync步骤,这里有个加速技巧:
cd ~/rk3568_linux_sdk
.repo/repo/repo sync -l -j$(nproc) --no-tags
遇到网络中断时,用这个命令续传:
.repo/repo/repo sync -c -j$(nproc) --no-clone-bundle
3. 驱动开发环境配置
交叉编译器配置是驱动开发的关键。SDK自带的工具链路径在:
prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/
建议把工具链加入环境变量:
export PATH=$PATH:~/rk3568_linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
export CROSS_COMPILE=aarch64-linux-gnu-
验证工具链是否生效:
aarch64-linux-gnu-gcc --version
# 应该显示 Linaro GCC 6.3.1
4. 内核模块开发实战
以最简单的LED驱动为例,在kernel/drivers/char/下新建rk_led.c:
#include <linux/module.h>
#include <linux/fs.h>
static int major;
static struct class *led_class;
static int led_open(struct inode *inode, struct file *filp) {
printk("LED device opened\n");
return 0;
}
static struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
};
static int __init led_init(void) {
major = register_chrdev(0, "rk_led", &led_fops);
led_class = class_create(THIS_MODULE, "rk_led_class");
device_create(led_class, NULL, MKDEV(major, 0), NULL, "rk_led");
return 0;
}
static void __exit led_exit(void) {
device_destroy(led_class, MKDEV(major, 0));
class_destroy(led_class);
unregister_chrdev(major, "rk_led");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
对应的Makefile配置:
obj-$(CONFIG_RK_LED) += rk_led.o
在kernel/drivers/char/Kconfig中添加:
config RK_LED
tristate "RK3568 LED Driver"
default y
help
Simple LED driver for RK3568
5. 模块编译与加载
内核配置是第一步:
cd ~/rk3568_linux_sdk/kernel
make ARCH=arm64 rockchip_linux_defconfig
make ARCH=arm64 menuconfig
在Character devices中找到我们的驱动选项,按Y键编译进内核,或M键编译为模块。
单独编译模块的命令:
./build.sh kernel
./build.sh modules
编译好的模块会在kernel/drivers/char/rk_led.ko,通过adb推送到开发板:
adb push rk_led.ko /data
adb shell insmod /data/rk_led.ko
查看驱动是否加载成功:
adb shell ls /dev/rk_led
adb shell dmesg | grep LED
6. 驱动调试技巧
printk日志分级很实用,在驱动中添加:
printk(KERN_DEBUG "Debug message\n"); // 级别0
printk(KERN_INFO "Info message\n"); // 级别4
printk(KERN_ERR "Error message\n"); // 级别3
通过adb shell cat /proc/sys/kernel/printk查看当前日志级别,修改级别过滤低优先级信息:
adb shell "echo 4 4 1 7 > /proc/sys/kernel/printk"
Oops分析是驱动开发必备技能。当内核崩溃时,用这个命令保存现场:
adb shell "cat /proc/vmcore > /data/vmcore"
然后用SDK中的工具链分析:
aarch64-linux-gnu-gdb vmlinux
(gdb) core-file vmcore
7. 固件打包与烧写
全编译命令会生成完整固件:
./build.sh all
./mkfirmware.sh
生成的固件在rockdev/目录下,关键文件:
MiniLoaderAll.bin:一级loaderuboot.img:U-Boot镜像boot.img:内核镜像rootfs.img:根文件系统
使用rkdeveloptool烧写镜像:
rkdeveloptool db MiniLoaderAll.bin
rkdeveloptool ul boot.img
rkdeveloptool ul rootfs.img
遇到烧写失败时,尝试进入MaskROM模式:短接开发板上的测试点,同时上电。
更多推荐

所有评论(0)