因为这部分内容是启动参数的设置,所以我们可以用如下的方式来搜索源码信息
譬如我像查找 mtdparts 的源码信息
1
|
grep -rn 'MODULE_PARM_DESC(parts'
|
其他的启动参数也可仿照如上方式来进行查询
mtd_id
1
|
mtd_id:size1(name1),size2(name2)
|
一般这样使用
1
2
3
|
mtdparts=mtd-id:<size1>@<offset1>(<name1>), \
<size2>@<offset2>(<name2>); \
mtd_id:size1(name1),size2(name2)
|
mtdparts
我们自己编写的时候,可以在实机上运行 dmesg 来查看 mtd 分区在内核中的地址
再以此编写仿真时所需要的 mydparts 参数
需要注意的是,内核要打开几个必要的宏:
-
Config 1
-
CONFIG_CMD_MTD
-
CONFIG_CMD_MTDPARTS
-
Config 2
格式
mtdparts 的格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
* mtdparts=<mtddef>[;<mtddef]
* <mtddef> := <mtd-id>:<partdef>[,<partdef>]
* <partdef> := <size>[@<offset>][<name>][ro][lk][slc]
* <mtd-id> := unique name used in mapping driver/device (mtd->name)
* <size> := standard linux memsize OR "-" to denote all remaining space
* size is automatically truncated at end of device
* if specified or truncated size is 0 the part is skipped
* <offset> := standard linux memsize
* if omitted the part will immediately follow the previous part
* or 0 if the first part
* <name> := '(' NAME ')'
* NAME will appear in /proc/mtd
*
* <size> and <offset> can be specified such that the parts are out of order
* in physical memory and may even overlap.
*
* The parts are assigned MTD numbers in the order they are specified in the
* command line regardless of their order in physical memory.
*
* Examples:
*
* 1 NOR Flash, with 1 single writable partition:
* edb7312-nor:-
*
* 1 NOR Flash with 2 partitions, 1 NAND with one
* edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
|
mtdparts 可以由一个或多个 mtddef 组成。每个mtddef定义如下:
1
|
<mtddef> := <mtd-id>:<partdef>[,<partdef>]
|
mtddef 可以由mtd-id 和一个或多个partdef组成,每个partdef定义如下:
因此在使用的时候,需要按照下面的格式来设置:
1
|
mtdparts=mtd-id:<size1>@<offset1>(<name1>),<size2>@<offset2>(<name2>)
|
这里需要注意的地方如下:
-
mtd-id 必须跟当前平台 flash 的 mtd-id 一致,不然整个 mtdparts会失效
-
size 在设置的时候,可以为实际的 size (xxM,xxK,xx)
,也可以为-
,表示剩余的所有空间,相关信息可以查看drivers/mtd/cmdlinepart.c
中注释找到相关描述
-
mtdparts 里mtd_id
的值为nandnand
,那么 kernel 的平台代码中也必须有一个名为nandnand
的分区表,平台代码中的那张分区表可以为空,因为 mtdparts 中已经有了,就不会解析平台代码中设置的分区表,但是分区表的名字还是要匹配的。kernel 中默认的分区表的名字是 Nand
样例
arm
1
|
mtdparts=armflash:0x80000@0(boot),0x180000@0x80000(nvram),0x3e00000@0x200000(linux),0x19d3ac@0x4000000(rootfs),0x3ec0000@0x4000000(brcmnand),0x140000@0x7ec0000(asus)
|
1
|
mtdparts=nand_iproc.0:1024k(nboot),1024k(nenv),8192k(nsystem),1038336k(ndata)
|
mips
1
|
mtdparts=physmap-flash.0:0x30000@0x0(Bootloader)0x10000@0x30000(nvram)0x10000@0x40000(Factory)0xeb0000@0x50000(linux)0xd847c0@0x17b840(rootfs)0x100000@0xf00000(jffs2)0x1000000@0x0(ALL)
|
mtd 分区内核地址
1
2
3
4
5
6
7
8
9
10
11
12
|
Concatenating MTD devices:
(0): "armflash-0"
(1): "armflash-1"
into device "armflash"
6 cmdlinepart partitions found on MTD device armflash
Creating 6 MTD partitions on "armflash":
0x000000000000-0x000000080000 : "boot"
0x000000080000-0x000000200000 : "nvram"
0x000000200000-0x000004000000 : "linux"
0x000004000000-0x00000419d3ac : "rootfs"
0x000004000000-0x000007ec0000 : "brcmnand"
0x000007ec0000-0x000008000000 : "asus"
|
解析脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument('file', help='boot info file')
args = parser.parse_args()
if args.file:
with open(args.file, "rb") as fd:
data = fd.read().strip()
output = b'mtdparts=armflash:'
data = data.split(b'\n')
for i in range(0, len(data)):
line = data[i][data[i].find(b'0x'):].split(b' : ')
addr = line[0].split(b'-')
name = line[1].strip(b'"')
output += hex(int(addr[1], 16) - int(addr[0], 16)).encode()
output += b'@'
output += hex(int(addr[0], 16)).encode()
output += b'(' + name + b')'
print(output)
with open(os.path.dirname(args.file) + "/mtdparts", "wb") as fd:
fd.write(output + b'\n')
|
/proc/mtd
1
2
3
4
5
6
7
8
|
/ # cat /proc/mtd
dev: size erasesize name
mtd0: 00080000 00010000 "boot"
mtd1: 00180000 00010000 "nvram"
mtd2: 03e00000 00010000 "linux"
mtd3: 0019d3ac 00010000 "rootfs"
mtd4: 03ec0000 00010000 "brcmnand"
mtd5: 00140000 00010000 "asus"
|
nandsim.parts
格式如下
1
|
nandsim.parts=64,64,64,64,64,64,64,64,64,64
|
开启方式
- 内核配置
- 用户手动开启
1
2
3
4
5
6
|
modprobe nandsim first_id_byte=0xc8 \
second_id_byte=0xd1 \
third_id_byte=0x80 \
fourth_id_byte=0x95 \
cache_file=/root/nandsim.bin \
\ parts=8,8,8,20,20,256,256,224,220
|
开启后内核启动后会打印出模拟 NAND 芯片的名字,一般如下
1
|
Manufacturer ID: 0x98, Chip ID: 0x39 (Toshiba NAND 128MiB 1,8V 8-bit)
|
但是模仿出来的 mtd 块名字不能更改,内部获取名字的函数如下
1
2
3
4
|
static char __init *ns_get_partition_name(int i)
{
return kasprintf(GFP_KERNEL, "NAND simulator partition %d", i);
}
|
参考链接