Firefly-RK3399玩机进阶:自己动手编译内核、定制驱动并打包完整固件
Firefly-RK3399深度定制指南从内核编译到固件打包全流程实战在开源硬件的世界里Firefly-RK3399凭借其强大的六核处理器和Mali-T860 GPU成为众多开发者进行嵌入式系统开发的首选平台。但官方提供的预编译系统镜像往往无法满足深度定制需求——无论是为了优化性能、添加特殊硬件支持还是单纯追求极致的系统控制权从源码构建完整系统都是必经之路。本文将带你完整走通从搭建交叉编译环境到生成可刷写固件的全流程重点解决三个核心问题如何为RK3399交叉编译定制内核如何编写并集成自己的内核驱动以及如何将所有组件打包成标准的Rockchip固件格式不同于简单的刷机教程这里每个步骤都包含原理解析和实战技巧适合已经熟悉Linux基础操作、希望完全掌控系统的开发者。1. 开发环境搭建与工具链配置1.1 宿主系统准备推荐使用Ubuntu 18.04 LTS作为开发主机系统这是目前对Rockchip工具链兼容性最好的环境。首先安装基础编译工具sudo apt update sudo apt install -y build-essential git curl lzop libncurses5-dev \ libssl-dev libelf-dev bc flex bison gcc-aarch64-linux-gnu对于64位系统还需安装32位兼容库sudo apt install -y libc6:i386 libstdc6:i386 zlib1g:i3861.2 获取专用工具链Firefly官方提供了优化的交叉编译工具链相比通用工具链包含更多Rockchip特有的优化mkdir -p ~/firefly-dev cd ~/firefly-dev git clone https://gitlab.com/TeeFirefly/prebuilts.git export PATH$PATH:~/firefly-dev/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin验证工具链是否生效aarch64-linux-gnu-gcc --version # 应显示类似以下信息 # aarch64-linux-gnu-gcc (Linaro GCC 6.3-2017.05) 6.3.1 201704041.3 安装固件打包工具Rockchip使用独特的固件打包格式需要专门工具处理git clone https://github.com/rockchip-linux/rkbin.git git clone https://github.com/rockchip-linux/tools.git关键工具说明工具名称作用所在路径rkdeveloptool底层刷写工具tools/linux/Linux_Upgrade_Tool/mkkrnlimg内核镜像打包工具rkbin/tools/resource_tool资源文件处理工具tools/linux/resource_tool/2. 内核源码获取与配置2.1 下载内核源码Firefly维护了针对RK3399优化的内核分支cd ~/firefly-dev git clone --depth1 -b firefly https://gitlab.com/TeeFirefly/linux-kernel.git源码目录关键结构linux-kernel/ ├── arch/arm64/boot/dts/rockchip/ # 设备树文件 ├── drivers/ # 内核驱动目录 ├── include/ # 头文件 └── scripts/ # 编译脚本2.2 内核配置与编译使用Firefly提供的默认配置cd linux-kernel make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- firefly_linux_defconfig常见自定义配置选项CPU调频策略CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMANDGPU驱动CONFIG_DRM_PANFROST文件系统支持CONFIG_OVERLAY_FS开始编译内核和设备树make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- -j$(nproc) rk3399-firefly-linux.img编译产物说明文件名称生成路径作用kernel.imgarch/arm64/boot/压缩内核镜像resource.img打包后生成设备树和启动资源vmlinux根目录调试用未压缩内核3. 驱动开发与内核集成3.1 创建Hello World驱动在drivers/char/下新建hello_firefly/目录创建以下文件hello.c:#include linux/module.h #include linux/init.h static int __init hello_init(void) { printk(KERN_INFO Firefly RK3399: Hello World!\n); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO Firefly RK3399: Goodbye!\n); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Your Name); MODULE_DESCRIPTION(Sample driver for Firefly-RK3399);Makefile:obj-$(CONFIG_HELLO_FIREFLY) hello.oKconfig:config HELLO_FIREFLY tristate Hello Firefly Driver default y help Simple hello world driver for Firefly-RK33993.2 集成驱动到内核修改上级目录的配置在drivers/char/Kconfig中添加source drivers/char/hello_firefly/Kconfig在drivers/char/Makefile中添加obj-$(CONFIG_HELLO_FIREFLY) hello_firefly/重新配置内核make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- menuconfig在Device Drivers - Character devices中启用新驱动标记为[*]。3.3 编译与验证驱动重新编译内核模块make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- modules提取驱动模块find . -name hello.ko # 确认模块路径 aarch64-linux-gnu-objdump -t hello.ko # 验证交叉编译4. 根文件系统定制4.1 构建基础rootfs使用Ubuntu Base创建最小系统cd ~/firefly-dev wget http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-arm64.tar.gz mkdir rootfs sudo tar -xpf ubuntu-base-20.04.1-base-arm64.tar.gz -C rootfs4.2 系统基础配置准备chroot环境sudo cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/ sudo cp -b /etc/resolv.conf rootfs/etc/resolv.conf配置软件源sudo tee rootfs/etc/apt/sources.list EOF deb http://ports.ubuntu.com/ubuntu-ports focal main restricted deb http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted deb http://ports.ubuntu.com/ubuntu-ports focal universe EOF安装基础软件包sudo chroot rootfs /bin/bash apt update apt upgrade -y apt install -y sudo ssh net-tools ethtool wireless-tools \ network-manager iputils-ping rsync vim4.3 创建系统镜像生成EXT4格式镜像dd if/dev/zero ofrootfs.img bs1M count2048 mkfs.ext4 -L rootfs rootfs.img mkdir tmp_mount sudo mount -o loop rootfs.img tmp_mount sudo cp -a rootfs/* tmp_mount/ sudo umount tmp_mount e2fsck -p -f rootfs.img resize2fs -M rootfs.img5. 固件打包与刷写5.1 准备打包组件创建固件组件目录mkdir -p firmware/Image cp linux-kernel/kernel.img firmware/Image/ cp linux-kernel/resource.img firmware/Image/ cp rootfs.img firmware/Image/获取必要的引导文件cp rkbin/rk33/rk3399_loader_v1.24.126.bin firmware/Image/MiniLoaderAll.bin cp rkbin/rk33/rk3399_bl31_v1.35.elf firmware/Image/trust.img5.2 配置打包参数创建package-file# NAME Relative path # # HWDEF HWDEF package-file package-file bootloader Image/MiniLoaderAll.bin parameter Image/parameter.txt trust Image/trust.img uboot Image/uboot.img boot Image/boot.img rootfs Image/rootfs.img示例parameter.txtFIRMWARE_VER: 1.0 MACHINE_MODEL: RK3399 MACHINE_ID: 007 MANUFACTURER: FIRFLY MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE: 3399 CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 TYPE: GPT CMDLINE: storagemediaemmc androidboot.storagemediaemmc androidboot.modenormal5.3 生成完整固件使用RKImageMaker打包tools/linux/afptool/afptool -pack ./firmware/ ./firmware/update.img tools/linux/rkImageMaker/mkimage -rk3399 firmware/Image/MiniLoaderAll.bin firmware/update.img update.img -os_type:androidos最终生成的update.img即可通过Rockchip刷机工具写入设备。6. 高级调试技巧6.1 内核日志实时监控通过串口调试控制台sudo apt install picocom picocom -b 1500000 /dev/ttyUSB0常见调试命令dmesg -w实时内核日志cat /proc/cmdline查看启动参数lsmod查看已加载模块6.2 性能优化参数在/boot/extlinux/extlinux.conf中添加内核参数append rootPARTUUID614e0000-0000 rw rootwait consolettyFIQ0 earlyprintk consoletty1 \ loglevel7 initcall_debug no_console_suspend \ cpufreq.default_governorperformance6.3 常见问题解决驱动加载失败journalctl -k -b 0 # 查看内核日志 modprobe -D hello # 显示依赖关系固件刷写错误确保设备进入Loader模式按住Recovery键上电使用最新版rkdeveloptoolrkdeveloptool ld # 检测设备 rkdeveloptool db MiniLoaderAll.bin rkdeveloptool wl 0 update.img