基于 RK3568 芯片实现 Linux 5.10 内核移植与驱动适配
核心流程是「环境搭建 → BSP 准备 → U-Boot 适配 → 内核移植(设备树为核心)→ 驱动开发 / 适配 → 根文件系统制作 → 烧录验证」。RK3568 作为 Rockchip 主流中低端嵌入式芯片,官方提供完善的 BSP 支持,无需从零开发,重点在于「设备树适配」和「驱动参数调优」。
详细记录了基于 RK3568 芯片的嵌入式 Linux 5.10 内核移植全过程。内容涵盖 Ubuntu 开发环境搭建、交叉编译工具链配置、U-Boot 编译与适配、内核设备树(DTS)修改以及根文件系统制作。重点实现了 V4L2 摄像头、I2C 温湿度传感器及 HDMI 显示驱动的适配与验证。最后提供烧录镜像步骤及常见启动失败、驱动加载问题的排查方案,适合安防等领域嵌入式开发参考。
核心流程是「环境搭建 → BSP 准备 → U-Boot 适配 → 内核移植(设备树为核心)→ 驱动开发 / 适配 → 根文件系统制作 → 烧录验证」。RK3568 作为 Rockchip 主流中低端嵌入式芯片,官方提供完善的 BSP 支持,无需从零开发,重点在于「设备树适配」和「驱动参数调优」。
| 类别 | 具体要求 |
|---|---|
| 主机系统 | Ubuntu 20.04/22.04(64 位,兼容性最佳,避免编译依赖冲突) |
| 交叉编译工具链 | aarch64-linux-gnu-gcc(Linaro 11.3 或 Rockchip 官方工具链,适配 ARMv8-A) |
| 依赖工具 | git make gcc flex bison dtc libssl-dev ncurses-dev parted dosfstools |
| 烧录工具 | RKDevTool(Windows/Linux)、SD Card Formatter(SD 卡烧录) |
| BSP 源码 | Rockchip 官方 Linux 5.10 内核(linux-rockchip)、U-Boot(u-boot-rockchip) |
| 根文件系统工具 | Buildroot 2022.02+(轻量快速,适合嵌入式)或 Yocto(复杂场景) |
sudo apt update && sudo apt install -y git make gcc flex bison dtc libssl-dev \
ncurses-dev parted dosfstools mkbootimg u-boot-tools device-tree-compiler \
python3-pip python3-setuptools
推荐使用 Rockchip 官方工具链(适配性更好):
# 下载工具链(ARMv8-A,支持 aarch64)
wget https://releases.linaro.org/components/toolchain/binaries/11.3.1-1/aarch64-linux-gnu/aarch64-linux-gnu-gcc-11.3.1.tar.xz
# 解压到 /opt 目录
sudo tar -xvf aarch64-linux-gnu-gcc-11.3.1.tar.xz -C /opt/
# 配置环境变量(临时生效,永久生效需写入 ~/.bashrc)
export PATH=/opt/aarch64-linux-gnu-gcc-11.3.1/bin:$PATH
# 验证工具链(输出版本即成功)
aarch64-linux-gnu-gcc -v
RK3568 的 Linux 5.10 内核、U-Boot 源码已在官方仓库维护,直接克隆即可:
# 创建工作目录
mkdir rk3568_project && cd rk3568_project
# 下载 Linux 5.10 内核(rk356x 分支对应 RK3568/3566)
git clone -b linux-5.10-gen-rkr4 https://github.com/rockchip-linux/linux.git
# 下载 U-Boot(支持 RK3568)
git clone -b master https://github.com/rockchip-linux/u-boot.git
# 下载设备树配置文件(可选,官方内核已包含基础 DTS)
git clone https://github.com/rockchip-linux/rkbin.git # 包含固件、设备树二进制
U-Boot 负责「初始化硬件 → 加载内核 → 引导根文件系统」,RK3568 官方 U-Boot 已适配核心硬件,只需简单配置编译:
cd u-boot
# 加载 RK3568 开发板默认配置(以 EVB1 开发板为例,根据实际硬件选择)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3568-evb1-ddr4-1008mhz_defconfig
# (可选)自定义配置(如启用 SD 卡启动、串口调试)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
关键配置项:Boot options → Default boot device(选择 SD 卡/eMMC)、Serial console(启用 UART0 作为调试串口)。
# 编译(-j 后面跟主机 CPU 核心数,加速编译)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
# 生成产物(关键文件):
# u-boot.bin(U-Boot 二进制)、idbloader.img(RK 芯片启动引导)、u-boot.itb(集成设备树的镜像)
RK 芯片需要「idbloader + u-boot.itb」组合才能启动,使用官方工具生成:
# 进入 rkbin 目录(之前克隆的)
cd ../rkbin
# 生成 idbloader.img(适配 RK3568)
./tools/mkimage -n rk3568 -T rksd -d bin/rk3568_ddr4_1008MHz_v1.16.bin:bin/rk3568_miniloader_v1.28.bin ../u-boot/idbloader.img
内核移植的核心是「设备树(DTS)配置」—— 告诉内核 RK3568 的硬件资源(GPIO、I2C 控制器、CSI 接口、HDMI 引脚等),驱动仅需基于设备树做少量适配(官方内核已包含 RK3568 大部分驱动框架)。
cd ../linux # 进入内核源码目录
# 加载 RK3568 默认配置(官方预配置,包含核心驱动框架)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rockchip_defconfig
# 自定义配置(启用三大驱动相关选项)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
关键配置项(必须启用):
| 驱动类型 | 配置路径与选项 |
|---|---|
| V4L2 摄像头 | Device Drivers → Multimedia support → V4L2 sub-device userspace API(勾选) → Camera sensors support(勾选对应摄像头型号,如 OV5640/IMX219) |
| I2C 子系统 | Device Drivers → I2C support → I2C bus support(勾选 RK3568 I2C 控制器,如 i2c-rockchip) |
| HDMI 显示 | Device Drivers → Graphics support → DRM (Direct Rendering Manager)(勾选) → Rockchip DRM support(勾选) → HDMI/DP support(勾选 DW HDMI 或 Rockchip HDMI) |
RK3568 的设备树文件在 arch/arm64/boot/dts/rockchip/ 目录下,基础设备树为 rk3568.dtsi(公共配置),开发板级设备树为 rk3568-evb1-ddr4.dts(基于 EVB1 开发板,需根据实际硬件修改)。核心操作:修改开发板设备树(rk3568-evb1-ddr4.dts)。
需添加 / 修改「摄像头 CSI 节点、I2C 传感器节点、HDMI 输出节点」,以下是关键节点示例:
RK3568 集成 DW HDMI 控制器,官方内核已包含驱动,只需在设备树中启用 HDMI 引脚和分辨率:
// 在 rk3568-evb1-ddr4.dts 中添加/修改
&hdmi {
status = "okay"; // 启用 HDMI 控制器
rockchip,hdmi-output = <1>; // 启用 HDMI 输出
hdmi_phy: hdmi-phy {
status = "okay";
compatible = "rockchip,rk3568-hdmi-phy";
reg = <0xfb800000 0x10000>;
clocks = <&cru CLK_HDMI_PHY>, <&cru CLK_HDMI_PLL>;
clock-names = "phy", "pll";
#phy-cells = <0>;
};
};
// 配置 HDMI 引脚(参考 RK3568 datasheet,确认引脚复用)
&pinctrl {
hdmi {
hdmi_tx_pin: hdmi-tx-pin {
rockchip,pins = <
RK_PB0 1 &pcfg_pull_none_drv_level_3 // HDMI_TX_CLK+
RK_PB1 1 &pcfg_pull_none_drv_level_3 // HDMI_TX_CLK-
RK_PB2 1 &pcfg_pull_none_drv_level_3 // HDMI_TX0+
RK_PB3 1 &pcfg_pull_none_drv_level_3 // HDMI_TX0-
// … 其他 HDMI 数据引脚(参考 datasheet 补充)
>;
};
};
};
确认传感器连接的 I2C 总线(如 I2C1),在设备树中添加传感器节点:
// 在 &i2c1 节点下添加 SHT30 节点
&i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c1m0_xfer>; // 复用 I2C1 引脚(参考基础 DTS)
clock-frequency = <100000>; // I2C 速率 100KHz
sht30@44 { // SHT30 的 I2C 从地址是 0x44
compatible = "sensirion,sht30"; // 驱动匹配名(需与驱动代码一致)
reg = <0x44>; // I2C 地址
status = "okay"; // (可选)中断引脚配置(如果传感器支持中断)
interrupt-parent = <&gpio0>;
interrupts = <RK_PA0 IRQ_TYPE_EDGE_RISING>;
};
};
驱动适配:如果内核已包含 SHT30 驱动(drivers/i2c/busses/i2c-rockchip.c + drivers/hwmon/sht3x.c),无需额外开发,仅需确保 compatible 字段匹配;若未包含,需编写简单的 I2C 子系统驱动(实现 probe/read 函数)。
RK3568 支持 CSI-2 接口,摄像头通常通过「CSI + I2C」连接(I2C 配置摄像头寄存器,CSI 传输图像数据):
设备树添加 CSI 控制器和摄像头节点:
// 启用 CSI 控制器
&csi2_dphy0 {
status = "okay";
};
&rkisp1 {
status = "okay";
ports {
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
csi2_rx0: endpoint@0 {
reg = <0>;
remote-endpoint = <&ov5640_ep>; // 关联摄像头端点
data-lanes = <1 2>; // CSI 数据 lanes(根据硬件连接配置)
};
};
};
};
// 添加 OV5640 摄像头节点(I2C 控制)
&i2c2 { // 摄像头连接的 I2C 总线
status = "okay";
ov5640: camera@3c { // OV5640 的 I2C 地址是 0x3C
compatible = "ovti,ov5640";
reg = <0x3c>;
status = "okay";
clocks = <&cru CLK_CAM0_OUT>;
clock-names = "xclk";
pinctrl-names = "default";
pinctrl-0 = <&cam0_clk>;
port {
ov5640_ep: endpoint {
remote-endpoint = <&csi2_rx0>;
data-lanes = <1 2>;
clock-lanes = <0>;
link-frequencies = /bits/ 64 <480000000>; // 链路频率(参考摄像头 datasheet)
};
};
};
};
驱动适配:内核已包含 OV5640 的 V4L2 驱动(drivers/media/i2c/ov5640.c),需确保驱动的 of_device_id 与设备树 compatible 匹配:
// ov5640.c 中的匹配表(无需修改,默认已支持)
static const struct of_device_id ov5640_of_match[] = {
{ .compatible = "ovti,ov5640" },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, ov5640_of_match);
# 编译内核镜像(Image 或 zImage,RK3568 支持 Image)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image -j$(nproc)
# 编译设备树(生成 dtb 文件)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs -j$(nproc)
# 编译内核模块(后续安装到根文件系统)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules -j$(nproc)
编译产物(关键文件):
arch/arm64/boot/Imagearch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4.dtbdrivers/ 目录下的 .ko 文件(如 I2C 传感器模块、摄像头模块)根文件系统是嵌入式 Linux 的运行环境,包含 shell、库文件、应用程序,用 Buildroot 可快速生成适配 RK3568 的根文件系统:
# 回到工作目录,下载 Buildroot
cd ../
wget https://buildroot.org/downloads/buildroot-2022.02.12.tar.bz2
tar -xvf buildroot-2022.02.12.tar.bz2 && cd buildroot-2022.02.12
# 配置 Buildroot(选择 RK3568 目标平台)
make menuconfig
关键配置项:
/opt/aarch64-linux-gnu-gcc-11.3.1/binaarch64-linux-gnu-make -j$(nproc)
# 生成产物:output/images/rootfs.ext4(根文件系统镜像)
将编译好的内核模块复制到根文件系统,确保驱动模块能被加载:
# 回到内核源码目录,执行模块安装命令(DESTDIR 指定根文件系统路径)
cd ../linux
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install \
DESTDIR=../buildroot-2022.02.12/output/target/
选择 SD 卡(推荐 8GB+),用 SD Card Formatter 格式化为 FAT32。用 fdisk 工具将 SD 卡分区(可选,Buildroot 生成的根文件系统可直接烧录):
# 确认 SD 卡设备名(如 /dev/sdb,用 lsblk 查看,避免误烧)
SD_DEVICE=/dev/sdb
# 烧录 idbloader.img(U-Boot 引导,偏移 64KB)
sudo dd if=../u-boot/idbloader.img of=$SD_DEVICE seek=64 bs=512
# 烧录 u-boot.itb(U-Boot 镜像,偏移 16384KB)
sudo dd if=../u-boot/u-boot.itb of=$SD_DEVICE seek=16384 bs=512
# 烧录内核镜像(偏移 24576KB)
sudo dd if=arch/arm64/boot/Image of=$SD_DEVICE seek=24576 bs=512
# 烧录设备树(偏移 32768KB)
sudo dd if=arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4.dtb of=$SD_DEVICE seek=32768 bs=512
# 烧录根文件系统到分区 2
sudo dd if=../buildroot-2022.02.12/output/images/rootfs.ext4 of=${SD_DEVICE}2 bs=1M
将 SD 卡插入 RK3568 开发板,连接串口(调试用)、HDMI 显示器、摄像头、I2C 传感器。上电启动,通过串口工具(如 Minicom,波特率 115200)查看启动日志。
驱动验证命令:
| 驱动类型 | 验证步骤与命令 |
|---|---|
| HDMI 输出 | 启动后观察显示器是否有画面;串口执行 drm-info 查看 DRM 显示节点是否正常 |
| I2C 传感器 | 1. 查看 I2C 总线:i2cdetect -l(确认 i2c1/i2c2 存在)2. 扫描设备: i2cdetect -y 1(看到 0x44 即 SHT30 识别成功)3. 读取数据: i2cget -y 1 0x44 0x2C 0x06(根据传感器协议读取) |
| V4L2 摄像头 | 1. 查看摄像头设备:v4l2-ctl --list-devices(看到 /dev/video0 即成功)2. 采集图像: v4l2-ctl --stream-mmap --stream-count=1 --stream-to=test.jpg(生成 test.jpg 即采集正常) |
dmesg | grep -i error 查看驱动加载日志,常见原因:设备树 compatible 与驱动不匹配、引脚复用冲突、硬件接线错误。基于 RK3568 实现目标需求的核心是「依托官方 BSP 减少重复开发,聚焦设备树适配」:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online