RK3506B — SD启动移植,上电零输入到 shell

RK3506B --- SD启动移植,上电零输入到 shell

RK-Forge准备升级,将扩展到支持更多的RK系列开发板!imx-forge那边也要准备步入应用层开发了!敬请期待~

仓库地址:https://github.com/Awesome-Embedded-Learning-Studio/rk-forge
静态网页:https://awesome-embedded-learning-studio.github.io/rk-forge/
SD-1 在 U-Boot 提示符手敲三行 mmc read 才能把 SD 卡上的 kernel 引起来,每 boot 一次敲一次,调试几轮下来手腕都酸。SD-2 要做的是把这套手敲序列 bake 进 uboot 二进制本身------上电、零输入、自动跑到 buildroot shell。完整记录见 notes/33

为什么是第二份 defconfig,而不是改环境

U-Boot 跑的是 CONFIG_BOOTCOMMAND 那串命令,我们这套板子的 env 又是 nowhere------不向任何介质存环境,所以每次 boot 都跑编译进二进制的默认 bootcmd。而 NAND 那份 defconfig(0003)的 bootcmd 是 mtd read boot ...,从 NAND 读 kernel;SD 这边要的是 mmc read ...,从 SD 卡的 GPT 第二分区读到 kernel FIT。两套 bootcmd 不兼容,硬塞进同一份 defconfig 不行。

可走的路有两条:改环境,或者做 sibling defconfig。env=nowhere 直接把第一条堵死------没有 env 介质就没法在运行时覆盖 bootcmd,能改的只剩编译进二进制那一份默认值。于是正解就是 0005:新增 configs/evb-rk3506_sd_defconfig,跟 NAND 那份除了 bootcmd 完全一样,NAND 的 defconfig 一行不动、NAND 那条 update.img 的 mtd-read 路径保持原样。两份 defconfig 各出一份 uboot(uboot.img / uboot-sd.img),由 pack/assemble 的 --variant sd 选着用。

新 defconfig 的核心就这两行:

复制代码
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="setenv bootargs 'console=ttyS0,1500000 root=/dev/mmcblk0p3 rootwait rw'; \
mmc dev 0; mmc read 0x04000000 0x4000 0x5000; bootm 0x04000000"

bootargs 里 root=/dev/mmcblk0p3 对应 RKFW SD 卡的三分区 GPT 布局------uboot 在 p1、kernel FIT 在 p2、rootfs 在 p3------这是 Ch1 那张卡烧完之后的固定拓扑,跟裸 dd 出来的整盘镜像不是一回事。mmc read 那行三个数也得对上 SD-1 手动验证过的序列:mmc dev 0 选卡、加载偏移 0x4000(扇区号,等于 SD 上 p2 内 kernel FIT 的位置)、读长 0x5000(扇区数,对齐我们 boot.img 的实际尺寸)。最后 bootm 0x04000000 把读进来的 FIT 从那个地址启动------0x04000000 这个暂存地址在内核那一章(boot/03)的"坑之二"里讲过为什么不能放 0x02080000,这里复用同一个避开 kernel load 区的暂存点。

Kbuild 的 trap:out-of-tree 翻车,正解是 git worktree

编第二份 defconfig,第一反应是 out-of-tree build,干净利落:

bash 复制代码
make -C $UBOOT_DIR O=$OUT_DIR/build-uboot-sd evb-rk3506_sd_defconfig
make -C $UBOOT_DIR O=$OUT_DIR/build-uboot-sd ...

Kbuild 直接拒了,错误信息一字不漏贴出来:

复制代码
*** The source tree is not clean, please run 'make ARCH=arm mrproper'
*** in .../third_party/src/uboot

理由很直白:源树里已经有 NAND 那一轮 in-tree build 的产物(u-boot-nodtb.bin、满地的 .ou-boot.cfg 那些),Kbuild 不许在脏源树上做 out-of-tree 构建。它让咱们 make mrproper 清干净------可 mrproper 一跑,NAND 那一份产物全毁,紧接着的 NAND pack-fit 直接断链。这条死路咱们怎么走都破不了:要么 Kbuild 拒,要么毁 NAND。

⚠️ 这里千万别想着"那我先编 SD、再编 NAND 顺序来"------两个 defconfig 在同一棵源树里 in-tree build,后编的照样覆盖前一个的产物,pack-fit 拿到的是错的二进制。

解法是 git worktree。同一 HEAD 上开一份干净的工作树,源树在那份工作树里是 pristine 的(git 跟踪状态干净、没有任何 build artifact),in-tree build 在那棵新树里跑,NAND 那棵树一根毛都不动。命令序列精简成这样:

bash 复制代码
git -C $UBOOT_DIR worktree add --detach $WT_DIR HEAD
# 在 $WT_DIR 里 in-tree build evb-rk3506_sd_defconfig
# 把产物 u-boot-sd-nodtb.bin + u-boot-sd.dtb 拷到 $OUT_DIR
git -C $UBOOT_DIR worktree remove --force $WT_DIR   # trap on exit,无论成败都收

--detach 是为了脱离任何分支引用------我们就是想就地编一份 SD uboot,不想动当前 checkout 也不想要新分支。编完 worktree remove --force 把这棵临时树收掉,bash 这边记得用 trap,免得中途脚本挂了留下脏 worktree 把后续 git 操作搞糊涂。tools/mkimage 两份 defconfig 共用(差的就是 bootcmd 那一行,mkimage 调用方式不变)。

成功长这样

SD defconfig 编出来的 uboot-sd.img 烧进 update-sd.img、RK 工具把卡写好、上电------这次一个键都不用敲,boot-sdl-2026-06211109 就是 SD-2 的全自动 boot:

复制代码
Hit any key to stop autoboot: 0          ← 倒计时归零,没人按键
mmc0 is current device
MMC read: dev # 0, block # 16384, count 20480 ... 20480 blocks read: OK
## Loading kernel from FIT Image at 04000000 ...
Starting kernel ...
EXT4-fs (mmcblk0p3): mounted filesystem ... r/w
VFS: Mounted root (ext4) on device 179:3
rk3506 login: root

block # 16384 就是 0x4000count 20480 就是 0x5000------bootcmd 里那两个数原样落到串口上,编译进二进制的 mmc read 跑通了。autoboot 倒计时归零、=> 提示符一次都没出现,U-Boot 直接执行 baked-in 的 bootcmd:mmc 选卡、读 kernel FIT、bootm 跳过去、内核挂上 SD 卡 p3 那份 ext4 rootfs、/sbin/init 起来、落 login。零输入、全自动、跨冷重启可复现。SD 这条路(Ch1 手动 + 这里自动)到此收口。

相关推荐
阿扬ABCD18 小时前
ipmitool的Windows版本编译
windows·驱动开发
带娃的IT创业者1 天前
原生体验的回归:深入解析 TREK —— 专为 Apple Silicon 打造的轻量级容器方案
macos·docker·虚拟化·开源项目·容器化·apple silicon·trek
charlie1145141912 天前
现代C++工程实践 WeakPtr 实战(三):WeakPtrFactory 与「最后成员」惯用法
开发语言·c++·开源项目·现代c++
编程圈子2 天前
电机驱动开发学习19. 霍尔 BLDC 三段式 FOC 启动算法
驱动开发·学习·算法
深念Y2 天前
AI编程Agent工具定义对比分析
agent·ai编程·开源项目·工具·tool·hermes·ccsiwtch
咖啡星人k3 天前
MonkeyCode 架构深度解析:SDD 规范驱动开发的工程哲学
驱动开发·架构·monkeycode
小此方3 天前
Re:Linux系统篇(四十六)信号篇·四:一文串联操作系统底层:时钟中断、内核态切换、系统调用与 Linux 信号处理全解析
linux·驱动开发·信号处理
qetfw4 天前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
qetfw4 天前
MWU:Vue 3 + FastAPI 的 MaaFramework 跨平台 WebUI 源码
前端·vue.js·python·fastapi·开源项目·效率工具