在linux中,我们一般会对flash进行一个分区,不同的地址空间存放不同的内容。一般我们只需要分3-4个区,第一个为boot区,一个为boot参数区(传递给内核的参数),一个为内核区,一个为文件系统区。而对于bootloader中只要能将内核下载到A~B区的A地址开始处就可以,C~D区的C起始地址下载文件系。这些起始地址在MTD的分区信息中能找到。所以bootloader对分区的概念不重要,只要它能把内核烧到A位置,把文件系统烧到C位置。所以,在bootloader对Flash进行操作时,哪块区域放什么是以内核为主。
但是在linux中如何来分区,分区的方式有几种呢?在网上可以看到好多关于这个问题的表述,这里我把各种说法整理一下,以方便学习.
一般在配置内核时我们会看到有三种方式:
1)、Redboot partition table parsing
2)、Kernel command-line partition table definition
3)、Board-specific mapping drivers
当然MTD还允许配置没有分区,在这种情况下,MTD简单地将整个闪存作为一个单一的设备访问。
下面就针对上面的三种方式来分别说明:
第一句说明flash芯片已经探测到了它的一些信息也通过CFI读了出来。CFI是一个工业标准,可以在网上找一下相关的信息。这里我们要说明,如果我们的flash支持CFI我们必须使能MTD_CFI选项,只有这样,才可以成功的探测flash.
Redboot的启动脚本中传递命令行参数给内核如下:
使用exec -c 选项,例如:
fis load -d vmlinux
exec -c "console=ttyS0,115200 root=31:02 rootfstype=jffs2 mtdparts=ar7100-nor0:256k(boot),0x130000(kernel),0x600000(jffs2),-(config) init=/sbin/init"
static struct mtd_partition pq2fads_partitions[] = { { #ifdef CONFIG_ADS8272 .name = "HRCW", .size = 0x40000, .offset = 0, .mask_flags= MTD_WRITEABLE, /* force read-only */ }, { .name = "User FS", .size = 0x5c0000, .offset = 0x40000, #else .name = "User FS", .size = 0x600000, .offset = 0, #endif }, { .name = "uImage", .size = 0x100000, .offset = 0x600000, .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { .name = "bootloader", .size = 0x40000, .offset = 0x700000, .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { .name = "bootloader env", .size = 0x40000, .offset = 0x740000, .mask_flags = MTD_WRITEABLE, /* force read-only */ } }; /* pointer to MPC885ADS board info data */ extern unsigned char __res[]; static int __init init_pq2fads_mtd(void) { bd_t *bd = (bd_t *)__res; physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL); physmap_set_partitions(pq2fads_partitions, sizeof (pq2fads_partitions) / sizeof (pq2fads_partitions[0])); return 0; } static void __exit cleanup_pq2fads_mtd(void) { } module_init(init_pq2fads_mtd); module_exit(cleanup_pq2fads_mtd);
static struct flash_platform_data coyote_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource coyote_flash_resource = {
.start = COYOTE_FLASH_BASE,
.end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device coyote_flash = {
.name = "IXP4XX-Flash",//这个name一定上与上面的/drivers/mtd/maps/pq2fads.c中platform_driver的name一致
.id = 0,
.dev = {
.platform_data = &coyote_flash_data,
},
.num_resources = 1,
.resource = &coyote_flash_resource,
};
...
static struct platform_device *coyote_devices[] __initdata = {
&coyote_flash,
&coyote_uart
};
static void __init coyote_init(void)
{
...
platform_add_devices(coyote_devices,
ARRAY_SIZE(coyote_devices));
}
...