和u-boot高版本不同,mtdparts命令没有cmd_mtdparts这么一个单独的文件来实现。
不过,搜索uboot可以在cmd_jffs2.c里面看到如下代码:
1 U_BOOT_CMD( 2 mtdparts, 6, 0, do_jffs2_mtdparts, 3 "mtdparts- define flash/nand partitions ", 4 " " 5 " - list partition table " 6 "mtdparts delall " 7 " - delete all partitions " 8 "mtdparts del part-id " 9 " - delete partition (e.g. part-id = nand0,1) " 10 "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro] " 11 12 13 ...
可知mtdpart命令是在do_jffs2_mtdparts函数里面实现的。
再看do_jffs2_mtdparts函数:
int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { if (argc == 2) { //这里先检测参数的个数,注意,我们通常使用mtdpart命令时是不带参数,下面会在这里做修改 if (strcmp(argv[1], "default") == 0) { setenv("mtdids", (char *)mtdids_default); //mtdids使用mtdids_default setenv("mtdparts", (char *)mtdparts_default); //mtdparts使用mtdparts,以上两个默认配置都是在配置文件里面实现的,如smdk2410.h setenv("partition", NULL); mtdparts_init(); return 0; } else if (strcmp(argv[1], "delall") == 0) { /* this may be the first run, initialize lists if needed */ mtdparts_init(); setenv("mtdparts", NULL); /* devices_init() calls current_save() */ return devices_init(); } } ...
此外,在cmd_jffs2.c文件的开头,注意有几个宏定义:
#include <linux/ctype.h> #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) #include <cramfs/cramfs_fs.h> #if (CONFIG_COMMANDS & CFG_CMD_NAND) #ifdef CFG_NAND_LEGACY #include <linux/mtd/nand_legacy.h> #else /* !CFG_NAND_LEGACY */
和
#ifdef CONFIG_JFFS2_CMDLINE /* default values for mtdids and mtdparts variables */ #if defined(MTDIDS_DEFAULT) static const char *const mtdids_default = MTDIDS_DEFAULT; #else #warning "MTDIDS_DEFAULT not defined!" static const char *const mtdids_default = NULL; #endif
还有
static int part_validate_nand(struct mtdids *id, struct part_info *part) { #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) /* info for NAND chips */ nand_info_t *nand;
这里需要定义三个宏还有默认配置:
#define CONFIG_JFFS2_CMDLINE 1 #define CONFIG_JFFS2_NAND 1 #define MTDIDS_DEFAULT "nand0=nandflash0" #define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k@0(bootloader)," "128k(params)," "2m(kernel)," "-(root)"
1 #define CONFIG_COMMANDS 2 CFG_CMD_JFFS2 |
以上,编译通过后,并不能立刻启动内核,注意此时的启动参数:
#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0" //因为kernel还没有被识别
这里应该改成:
#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 0x60000 0x200000; bootm 0x30007FC0"
//这里是内核已经被烧写到Nand里面去了,然后使用nand read命令读到sdram的30007fc0地址处,内核在nand里面的地址是0x60000,大小是2M
这里还是不能使用mtdpart命令,原因是上面提到过mtdpart参数的问题
因为我们不使用参数,那么:
1 if (argc == 2) { 2 if (strcmp(argv[1], "default") == 0) { 3 setenv("mtdids", (char *)mtdids_default); 4 setenv("mtdparts", (char *)mtdparts_default); 5 setenv("partition", NULL); 6 7 mtdparts_init(); 8 return 0; 9 } else if (strcmp(argv[1], "delall") == 0) { 10 /* this may be the first run, initialize lists if needed */ 11 mtdparts_init(); 12 13 setenv("mtdparts", NULL); 14 15 /* devices_init() calls current_save() */ 16 return devices_init(); 17 } 18 } 19 20 /* make sure we are in sync with env variables */ 21 if (mtdparts_init() != 0) 22 return 1; 23 24 if (argc == 1) { 25 list_partitions(); 26 return 0; 27 }
那么,以下四个函数没有执行:
setenv("mtdids", (char *)mtdids_default);
setenv("mtdparts", (char *)mtdparts_default);
setenv("partition", NULL);
mtdparts_init(); //其中,主要是这个没有被执行
处理措施:有两种
第一个,把参数解析那个去掉,直接执行mtdparts_init()函数,代码如下:
1 int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 2 { 3 //by Flinn 4 setenv("mtdids", (char *)mtdids_default); 5 setenv("mtdparts", (char *)mtdparts_default); 6 setenv("partition", NULL); 7 8 mtdparts_init(); 9 if (argc == 2) { 10 if (strcmp(argv[1], "default") == 0) { 11 //setenv("mtdids", (char *)mtdids_default); 12 //setenv("mtdparts", (char *)mtdparts_default); 13 //setenv("partition", NULL); 14 15 //mtdparts_init(); 16 return 0; 17 } else if (strcmp(argv[1], "delall") == 0) { 18 /* this may be the first run, initialize lists if needed */ 19 mtdparts_init(); 20 21 setenv("mtdparts", NULL); 22 23 /* devices_init() calls current_save() */ 24 return devices_init(); 25 } 26 }
第二种,如韦东山所做,在main.c的main_loop函数里面添加:
1 #ifdef CONFIG_JFFS2_CMDLINE 2 extern int mtdparts_init(void); //先执行init函数 3 if (!getenv("mtdparts")) 4 { 5 run_command("mtdparts default", 0); //再调用默认配置 6 } 7 else 8 { 9 mtdparts_init(); 10 } 11 #endif
以上两种办法都是可以的。