
做RK3568方案的这半年我记不清被parameter.txt折腾过多少回了。表面看这就是一个几百行的文本文件搞懂它之前调分区、调启动、调系统大小全靠瞎蒙搞懂之后很多问题其实都是同一个根源。如果你正在用瑞芯微RK3568开发板跑Android11想自己改改分区、压缩缓存、扩userdata或者想知道系统到底是怎么知道该从哪块区域启动的这篇文章值得你花十五分钟读完。我会从启动链路开始讲把parameter.txt的每一行、每个十六进制数都拆开说明白最后附上我在实际项目中踩过的坑和排查思路。1. 先搞清楚parameter.txt在启动链路中的角色1.1 这个文件为什么能“牵一发动全身”Rockchip平台的Android启动链路里有一个固定顺序BootROM从eMMC/NAND最前面的固定位置加载MiniLoaderMiniLoader再加载U-BootU-Boot读取parameter.txt拿到分区表根据分区表找到boot/recovery等分区加载内核之后Android系统才真正接管。也就是说parameter.txt位于U-Boot启动阶段是整个系统“从哪儿找东西、往哪儿放东西”的全局航线图。为什么要用一个独立文件而不是把分区表写死在U-Boot源码里因为这颗芯片面向的是多产品线——同一款RK3568主板有的客户拿去做商业显示需要大userdata装素材有的拿去做工业盒子需要专门的日志分区。要是把分区写死在代码里每次定制都要重新编译U-Boot维护成本太高。所以Rockchip把分区表抽出来放到固定扇区U-Boot启动的时候动态解析。这样一来改分区就退化成改一个文本文件的问题了。这里的“固定扇区”不是随便挑的。RK3568默认把parameter.txt放在eMMC的0x2000扇区偏移处即1MB偏移位置大小通常是2KB到4KB左右。烧录工具会把这个文件单独擦写进去U-Boot在启动早期就会来读。我最初犯过一个错误以为只需要重新烧写system.img就能让新分区表生效结果启动还是老状态——因为parameter.txt没有烧进去U-Boot读到的还是旧的航线图。1.2 CMDLINE里藏着的启动密钥在parameter.txt顶部有一行以CMDLINE开头的参数很多新手会忽略它实际上这行是内核能不能正常找到根文件系统的关键。典型的内容长这样CMDLINE: consolettyFIQ0,1500000n8 rootPARTUUID614e0000-0000-4b53-8000-1d28000054a9 rw rootwait androidboot.selinuxpermissive逐个拆开看consolettyFIQ0,1500000n8指定调试串口号和波特率RK3568的调试串口通常是ttyFIQ0波特率1500000这是Rockchip平台的特色。rootPARTUUID...告诉内核根文件系统所在的分区这里用的是分区的UUID而不是设备节点名如/dev/mmcblk0p8。原因是内核在启动早期无法保证mmcblk设备号的稳定性改用UUID能避免因为分区顺序变化找不到根分区的问题。rw根分区以读写方式挂载如果少了它系统会变成只读开发阶段会非常痛苦。rootwait等待根设备出现再挂载。eMMC/NAND驱动加载需要时间没有这个参数可能内核已经尝试挂载根分区而设备还没准备好导致启动失败。androidboot.selinuxpermissive开发阶段关闭SELinux强制约束避免因SELinux策略没配置好导致各种莫名其妙的拒绝访问。量产时需要改成enforcing。我在调试中碰到过一次非常隐蔽的问题改分区时动了分区UUID但忘了同步改CMDLINE里这个rootPARTUUID结果内核找不到根文件系统启动时直接panic。这类问题临时能用fastboot或串口命令去救但根治办法就是保持parameter.txt里CMDLINE、uuid和分区表三者一致性。1.3 不要手动硬改文件先找到生成它的源头RK3568 Android11 SDK里parameter.txt通常由device/rockchip/rk3568/目录下的BoardConfig.mk和mkimage.sh等在编译时自动生成。你真正在该看的是类似这样的路径device/rockchip/rk3568/rk3568_mid/parameter/*.txt不同产品形态有不同模板rockdev/Image-rk3568/parameter.txt编译输出目录里的实际烧录文件也就是说如果你只是“临时改一下rockdev目录里的parameter.txt”下次执行./mkimage.sh就会被覆盖。正确做法是先改源头模板或BoardConfig.mk里的size变量再重新生成。不然你辛苦半小时改好的分区一天后编译一次就全没了这是最基础也最容易踩的坑。提示在修改任何分区大小前先确认你改的文件是“模板文件”还是“生成产物”。后者不要直接改要从源头改。2. 逐行拆解分区表sizestart(name)的换算与语义2.1 十六进制、扇区和MB一个快速换算表Rockchip分区表的每一行格式是固定不变的0x000020000x00004000(uboot_a)含义是sizestart(name)。冒号前面的0x00002000是分区大小后面的0x00004000是该分区的起始地址括号里是分区名。这里的单位是扇区每个扇区固定512字节。所以一个分区的大小换算成MB用十六进制数变成十进制再乘以512再除以1024再除以1024即除以2048。很多人在门店干活时要反复换算我直接给出一张常用速查表省得每次掏计算器十六进制扇区数一次性换算结果0x000010002MB0x000020004MB0x000040008MB0x0000800016MB0x0001000032MB0x0002000064MB0x00040000128MB0x00080000256MB0x00100000512MB0x002000001GB注意这只是“分区大小”的换算起始地址的换算方法一样。计算下一个分区起始地址时必须用上一个分区的起始地址加大小否则会重叠。如果你把地址算错了哪怕只差一个扇区U-Boot解析时也可能直接报错或者覆盖相邻分区。2.2 A/B分区与super动态分区Android 11的大背景在Android 11版本的RK3568 SDK中默认趋势是采用A/B系统和无缝升级方案。分区表里会同时存在boot_a/boot_b、recovery_a/recovery_b、dtbo_a/dtbo_b等成对分区。这样做的好处是系统升级时可以先往B槽写入新系统重启后从B槽引导如果新系统有问题还能回退到A槽大大减少变砖风险。与A/B分区配套的是super动态分区。以往system、vendor、product、odm各占一个独立分区尺寸必须提前定死因为分区表是静态的。而动态分区方案是将这些系统镜像全部打包进一个名为super的大分区里Android系统启动后根据分区表里super的大小再在super内部动态创建和管理system、vendor、product、odm。这对我们改parameter.txt有什么实际影响如果你只是想扩大system分区在动态分区方案里并不存在独立的system分区你需要改的是super分区的大小。系统在运行时会把super剩余的未分配空间自动分给需要的逻辑分区。我之前给客户定制ROM时想加大system容量直接在旧的非A/B分区表里找system那一行改大小结果完全没有效果因为系统实际运行的是super里的逻辑分区这就是对底层机制不熟悉造成的白费功夫。2.3 改分区表前必须先确认的四个前提改分区不是改完保存就完事它在整个链路里牵涉多个约束。我总结下来动手之前至少要确认以下四点确认你使用的是A/B还是非A/B分区方案。A/B下没有独立的system分区而只有super。确认下发烧录的loader版本与parameter文件匹配。有时候SDK升级以后loader和旧parameter之间会出现misc分区位置不兼容的问题。确认下一个分区起始地址是上一个分区startsize计算出来的没有重叠或间隙异常。确认CMDLINE里的rootPARTUUID值在分区表里有对应的uuid: 声明并且这个分区确实存在。如果不满足这些条件你烧录时会报“分区表错误”或者启动进不了系统。这些坑在后面的排查章节里我再细讲。3. 实战三种高频改分区需求的完整配置方法3.1 需求一给userdata扩容从源头根治存储不足RK3568Android 11最常见的定制需求就是把userdata分区扩大因为很多设备预装大量应用、离线地图或广告素材。默认分区表里userdata通常是最后一个分区它的大小通常占据剩余全部空间。但是在某些产品预编译版本里userdata被设成一个固定大小导致64GB eMMC实际可用空间只有32GB。具体操作步骤如下第一步找到模板文件。如果你的SDK路径是device/rockchip/rk3568/就先看rk3568_mid/parameter/目录下的txt文件。第二步找到userdata那一行。0x038000000x00000000(userdata)假设你的eMMC是64GB即十六进制0x08000000扇区因为64GB除以512字节每扇区再按1024换算实际是0x08000000扇区附近不过要注意eMMC实际可寻址扇区并不等于标称容量除以512一般会小一些。第三步把userdata的size改为剩余空间。怎么算用eMMC总扇区数减去userdata起始地址。比如userdata起始于0x02800000处换算成十进制是41,943,040扇区64GB eMMC可用扇区总数通常在125,829,120扇区左右64GB标称那么最大可用的userdata大小就是125,829,120 - 41,943,040 83,886,080扇区再换算回十六进制是0x05000000。0x050000000x02800000(userdata)第四步重新生成镜像并烧录。如果修改的是源头模板执行一次mkimage.sh后用AndroidTool或rkdeveloptool重新烧录即可。这里需要特别提醒仅烧写parameter和userdata分区是不够的因为分区表的变更也需要U-Boot重新读取最好把parameter和loader一并烧进去。3.2 需求二增加一个独立的日志分区在生产设备上应用日志、内核日志如果长期写入userdata容易造成存储碎片和分区满我一般会切出一个独立的log分区。具体操作如下先确定要插在哪个位置。假设我在recovery之后、cache之前插入一个大小为256MB0x00080000扇区的log分区。如果recovery分区起始地址是0x00030000大小是0x00020000那么log分区的起始地址就是0x00030000 0x00020000 0x00050000。对应分区表增加一行0x000800000x00050000(log)然后检查后续分区的起始地址是否被影响。原来cache分区的起始地址是0x00050000现在log占用了0x00050000到0x000D0000所以cache起始地址要改成0x000D0000。依次把所有后续分区的start都后移。再接下来需要让系统能识别这个分区为块设备。Android 11的机制下每个分区会自动生成对应的设备节点例如/dev/block/by-name/log或/dev/block/mmcblk0pN。应用可以直接访问它或者你把它格式化后挂载到/data/log目录。最后别忘了在Device Tree或init脚本里加上挂载逻辑。我常用做法是在init.rc或板级init脚本里增加mount命令或者在fstab.rk3568里加一行。如果你用的是RK默认的overlay机制还要确认fstab有没有对log分区做特殊处理否则系统可能不识别。3.3 需求三从A/B改为传统非A/B的简化路线有些产品根本不需要A/B无缝升级反而觉得双分区浪费空间。这时候你想把系统改回传统单分区布局将super拆回system、vendor独立分区。方法如下先关闭A/B开关。在BoardConfig.mk里找到类似AB_OTA_UPDATER和PRODUCT_PACKAGES相关的配置把OTA相关支持关闭。同时把BOARD_USES_AB_IMAGE标志去掉。接着在parameter模板里把成对的uboot_a/uboot_b、boot_a/boot_b等合并成单一分区把super分区删除换成system、vendor、product、odm等独立分区。然后需要删除或调整super相关的逻辑分区设备。Android 11在非A/B模式下system分区会被直接挂载为根分区所以fstab也要从动态分区的处理逻辑改回传统逻辑。最后执行一次完整编译和烧录。这条路涉及的配置项很多不同SDK版本差异比较大如果项目周期紧建议在SDK release notes里查找“non-A/B”或“legacy partition”的说明或者直接让FAE给一份非A/B模板。4. 常见问题与排查技巧实录4.1 烧录时报“Parameter mismatch”或Loader不匹配故障现象用AndroidTool烧录时弹窗提示partition mismatch或者烧录到一半卡住。排查思路这通常说明你烧录的parameter.txt和当前loaderMiniLoaderAll.bin版本不兼容。我遇到过拿着A版本SDK编译的parameter配B版本SDK的loader去烧结果直接报mismatch。解决方法是保证parameter和loader来自同一套SDK或者至少同一个Release版本。下载工具需要把parameter和loader一起update不要只单独烧parameter。具体到AndroidTool烧录前选择“Loader”分区和“Parameter”分区确认它们匹配后再点执行。4.2 改完分区后开机卡在logo或反复重启故障现象parameter.txt改完烧录后系统启动卡在RK logo串口无输出或者只有U-Boot信息但进不了桌面。排查要点第一检查分区起始地址是否重叠。如果两个分区地址重叠U-Boot解析时会混乱最直接的表现就是内核找不到根分区或系统挂载失败。用十六进制计算工具重新核对一遍相邻分区的衔接关系。第二检查rootPARTUUID路径。如果你动了分区表但没有同步更新CMDLINE里的UUID内核就找不到/system所在分区。把CMDLINE和uuid:行与分区表逐一对齐。第三检查super分区是否够大。在动态分区方案里system、vendor等逻辑分区被塞进super如果super标称大小小于所有逻辑分区实际大小之和系统编译时就会报错如果恰好只有parameter被改动其他镜像没重编也可能出现super空间不足导致挂载失败。第四检查selinux。如果启动卡在Android动画前的黑屏状态偶尔是SELinux策略问题。尤其在开发阶段建议把CMDLINE保持androidboot.selinuxpermissive先把功能跑通再收紧安全策略。4.3 用rkdeveloptool和串口log快速定位问题很多时候分区问题看UI报错看不懂直接用命令行工具最直观。Linux下用rkdeveloptool可以读取当前eMMC里的分区表sudo rkdeveloptool rd 0x2000 64 /tmp/param_dump.txt然后查看这个文件就能确认板子上实际生效的parameter是不是你烧进去的版本。如果看到的还是旧分区信息说明烧录过程有问题或者烧错了位置。此外一定要养成接串口的习惯。RK3568调试串口默认在UART2波特率1500000注意不是115200接上USB转串口打开minicom或者cutecom启动时能看到U-Boot完整日志包括它解析parameter.txt的过程。比如U-Boot打印出类似“Wrong partition table”或“Cannot find partition”的信息比你在屏幕前瞎猜要快得多。结合串口日志和分区表dump95%的parameter问题都能在十分钟内定位出来。5. 一些后续再补充的经验这半年来我还发现和parameter.txt密切相关的周边内容里设备树的chosen节点、Android 11的remote display功能和USB OTG配置在项目落地时也是绕不开的。设备树里chosen节点的bootargs会和parameter的CMDLINE做合并调串口或调显示驱动时要两边一起看远程投屏调试时userdata空间不足很容易导致录屏失败分区大小会直接影响后台上层应用表现OTG切换到host模式后默认分区检查逻辑也可能因为挂载异常而触发自动重启。针对这些场景参数配置只是第一步真正稳的是把“启动链路、动态分区、设备树”这几个知识点打通。下次有机会我再单独写一篇RK3568设备树里chosen节点和bootargs的关联细节以及Android 11 remote display在板端的调试心得。