分区设置
本章节介绍 Luban-Lite 系统中分区的一些特点、规则和分区修改的设置方法。
默认分区
本节首先介绍 Luban-Lite 系统中的一些分区特点,以及需要遵循的使用规则。
启动分区
对于所有的存储介质,第一个分区总是启动分区,Luban-Lite 系统中通常命名为 spl
分区。
不同存储介质上,启动分区的实际位置和大小有所不同,当前方案上的设置如下:
SPINOR
Flash 的 0 ~ X 的区间是启动分区,当前设置存放 BootLoader,大小设置为 256K。
实际上 BROM 加载的程序并不限制为小于 256K,但是由于 BROM 运行时的速度较慢,不建议让 BROM 加载过大的程序。
SPINAND
Flash 的前4个物理块为启动块,对于块大小为 128K 的 SPINAND,启动分区为 512K;对于 块大小为 256K 的 SPINAND,启动分区为 1M。 启动分区内使用4个启动块保存2份启动镜像。
eMMC
eMMC 的启动分区是 UDA 区域的 17K ~ X 区间,BROM 从该区域读取的程序。建议启动镜像小于 512K。
数据分区
Luban-Lite 系统中,SPINOR/SPINAND Flash 上设置了两个默认的分区来保存数据:
- rodata
- data
这两个分区在设计和实现上有一些差异,用户需要了解并根据实际情况规划数据存储。
rodata
分区的设计初衷是保存 APP 应用需要使用的资源文件,这些文件通常是应用的一部分,都是只读的数据,只是为了更好的管理和访问,使用 FAT 文件系统的方式保存。应用在访问这些资源文件的时候,通常要求能够快速读取数据,因此 rodata 分区在实现的时候,删减了多余的软件层次,通过直接访问 Flash 的方式读取数据,以达到更优的速度。这些优化,也使得 rodata 仅支持读取,不支持写入。
data
分区的设计初衷是作为一个可读写的文件系统分区,保存设备在使用过程中需要写入 Flash 的数据。在 SPINOR Flash 上该分区使用 LittleFS,SPINAND Flash 上该分区使用 FATFS。
在 eMMC 上,每一个分区都是可读写的,需要使用文件系统时,默认使用 FATFS。
1. Flash 写入前需要先按块擦除,但是擦除和重新写入需要的时间比较长
2. FATFS 没有日志,不支持异地写入,因此需要原地回写,如果擦除和回写时出现掉电,会导致文件系统损坏
A/B 分区
Luban-Lite 上 OTA 使用 A/B 系统的方式实现,即 Flash 上保存前后两个版本的系统程序。 A/B 系统的分区命名遵循以下规则:
- A 系统分区命名直接使用需要的名字,如 “rodata” 分区
- B 系统分区总是在对应的 A 系统分区名后加上 “_r”,如 “rodata_r”
分区与设备
Luban-Lite 上使用 RT-Thread 时,每个分区都对应一个或者多个系统设备,不同存储介质的对应关系如下表格所示。
表 2.11 SPINOR 上的分区、设备和文件系统 1
分区名字 | MTD 设备名 | 块设备名 | 文件系统 | 备注 |
spl | spl | - | - | |
os | os | - | - | |
rodata | rodata | blk_rodata | FATFS | FATFS 通过 blk_rodata 设备访问 Flash |
data | data | - | LittleFS | LittleFS 直接通过 MTD 设备访问 Flash |
规则:
- 直接访问 Flash,使用 MTD 设备
- FATFS 访问 Flash,需要使用块设备
- LittleFS 访问 Flash,使用 MTD 设备
系统中出现但此处未列出的其他分区,同样遵循上述规则。
表 2.12 SPINAND 上的分区、设备和文件系统 2
分区名字 | MTD 设备名 | 块设备名 | 文件系统 | 备注 |
spl | spl | - | - | |
os | os | - | - | |
rodata | rodata | blk_rodata | FATFS | 通过 blk_rodata 设备访问 Flash,FATFS 只读 |
data | data | blk_data | FATFS | blk_data 设备是通过 NFTL 层创建,FATFS 访问 blk_data 时,通过 NFTL 访问 Flash |
规则:
- 直接访问 Flash,使用 MTD 设备
- FATFS 访问 Flash,需要使用块设备,通过 NFTL 层访问 Flash
表 2.13 eMMC 上的分区、设备和文件系统 3
分区名字 | MTD 设备名 | 块设备名 | 文件系统 | 备注 |
spl | - | mmc0p0 | - | |
os | - | mmc0p1 | - | |
rodata | - | mmc0p2 | FATFS | 此处的分区排序仅为示例 |
data | - | mmc0p3 | FATFS | 此处的分区排序仅为示例 |
规则:
- 块设备的命名,按照分区的排序从0开始编号
修改分区
修改分区大小和位置,需要在 image_cfg.json 文件中进行修改。
image_cfg.json 文件是设置分区信息以及如何生成烧录镜像文件的配置文件,由于分区和烧录信息是相互关联的,因此在一个文件中进行配置。 image_cfg.json 文件的保存路径为 target/<chip>/<board>/pack/image_cfg.json
。
修改大小
对于 SPINOR:
"spi-nor": {
"size": "16m", // Size of SPI NOR
"partitions": {
"spl": { "size": "256k" },
"env": { "size": "128k" },
"env_r": { "size": "128k" },
"os": { "size": "1m" },
"os_r": { "size": "1m" },
"rodata": { "size": "3m" },
"rodata_r": { "size": "3m" },
"data": { "size": "7m" }
},
},
2
3
4
5
6
7
8
9
10
11
12
13
如示例,如果要修改 data 分区大小为6 MB,则直接修改对应的 size 值即可,如:
"data": { "size": "6m" }
* 不带单位,表示字节
* 单位 k 或者 K
* 单位 m 或者 M
如果是 SPINAND Flash,则需要注意 NFTL 分区的配置方法:
"spi-nand": {
"size": "128m", // Size of SPI NAND
"partitions": {
"spl": { "size": "1m" },
"env": { "size": "256k" },
"env_r": { "size": "256k" },
"os": { "size": "4m" },
"os_r": { "size": "4m" },
"rodata": { "size": "12m" },
"rodata_r": { "size": "12m" },
"data": {
"size": "40m",
"nftl": { // Volume in NFTL device
"datavol": { "size": "-" },
},
},
},
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
如上,在 “spi-nand” 中配置了一个 40 MB 的 “data” 分区,在该分区中配置了一个 NFTL 设备,包含了一个卷 “datavol”。 “-” 表示该卷的大小是 NFTL 设备的所有剩余存储空间。
注意,NFTL 设备需要使用大约 6 MB 的空间做坏块管理,因此 “datavol” 的可用大小大约为 34 MB。
如果是 eMMC,则需要注意第一个分区的开始位置:
"mmc": {
"size": "8G", // Size of SD/eMMC
"partitions": {
"spl": { "offset": "0x4400", "size": "256k" },
"os": { "size": "1m" },
"rodata": { "size": "3m" },
"data": { "size": "5m" }
},
},
2
3
4
5
6
7
8
9
eMMC 使用 GPT 分区表格式,需要在 eMMC 的开始和末尾都预留 17K 的空间存放 GPT 信息,因此 “spl” 的开始位置为 “0x4400”。
* SPINOR: 需要与最小擦除块大小对齐,一般为 4K 或者 64K,具体请参考 SPINOR 的数据手册
* SPINAND: 需要与最小擦除块大小对齐,一般为 128K 或者 256K,具体请参考 SPINAND 的数据手册
* eMMC: 需要 512 字节对齐
新增分区
新增一个分区比较简单,直接在需要的位置添加一行配置即可,例如:
"spi-nand": {
"size": "128m", // Size of SPI NAND
"partitions": {
"spl": { "size": "1m" },
"env": { "size": "256k" },
"env_r": { "size": "256k" },
"os": { "size": "4m" },
"os_r": { "size": "4m" },
"rodata": { "size": "12m" },
"rodata_r": { "size": "12m" },
"user": { "size": "20m" }, // 新添加的分区
"data": {
"size": "40m",
"nftl": { // Volume in NFTL device
"datavol": { "size": "20m" },
"datavol2":{ "size": "-" }, // 新添加的分区
// 所占空间为 NFTL 设备的剩余空间
},
},
},
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
如果新增的分区有需要烧录的预制内容,则需要在 “target” 段中新增配置,如:
"target": { // Image components which will be burn to device's partitions
"spl": {
"file": "bootloader.aic",
"attr": ["required"],
"part": ["spl"]
},
...
"mydata": { // 此处组件名字可自定义
"file": "userdata.bin", // 此处为要烧录到分区的数据
"attr": ["mtd", "optional"],
"part": ["user"] // 此处设置要烧录的分区名字
},
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
删除分区
删除分区与新增分区做相反的操作即可:
- 在分区配置中,删除对应的分区配置行
- 检查 “target” 段中是否有使用该分区,如果有,则删除相关的配置