rk3506 nand开发kernel和root的高效方法
1.现有流程存在主要问题
1.1 标准开发流程回顾
RK3506 NAND开发板的常规调试链路:代码修改 → 打包固件(update.img) → 进入Loader/Maskrom模式 → 使用烧录工具(如RKDevTool) → 等待烧写完成 → 重启验证。
启动源头:BootROM强制从NAND加载ID Block,U-Boot主体运行在NAND中。rk3506的设置造成优先在有idblock的介质上启动,这个是硬件决定的,无法修改
1.2 带来的问题
开发时间问题:每次修改一行代码或一个配置,都要走全流程烧录,烧写速度慢(尤其大固件),对于普通的应用开发还可以通过直接拷贝程序到nand里的方法,还可以接受。如果需要频繁调整boot和rootfs的就很麻烦了
硬件寿命焦虑:NAND Flash擦写次数有限(通常10万次级别),高频调试下虽不至于立即损坏,但心里始终悬着一把“耐久度”的剑。
操作繁琐问题:频繁切换开发板的USB烧录模式、按键组合(如短接RECOVERY),甚至需要反复插拔SD卡(如果用于烧录辅助),物理操作极易疲劳。另外linux下没有sd卡烧写程序,如果在linux下开发需要切换到windows下制作sd卡
故障恢复问题:如果烧录过程中断或固件有问题导致板子变砖,还需要额外的救砖步骤。
2.NFS方案实现rootfs的更新
2.1 NFS方案的主要优点
无需烧录Rootfs,开发机共享文件夹直接挂载,修改代码即刻生效。 网络文件系统非常适合应用层和动态库的调试。 无需要反复烧写nand, 理论上boot可以通过tftp进行加载,但是实际存在如下问题
2.2 RK3506在实际调试中的“拦路虎”
U-Boot阶段网络缺失(核心瓶颈):Rockchip官方SDK提供的RK3506 U-Boot源码中,以太网驱动默认是关闭的(CONFIG_NET及相关PHY驱动未启用)。这意味着U-Boot命令行下无法执行dhcp、tftp、nfs等网络命令,自然也无法从网络加载内核和设备树。 自行开启的隐藏成本:虽然理论上可以在U-Boot中开启CONFIG_NET并编译对应网卡驱动(如dwmac系列),但在RK3506的实际板级适配中,会遇到以下棘手问题: PHY芯片复位管脚配置:不同开发板(如万象奥科、Firefly)使用的PHY型号和复位GPIO各不相同,需要在U-Boot设备树中正确配置reset-gpios和reset-delay等参数。 时钟与时序依赖:GMAC时钟源(如clk_mac_src)的初始化顺序有严格依赖,U-Boot阶段时钟框架不如Linux完善,调试难度较大。 调试成本与收益倒挂:为了解决“少烧录”的问题,反而需要投入大量时间反复烧录U-Boot来调试网络驱动,本末倒置。 所以主要能够方便的加载Rootfs的,可以把rootfs放在自己的硬盘上,每次构建了新的rootfs,就可以把新的rootfs覆盖即可,这样不用反复烧写root了。但是由于启动阶段的网络没有开启只有等到系统启动后Linux内核驱动网卡,NFS Rootfs可以挂载。这就造成一个比较头疼的问题: Boot(内核/设备树)无法更新:依然依赖烧写NAND。
2.3 NFS的改进和存在问题
可以辅助应用调试,但无法解决Boot更新的核心痛点,且boot的更新无法脱离NAND烧录的束缚。
3 SD卡双分区 + extlinux 实现Boot与Rootfs无损更新
3.1 核心思路
依然从SD卡启动机器,在NAND保留U-Boot引导,U-Boot读取SD卡上的内核与Rootfs”。 将SD卡视为一个可插拔的系统盘,所有调试产物都放在SD卡上,NAND只负责“启动引导”这一层。
3.2 Boot更新
SD卡单一Boot分区,直接拷贝 在SD卡上划分一个FAT32分区存放内核(Image)和设备树(.dtb)。 修改NAND中U-Boot的环境变量(bootcmd),指向SD卡分区加载内核。 更新方式:调试时只需拔下SD卡插到电脑,直接拷贝覆盖新的内核或设备树文件,插回板子重启即可。真正实现“拷贝即更新”。
3.3 Rootfs更新
SD卡双Rootfs分区 + extlinux版本切换 为什么需要双分区? 因为Rootfs是EXT4格式且正在运行时无法自我覆盖。如果只有一个分区,新Rootfs无法写入正在运行的系统分区。 分区布局设计: SD卡分区1:FAT32 (存放Boot: Image + dtb + extlinux配置文件) SD卡分区2:EXT4 (Rootfs A) SD卡分区3:EXT4 (Rootfs B) 切换机制(extlinux): 在Boot分区的extlinux/extlinux.conf中,通过配置不同的FDT和APPEND参数,指定root=/dev/mmcblk1p2或/dev/mmcblk1p3。 默认指向当前运行分区(如A)。 更新操作流程: 假设当前运行在Rootfs A。 将新编译的Rootfs直接解压覆盖到Rootfs B分区(对运行中的A系统无任何影响)。 修改extlinux.conf文件中的DEFAULT标签或调整分区指向,重启即可无缝切换到新的Rootfs B。 回滚能力:如果新系统异常,只需在U-Boot命令行临时修改环境变量或开机时选择extlinux菜单,即可切回旧Rootfs A。
3.4 方案终极优势汇总
Boot更新:拷贝即用,无需烧录工具。 Rootfs更新:双分区滚动升级,更新过程不影响当前系统运行,且具备一键回滚能力。 NAND寿命:除首次烧写U-Boot外,调试阶段NAND零写入,彻底解决耐久度焦虑。
3.5 对比方案的优缺点
| 对比维度 | 传统NAND烧录方案 | NFS网络挂载方案 | SD卡双分区方案 |
| Boot(内核/设备树)更新 | 重新打包+烧录全固件 | 无法更新(U-Boot无网络 | ✅ 拷贝覆盖即更新 |
| Rootfs更新 | 重新打包+烧录全固件 | 可以直接挂载到硬盘上,停止系统后直接覆盖root即可 | 双分区滚动更新,不中断当前系统 |
| 是否需要烧录工具 | ✅ 需要(RKDevTool等) | 不需要 | 不需要 |
| NAND擦写损耗 | 🔴 高(每次调试都擦写) | 🟢 较低(只需要boot改写,root不需要) | 极低,正常uboot就可以 |
| 单次更新耗时 | 每次都需要烧写全部固件 | 可以实现root的即时修改,对于boot则无能为力 | 在线修改,启动时切换a b区,还可以分开更新root 和boot |
| 调试中断程度 | 严重,插拔sd卡,还需要全部固件烧写 | 停止系统后更新root就可以,但是无法更新boot, | 在线修改,修改后直接断电或者reboot就可以 |
4 修改的实现
4.1 nfs修改要点
rockchip的uboot的bootfit是自己修改的,需要修改dtsi里的bootargs的内容将其修改为bootargs = "console=ttyFIQ0 root=/dev/nfs rw nfsroot=192.168.31.130:/xxx/nfs_share,v3,tcp ip=192.168.31.50:192.168.31.130:192.168.31.1:255.255.255.0::eth0:off";然后重新编译生成kenrel,再把kernel烧写到nand里就可以了,这里的ip地址可以根据你的实际内容进行调整,这里的nfs路径也是你自己设立nfs的文件夹位置,把rk3506_linux6.1_v1.2.0/buildroot/output/latest/images/rootfs.tar的内容展开到对应的nfs文件夹下就可以,不过此时nfs的连接不能断开,否则就会出错
4.2 sd卡的修改要点
sd卡的启动root和boot思路上面已经说了,主要的思路就是划分分区以后,增加一个boot sd的脚本,同时再通过修改extlinux.conf文件,实现加载不同的root分区。但这里有一个坑,rockchip的uboot已经经过了修改,(我用的启明智显的rk3506开发板)用的是他们提供的百度网盘上的sdk2.0这个版本),正常的miniallloader程序在正常启动的情况下并不会进入uboot程序,而是直接跳转到加载内核然后再加载root,如果光修改uboot增加boot sd脚本和bootcmd没有用,我当时进入了uboot以后直接执行bootsd命令都成功了,但是加在bootcmd中就是无法启动,折腾了半天才发现必须修改spl才可以,最后才搞清楚,只有在启动时候按下了ctrlc按键才能进入uboot,所以需要修改uboot-spl才可以进入标准的uboot,然后就是启动脚本了,具体的方法是:修改/rk3506_linux6.1_v1.2.0/u-boot/arch/arm/mach-rockchip/spl.c程序里的void spl_next_stage(struct spl_image_info *spl)函数,这个函数是在启动的时候检查是否有按键按下,如果有按键才会跳转到uboot的启动过程,否则进入对应启动阶段,在switch case中有一个default,把default对应的语句改成
spl->next_stage = SPL_NEXT_STAGE_UBOOT
这样就会进入uboot了,然后运行uboot下的./make.sh --spl,然后会生成一个
rk3506_spl_loader_v1.06.111.bin
的文件,这个文件用
upgrade_tool UL rk3506_spl_loader_v1.06.111.bin
命令烧写到nand里就可以了,这时候再启动就可以进入uboot了,然后修改文件include.config/rk3506_common.h文件,这段程序是在uboot中增加boot_sd脚本程序,并把bootcmd中增加这个启动脚本
diff --git a/u-boot/include/configs/rk3506_common.h b/u-boot/include/configs/rk3506_common.h index 8d17fcd4c..194eba883 100644 --- a/u-boot/include/configs/rk3506_common.h +++ b/u-boot/include/configs/rk3506_common.h @@ -71,20 +71,32 @@ #include <config_distro_bootcmd.h> +#define RKIMG_SD_BOOT \ + "boot_sd=" \ + "echo Trying SD extlinux boot...; " \ + "mmc dev 0; " \ + "if mmc rescan; then " \ + "sysboot mmc 0:1 fat ${scriptaddr} /extlinux/extlinux.conf; " \ + "fi\0" + #define CONFIG_EXTRA_ENV_SETTINGS \ ENV_MEM_LAYOUT_SETTINGS \ "partitions=" PARTS_RKIMG \ ROCKCHIP_DEVICE_SETTINGS \ + RKIMG_SD_BOOT \ RKIMG_DET_BOOTDEV \ BOOTENV + + + #undef RKIMG_BOOTCOMMAND #ifdef CONFIG_FIT_SIGNATURE #define RKIMG_BOOTCOMMAND \ "boot_fit;" #else #define RKIMG_BOOTCOMMAND \ - "boot_fit;" \ + "run boot_sd;boot_fit;" \ "boot_android ${devtype} ${devnum};" #endif
再运行make.sh命令生成uboot.img,然后用这个uboot.img去更新nand里的uboot,处理用upgradtool烧写以外,还可以直接在开发板进入linux以后烧写,方法是先把生成的uboot.img拷贝到 /tmp下,在命令行输入如下内容 flash_erase /dev/mtd0 0 0 擦除uboot的难度分区,接着调用命令 nandwrite -p /dev/mtd0 /tmp/uboot.img 然后再运行sync命令就更新uboot镜像成功了。接着需要制作sd卡,按照3里面说的划分好分区,其中boot分区格式是fat32,大小为512M,a,b分区可以根据自己需求划分,在boot分区下把zimage(内核)dtb文件拷贝过来,再建一个extlinux的文件夹,然后在里面添加一个extlinux.conf文件,内容如下
DEFAULT roota TIMEOUT 100 MENU TITLE RK3506 boot menu LABEL roota MENU LABEL Linux rootfs A LINUX /zImage FDT /ido-evb3506-v1a-flash-mipi-720x720.dtb APPEND console=ttyS2,1500000 root=PARTUUID=2fca0894-02 rootfstype=ext4 rootwait rw LABEL rootb MENU LABEL Linux rootfs B LINUX /zImage FDT /ido-evb3506-v1a-flash-mipi-720x720.dtb APPEND console=ttyS2,1500000 root=PARTUUID=2fca0894-03 rootfstype=ext4 rootwait rw
这里面dtb的文件可以根据你的实际文件名字填写,timeout是启动时候的延时显示,以100ms为单位,再重新启动就可以看到启动菜单了,更新kernel直接就可以把对应的zimage和dtb文件覆盖到boot分区里就可以,如果想更新root可以把rk3506_linux6.1_v1.2.0/buildroot/output/latest/images/rootfs.tar文件展开覆盖a或b的分区内容就可以,然后修改extlinux.conf文件就可以了,这样就不用拔出sd卡,所有的操作都可以在linux下进行,改好了直接reboot就可以
浙公网安备 33010602011771号