☰
RK3568 Android11分区调整:parameter.txt深度解析与实战
2026/10/3 3:21:19 网站建设 项目流程

1. 一次启动失败,让我重新认识了parameter.txt

做瑞芯微RK3568开发板调试,尤其是Android11系统定制,绕不开的一个文件就是parameter.txt。很多人第一次接触它,是拿到开发板编译完固件,按文档把parameter.txt、uboot.img、boot.img、system.img一个个拖进烧录工具,点“执行”之后看到绿色对勾,就再也没管过它。

我最初也是这样。直到有一次,我自己改了分区大小,烧录后板子卡在开机logo,串口打印停在Kernel panic - not syncing: VFS: Unable to mount root fs,我才被迫把这个文件从头到尾啃了一遍。回头再看,这玩意儿表面上就几十行文本,实际上它同时决定了烧录行为、uboot读取kernel的方式、Android系统挂载分区的路径,任何一个冒号、逗号、错位的数字,都能让整块板子变砖。

这篇文章就以RK3568 + Android11为基线,把parameter.txt从格式到字段含义,再到实际修改方法和排查思路,完整梳理一遍。适合正在做Android系统定制、需要调整分区或者尝试在RK3568上做多系统启动的开发者参考。文中涉及的内容基于我自己在几块不同方案板上的调试经验,原理层面对RK3568和同系芯片的Android参数文件基本通用。

2. 逐段拆解:parameter.txt里每一行都在干什么

2.1 FIRMWARE_VER和MACHINE_MODEL是给谁看的

先看一个标准的parameter.txt长什么样:

FIRMWARE_VER: 11.0.0 MACHINE_MODEL: RK3568 MACHINE_ID: 007 MANUFACTURER: Rockchip MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE: 0xffffffff CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 TYPE: GPT CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00010000@0x00008000(boot),0x00010000@0x00018000(recovery),0x00010000@0x00028000(backup),0x00040000@0x00038000(cache),0x00040000@0x00078000(metadata),0x00030000@0x000B8000(security),0x00100000@0x000E8000(system),0x00008000@0x001E8000(metadata),0x00040000@0x001F0000(vendor),0x00040000@0x00230000(odm),0x00010000@0x00270000(persist),0x00002000@0x00280000(security),0x00010000@0x00282000(kernel),0x00010000@0x00292000(ramdisk),0x00040000@0x002A2000(parameter),0x00040000@0x002E2000(system),0x00080000@0x00322000(data)

顶部几行,FIRMWARE_VER、MACHINE_MODEL、MACHINE_ID、MANUFACTURER,看起来像备注,实际上它们会被烧录工具读取并写入设备信息。

FIRMWARE_VER是固件版本号,Android升级、系统设置里的“版本号”都会引用它。MACHINE_MODEL和MACHINE_ID则用于匹配uboot或内核中的机器型号。有些方案商会把MACHINE_ID改成一个自己约定的编号,用于区分同一块板子的不同硬件版本。还有一个容易被忽略的MAGIC: 0x5041524B,这是"PARK"的ASCII码,起到校验作用,烧录工具拿到这个字段才知道文件确实是parameter格式,不是乱改出来的文本。

2.2 CMDLINE里的mtdparts才是真正的分区逻辑

看到CMDLINE: mtdparts=rk29xxnand:...这一长串,很多人会误以为里面写的三个分区名和后面的分区名是重复的——比如前面出现两个metadata、两个security、甚至两个system。这不是笔误,是RK方案里一个非常容易困惑的设计。

mtdparts字符串中,每个分区条目由size@offset(name)构成,逗号分隔。烧录工具解析这一串时,会把每个分区的起始地址、大小记录下来,生成一张分区表传给后续环节。后面两处system和metadata的重复出现,是因为在部分官方板级配置中,后续跟的是uboot或者kernel实际使用的分区定义,需要覆盖前面某个条目的大小。不同版本、不同方案商的parameter.txt差异很大,有的简化为一条system,有的则兼容多种启动模式有意保留两组。

更重要的是,这一长串分区描述,最终会传递给uboot的mtdparts环境变量和内核的cmdline。也就是说,内核启动时访问/dev/block/by-name/system这类节点,依赖的就是这份分区表。如果你想在Android11的/dev/block下看到一个叫userdata的分区,而parameter.txt里写的是data,那上层应用访问时就会对不上。

2.3 TYPE: GPT和PWR_HLD的隐藏作用

再往下看,TYPE: GPT表示分区表类型使用GPT格式。RK3568默认支持GPT,这也是Android11推荐的分区表格式,相比旧的MBR,GPT支持更多分区数量、更大容量、还有备份分区表。这里不建议为了省空间改回MBR,因为Android11的某些分区(比如super、vendor_boot)在动态分区机制下依赖GPT的特性。

PWR_HLD: 0,0,A,0,1是电源保持时序配置,一般不需要动,但如果你在做低功耗调试、需要控制供电时序,可以研究一下,平时保持默认即可。

3. 分区大小计算的底层逻辑:从十六进制到实际MB

3.1 size字段的单位和偏移规则

0x00010000@0x00008000(boot)这种写法,看起来像一串十六进制编码,本质上是两个数:分区大小和分区偏移,单位都是sector(扇区),每个扇区512字节。换算规则很简单:

实际大小(字节) = 十六进制值 * 512

举例:0x00010000换算成十进制是65536,乘以512得到33554432字节,等于32MB。0x00040000是262144,乘以512等于134217728字节,即128MB。0x00100000是1048576个扇区,乘以512就是536870912字节,即512MB。

偏移@0x00008000表示这个分区的起始扇区是0x8000,即32768扇区,对应16MB偏移。为什么第一个分区不从0开始?因为前面需要预留uboot、parameter自身、以及一些不可见区域。parameter分区本身也在分区表中占有一席之地,通常放在比较靠后的位置,而真正的引导流程是通过烧录工具先把IDB(含uboot)写入固定区域,再解析parameter.txt去烧其他分区。

3.2 对齐:分区size最好遵循的规则

手动新增分区时,不能只算好大小随便塞进去。eMMC的擦除块通常是512KB或1MB,NAND的页大小和块大小又有差异,因此分区对齐遵循的规则是:偏移最好按0x2000(即4MB)对齐,大小最好按0x2000(4MB)或其整数倍来分配。

这不是有人强迫你这么做,而是不对齐会导致两个实际痛点:一是烧录工具写入时出现奇怪的“擦除失败”,因为跨块擦除;二是后续在uboot里做OTA时,部分分区的大小比较繁琐。我自己有一次把一个新的test分区设成0x1000大小、偏移随手写在一个奇数位置,结果烧录正常,但Android启动后mmcblk0p设备节点虽然在,读取数据时却偶发CRC错误,后来把大小改成0x2000对齐,问题消失。

3.3 分区总容量与eMMC实际容量校验

还有个容易踩的坑:分区表里所有分区大小之和,加上它们之间的空隙,不能超过eMMC实际可用空间。

以一个64GB(实际容量约61GB,即大约122683392个扇区)的eMMC为例,你必须在分配完所有分区后留出足够余量给data分区。data分区通常不写固定大小,而是写成:

0xFFFFFFFF@0x某偏移(data)

0xFFFFFFFF是特殊占位符,表示“剩余全部空间”。烧录工具看到这个值,会自动把从该偏移到eMMC末尾的所有空间分配给data分区,这样你就不用手动算到最后一个字节。但前提是:前面所有分区加偏移不能超过eMMC容量,否则0xFFFFFFFF会算出负数,烧录直接报错。

4. 三类最常遇到的分区调整需求与完整操作方法

4.1 把system分区调大:Android11动态分区下的正确姿势

Android11引入了动态分区机制,system、vendor、odm等分区会被合并到super分区中。如果你的板子沿用老式独立分区布局(parameter里直接列出system、vendor各占一块),调整system大小的逻辑就是:先减其他分区,再增system分区。

操作步骤:

  1. 用计算器把目标分区大小转成扇区数。假设你希望system从512MB(0x00100000)扩到768MB,那system的size就是0x00180000。
  2. 检查system后面紧跟的分区的偏移是否需要后移。如果system占据的空间变大了,后面分区的@偏移必须同步向右移动,否则分区会重叠。
  3. 修改后,把parameter.txt烧入,或者使用upgrade_tool的di -p parameter.txt命令只更新parameter分区,然后重启进入fastboot或loader模式重新烧system.img。

注意:如果使用Android11动态分区,system分区大小实际意义取决于super分区里的逻辑分区分配,真正要改的是super分区大小,而不是system。很多初次接触RK3568的工程师把时间浪费在改system上,结果super没动,烧完依旧提示空间不足。

4.2 新增一个自定义分区:从parameter到挂载路径

想在Android11里加一个自己的appdata分区存放业务数据,需要改动三个地方:parameter.txt、uboot的mtdparts环境变量、Android的fstab。

parameter.txt里,找一个空闲位置插入:

0x00020000@0x00280000(appdata)

需要确保@后面的偏移与上一分区的位置合理衔接。然后同步修改uboot源码中的include/configs/rk3568_common.h里的mtdparts字符串和Android设备树/ramdisk中的fstab,添加:

/dev/block/by-name/appdata /appdata ext4 defaults defaults

这个过程最烦的是三处必须保持完全一致。我给出一个自查顺序:先改parameter,烧录后进uboot命令行敲mtdparts和part list mmc 0,看分区是否出现;再改fstab重启看挂载是否成功。任何一步丢了,Android起来后/appdata目录可能空挂或者找不到设备。

4.3 为多系统预留分区:GPT的分区名不能随便叫

RK3568支持多系统引导,比如Android和Buildroot双系统通过uboot选择启动。这种情况下,parameter.txt需要同时保留两套系统的根文件系统分区。常见做法是留两个根分区:

0x00100000@0x000E8000(rootfs_a) 0x00100000@0x001E8000(rootfs_b)

分区名的后缀_a和_b不是可选的,是uboot的AB系统切换策略依赖的命名规范。Android11本身支持A/B无缝升级,你在parameter里看到带_a、_b后缀的分区,就是这个机制在起作用。如果发现板子只烧了A槽,开机却去尝试从B槽启动,就检查一下是否漏了其中一个分区定义。

5. 排查实战:从烧录失败到启动崩溃的完整链路

5.1 烧录报错“IDB失败”或“Loader下载失败”

烧录工具报这类错,通常不是下载通道问题,而是parameter.txt解析失败。常见原因:文件中出现了全角冒号、多余空格、或者某个分区大小超过eMMC总容量。

排查顺序:

  1. 用文本编辑器打开parameter.txt,开启显示所有字符,检查是否存在不可见字符。
  2. 把文件另存为UTF-8无BOM编码。Windows记事本默认保存带BOM(EF BB BF),烧录工具不认,导致解析到的第一个字段异常。
  3. 用Notepad++或VS Code打开,选“编码”->“使用UTF-8编码”,重新保存。

很多所谓“换个电脑就能烧成功”的玄学,其实是换电脑后编辑器默认编码变了,跟驱动没关系。这个坑我踩过一次之后,现在每次发板级资料给别人,都会特意提醒注意编码。

5.2 开机反复重启或卡在Failed to mount /system

这种问题在Android11上经常跟parameter.txt中system分区大小和实际烧入的system.img大小不匹配有关。

排查链路:

  • 进入uboot命令行,执行mmc part查看当前GPT分区表对不对。
  • 如果分区表正常,执行ext4ls mmc 0:8(假设system是第8个分区)确认img内容是否真实存在。
  • 确认img存在但内核仍无法挂载,检查fstab里是否引用了/dev/block/by-name/system,而parameter里把分区名意外的写成了sys。名字对不上,内核就找不到设备节点。

这类问题还有一个隐蔽成因:修改parameter.txt后,没有重新烧写parameter分区本身,烧录工具烧的是之前缓存的旧分区表。此时新烧的system.img按旧表烧到了错误位置,整个系统的分区信息都是错乱的。解决方法是重新烧一遍parameter,再烧boot和system。

5.3 串口看到的Kernel cmdline和mtdparts不一致

“我明明改了parameter.txt,但内核起来后/proc/cmdline里没有我新增的分区。”

这是排查链路中比较废时间的一种。原因在于,内核cmdline里的mtdparts有两个来源:一是parameter.txt烧写时写入misc分区或uboot环境变量里的值,二是uboot启动时动态生成的bootargs。修改parameter后,如果uboot环境变量里的bootargs还是旧值,它会覆盖新的分区信息。

解决方法是进入uboot命令行,执行:

env default -a saveenv

然后重启。uboot的env也保存着旧的mtdparts,保存新env前,uboot会重新从GPT表里读取分区信息,与parameter.txt自动同步。

5.4 分区总大小没问题,但data分区无法格式化

data分区使用0xFFFFFFFF自动扩展后,第一次启动Android时会自动格式化。偶尔会遇到格式化失败,开机循环回fastboot。这种问题的根源往往不是parameter,而是eMMC坏块或文件系统格式与内核驱动不匹配。

不过,有一种情况确实源自parameter:你给data分区前面保留的偏移区太小,导致data分区起始位置正好落在某个坏块区或保留区上。建议在data前面预留至少0x2000(4MB)的空闲扇区,给它足够的缓冲,可以规避大多数偶发异常。

6. 改完parameter.txt之后,别忘了这几件事

6.1 uboot环境变量和kernel设备树的联动检查

很多人在改完parameter.txt后,只盯着分区看,忽略了uboot环境变量里有一个mtdparts声明,以及kernel设备树中可能存在的chosen节点引用了分区名。这两个位置不同步,新分区映射关系就无法生效。

推荐动作:

  • 在uboot命令行执行env print bootargs,核对mtdparts是否与parameter一致。
  • 如果uboot默认环境来自include/configs/rk3568_common.h,修改parameter后需要同步更新这个头文件里的字符串,重新编译uboot,否则saveenv后旧参数依旧存在。

这步做完,才算真正完成一次分区调整,否则就是“烧的时候正常,启动的时候翻车”。

6.2 备份原始parameter.txt

调试过程中手滑改错文件是常事,尤其是同时维护多个板卡版本时。我这边有个固定习惯:每次拿到新板子,先把原始的parameter.txt复制一份,命名为parameter_original_vX.X.txt存进板卡资料目录。后续所有修改都基于副本进行,不碰原文件。这个习惯在需要回退对比时非常救命。

6.3 用烧录工具读取当前分区表来验证修改

RK烧录工具(RKDevTool)在“设备分区表”页签里能直接显示当前连接到电脑的板子实际使用的分区表信息。修改parameter后,不必急着烧整个固件,先把parameter单独烧进去,然后用烧录工具读取设备信息,核对每个分区的size和offset是否和配置一致,能省下大量反复重启的时间。

做RK3568开发,parameter.txt就是个“牵一发动全身”的文件。它不难,但细节极多,编码、对齐、分区名、uboot同步,任何一环出错都会以各种奇怪的方式反馈到启动过程中。希望这篇基于实际调试过程总结的文章,能帮你减少一些无头绪的debug时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询