由於10.3的kernel過時,所以10.3.1是用kernel 4.19來做補充。
MTD Partition除了在code中寫死以外,其實還可以透過一些parsers來作規劃,這一章就要來教大家如何使用"Command line partition table parsing"。
首先必須在kernel中啟用"Command line partition table parsing",請參照10.3。
接著在command line中加入mtdparts的設定,其簡單說明如下:
* mtdparts=<mtddef>[;<mtddef] * <mtddef> := <mtd-id>:<partdef>[,<partdef>] * <partdef> := <size>[@<offset>][<name>][ro][lk] * <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. * Due to the way Linux handles the command line, no spaces are * allowed in the partition definition, including mtd id's and partition * names.
這裡我用qemu與mtdram來執行,執行參數如下
qemu-system-arm -s -M vexpress-a9 -m 128M -kernel ./linux/arch/arm/boot/zImage \ -dtb ./linux/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd ./initrd-arm.img \ -nographic -append "console=ttyAMA0 mtdparts=\"mtdram test device:1024k(p1),1024k(p2),-(p3)\""
這裡特別要說明的是mtd-id就是mtd name,基本上你可以以cat /proc/mtd,就可以知道mtd name了,或者trace一下code也行
// file "drivers/mtd/cmdlinepart.c" static int parse_cmdline_partitions(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { ... const char *mtd_id = master->name; /* * Search for the partition definition matching master->name. * If master->name is not set, stop at first partition definition. */ for (part = partitions; part; part = part->next) { if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) break; } ... } // drivers/mtd/devices/mtdram.c static int __init init_mtdram(void) { ... err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device"); ... } int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, unsigned long size, const char *name) { ... /* Setup the MTD structure */ mtd->name = name; ... }
此外我多印了一些deubg資訊在drivers/mtd/cmdlinepart.c
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 3ea44cff9b75..a411ce85097e 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -48,6 +48,7 @@ * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) */ +#define DEBGU #define pr_fmt(fmt) "mtd: " fmt #include@@ -58,7 +59,7 @@ #include /* debug macro */ -#if 0 +#if 1 #define dbg(x) do { printk("DEBUG-CMDLINE-PART: "); printk x; } while(0) #else #define dbg(x) @@ -315,6 +316,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, struct cmdline_mtd_partition *part; const char *mtd_id = master->name; + printk("BROOK, %s(#%d), cmdline_parsed:%d\n", __func__, __LINE__, cmdline_parsed); /* parse command line */ if (!cmdline_parsed) { err = mtdpart_setup_real(cmdline); @@ -327,12 +329,15 @@ static int parse_cmdline_partitions(struct mtd_info *master, * If master->name is not set, stop at first partition definition. */ for (part = partitions; part; part = part->next) { + printk("BROOK, %s(#%d), mtd_id:%s, part->mtd_id:%s\n", __func__, __LINE__, mtd_id, part->mtd_id); if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) break; } - if (!part) + printk("BROOK, %s(#%d), part:%p\n", __func__, __LINE__, part); + if (!part) { return 0; + } for (i = 0, offset = 0; i < part->num_parts; i++) { if (part->parts[i].offset == OFFSET_CONTINUOUS)
執行結果如下:
/ # dmesg ... [ 4.688086] BROOK, parse_cmdline_partitions(#319), cmdline_parsed:0 [ 4.688876] DEBUG-CMDLINE-PART: [ 4.688994] parsing <1024k(p1),1024k(p2),-(p3)> [ 4.690787] DEBUG-CMDLINE-PART: [ 4.690944] partition 2: name <p3>, offset ffffffffffffffff, size ffffffffffffffff, mask flags 0 [ 4.692017] DEBUG-CMDLINE-PART: [ 4.692102] partition 1: name <p2>, offset ffffffffffffffff, size 100000, mask flags 0 [ 4.692950] DEBUG-CMDLINE-PART: [ 4.693034] partition 0: name <p1>, offset ffffffffffffffff, size 100000, mask flags 0 [ 4.693993] DEBUG-CMDLINE-PART: [ 4.694101] mtdid=<mtdram test device> num_parts=<3> [ 4.695000] BROOK, parse_cmdline_partitions(#332), mtd_id:40000000.flash, part->mtd_id:mtdram test device [ 4.696546] BROOK, parse_cmdline_partitions(#337), part: (null) [ 4.763129] BROOK, parse_cmdline_partitions(#319), cmdline_parsed:1 [ 4.763742] BROOK, parse_cmdline_partitions(#332), mtd_id:48000000.psram, part->mtd_id:mtdram test device [ 4.764461] BROOK, parse_cmdline_partitions(#337), part: (null) [ 4.806551] BROOK, parse_cmdline_partitions(#319), cmdline_parsed:1 [ 4.808150] BROOK, parse_cmdline_partitions(#332), mtd_id:mtdram test device, part->mtd_id:mtdram test device [ 4.809227] BROOK, parse_cmdline_partitions(#337), part:(ptrval) [ 4.810325] 3 cmdlinepart partitions found on MTD device mtdram test device [ 4.811006] Creating 3 MTD partitions on "mtdram test device": [ 4.813103] 0x000000000000-0x000000100000 : "p1" [ 4.830841] 0x000000100000-0x000000200000 : "p2" [ 4.846502] 0x000000200000-0x000000400000 : "p3" ... / # cat /proc/mtd dev: size erasesize name mtd0: 08000000 00040000 "40000000.flash" mtd1: 02000000 00001000 "48000000.psram" mtd2: 00100000 00020000 "p1" mtd3: 00100000 00020000 "p2" mtd4: 00200000 00020000 "p3" / # zcat /proc/config.gz | grep -i MTDRAM CONFIG_MTD_MTDRAM=y CONFIG_MTDRAM_TOTAL_SIZE=4096 CONFIG_MTDRAM_ERASE_SIZE=128