浅析yaffs2文件系统被mount的梗概流程
《浅析linux下mtd设备onenand存储器的分区和节点创建流程及yaffs2文件系统挂载》
在init.rc脚本中
on init
loglevel 3
...
mkdir /system
mkdir /local 0777 system system
mkdir /data 0771 system system
# mount mtd partitions
# Mount /system rw first to give the filesystem a chance to save a checkpoint
mount yaffs2 mtd@system /system
# We chown/chmod /data again so because mount is run as root + defaults
mount yaffs2 mtd@userdata /data
chown system system /data
chmod 0771 /data
# Same reason as /data above
mount yaffs2 mtd@local /local
chown system system /local
chmod 0777 /local
...
所以init进程将在执行init.rc脚本时,会执行mtd文件系统的mount操作,
比如:mount yaffs2 mtd@system /system
int do_mount(int nargs, char **args)
{
...
source = args[2];
if (!strncmp(source, "mtd@", 4)) {
n = mtd_name_to_number(source + 4);//进行转换
if (n >= 0) {
sprintf(tmp, "/dev/block/mtdblock%d", n);
source = tmp;
}
}
return mount(source, args[3], args[1], flags, options);
//source 为"/dev/block/mtdblock0等"
//args[3] 为"/system"
//args[2] 为"yaffs2"这是文件系统的名字,即:init_yaffs_fs注册登记的如下yaffs系统
//
//static struct file_system_to_install fs_to_install[] = {
//#ifdef CONFIG_YAFFS_YAFFS1
//{&yaffs_fs_type, 0},
//#endif
//#ifdef CONFIG_YAFFS_YAFFS2
//{&yaffs2_fs_type, 0},
//#endif
//{NULL, 0}
};
static struct file_system_type yaffs_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs",
.get_sb = yaffs_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
static struct file_system_type yaffs2_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs2",
.get_sb = yaffs2_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
//来看看系统调用sys_mount[luther.gliethttp]
asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
char __user * type, unsigned long flags,
void __user * data)
}
int mtd_name_to_number(const char *name)
{
int n;
if (mtd_part_count < 0) {
mtd_part_count = 0;
find_mtd_partitions();
}
for (n = 0; n < mtd_part_count; n++) {
if (!strcmp(name, mtd_part_map[n].name)) {
return mtd_part_map[n].number;
}
}
return -1;
}
static void find_mtd_partitions(void)
{
int fd;
char buf[1024];
char *pmtdbufp;
ssize_t pmtdsize;
int r;
fd = open("/proc/mtd", O_RDONLY);
if (fd < 0)
return;
buf[sizeof(buf) - 1] = '/0';
pmtdsize = read(fd, buf, sizeof(buf) - 1);
pmtdbufp = buf;
while (pmtdsize > 0) {
int mtdnum, mtdsize, mtderasesize;
char mtdname[16];
mtdname[0] = '/0';
mtdnum = -1;
r = sscanf(pmtdbufp, "mtd%d: %x %x %15s",
&mtdnum, &mtdsize, &mtderasesize, mtdname);
if ((r == 4) && (mtdname[0] == '"')) {
char *x = strchr(mtdname + 1, '"');
if (x) {
*x = 0;
}
INFO("mtd partition %d, %s/n", mtdnum, mtdname + 1);
if (mtd_part_count < MAX_MTD_PARTITIONS) {
strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1);
mtd_part_map[mtd_part_count].number = mtdnum;
mtd_part_count++;
} else {
ERROR("too many mtd partitions/n");
}
}
while (pmtdsize > 0 && *pmtdbufp != '/n') {
pmtdbufp++;
pmtdsize--;
}
if (pmtdsize > 0) {
pmtdbufp++;
pmtdsize--;
}
}
close(fd);
}
# cat /proc/mtd,这里由init_yaffs_fs驱动完成
dev: size erasesize name
mtd0: 00100000 00020000 "Bootloader"
mtd2: 000c0000 00020000 "NVM"
mtd3: 00040000 00020000 "logo"
mtd4: 00300000 00020000 "Kernel"
mtd5: 06000000 00020000 "system"
mtd7: 04000000 00020000 "userdata"
mtd8: 01e00000 00020000 "local"
mtd9: 008c0000 00020000 "cache"
mtd10: 00600000 00020000 "fota"
mtd11: 00080000 00020000 "panic"
mtd12: 00080000 00020000 "BBT"
至于"/dev/block/mtdblock%d"下面的这些节点是在什么时候,由谁创建的,
分为2部分,一部分是平台提供的flash分配图,如下:
在arch/arm/mach-pxa/luther.c这个产品平台文件中,即:
MACHINE_START(LUTHER, "luther")
.phys_io = 0x40000000,
.boot_params = 0xa0000100,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = luther_init,
MACHINE_END
static struct mtd_partition android_256m_v75_partitions[] = {
[0] = {
.name = "Bootloader",
.offset = 0,
.size = 0x100000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
...
[3] = {
.name = "logo",
.offset = 0xa00000,
.size = 0x040000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
[4] = {
.name = "Kernel",
.offset = 0xa40000,
.size = 0x300000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
[5] = {
.name = "system",
.offset = 0x0d40000,
.size = 0x6000000, /* mount 96M fs */
},
...
};
static void __init _init_onenand(void)
{
if (is_android()) {
luther_onenand_info.parts = android_256m_v75_partitions;
luther_onenand_info.nr_parts =
ARRAY_SIZE(android_256m_v75_partitions);
}
else {
luther_onenand_info.parts = pxa930_256m_v75_partitions;
luther_onenand_info.nr_parts =
ARRAY_SIZE(pxa930_256m_v75_partitions);
}
pxa3xx_device_onenand.dev.platform_data = &luther_onenand_info;
platform_device_register(&pxa3xx_device_onenand);
}
令一部分就是对应的驱动:
drivers/mtd/onenand/generic.c
#define DRIVER_NAME"onenand"
static struct platform_driver generic_onenand_driver = {
.driver = {
.name= DRIVER_NAME,
},
.probe= generic_onenand_probe,
.remove= generic_onenand_remove,
#ifdef CONFIG_PM
.suspend= NULL,
.resume= NULL,
#endif
};
所以最后调用probe函数来创建平台文件luther.c中指定的flash配置图,
static int __devinit generic_onenand_probe(struct platform_device *dev)
{
struct onenand_info *info;
struct platform_device *pdev = dev;
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
int err;
info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
if (!request_mem_region(res->start, size, pdev->name)) {
err = -EBUSY;
goto out_free_info;
}
info->onenand.base = ioremap(res->start, size);
if (!info->onenand.base) {
err = -ENOMEM;
goto out_release_mem_region;
}
info->onenand.mmcontrol = pdata->mmcontrol;
info->onenand.irq = platform_get_irq(pdev, 0);
info->mtd.name = pdev->dev.bus_id;
info->mtd.priv = &info->onenand;
info->mtd.owner = THIS_MODULE;
if (onenand_scan(&info->mtd, 1)) {
err = -ENXIO;
goto out_iounmap;
}
#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
if (err > 0)
add_mtd_partitions(&info->mtd, info->parts, err);
else if (err < 0 && pdata->parts)
add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);//添加设备创建设备节点
else
#endif
err = add_mtd_device(&info->mtd);
dev_set_drvdata(&pdev->dev, info);
return 0;
out_iounmap:
iounmap(info->onenand.base);
out_release_mem_region:
release_mem_region(res->start, size);
out_free_info:
kfree(info);
return err;
}
以上是一个大体的流程梗概,对于更细致的分析,以后有时间再慢慢解读[luther.gliethttp]
分享到:
相关推荐
yaffs yaffs2 文件系统正确补丁包 移植LINUX常用 CSDN有的下载的编译不正确,特发布正确的。
YAFFS2文件系统的加载过程,具普遍性
Yaffs2文件系统是转为Nand Flash设计的文件系统,是基于日志式的文件系统
s3c2440下 yaffs2文件系统制作详解,本人实践成功
linux下yaffs2文件系统剖析,详细阐述yaffs2文件系统在nandflash中的实现
yaffs2 linux bsp YAFFS意义为‘yet another... YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,目前有YAFFS 和YAFFS2 两个版本,两个版本的主要区别之一在于YAFFS2 能够更好的支持大容量的NAND FLASH芯片。
截止到2013年4月26日为止最新的yaffs2文件系统源代码
YAFFS意义为‘yet another flash file system... YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,目前有YAFFS 和YAFFS2 两个版本,两个版本的主要区别之一在于YAFFS2 能够更好的支持大容量的NAND FLASH芯片。
yaffs2文件系统源码在网络上非常难找,找到了也很难下载下来!!!!
Yaffs2文件系统的源代码,很齐全,很实用,有需要的,可以下载。
这是在linux2.6.30以上版本的yaffs2文件系统代码
文件系统是包括在一个磁盘(包括光盘、软盘、闪盘及其它存储设备)或分区中的目录结构;一 个可应用的磁盘设备可以包含一个或多个文件系统;...为了挂载(mount)文件系统,您必须指定一个挂载点(所挂载的目录)。
yaffs2 文件系统
压缩包 制作yaffs2文件系统及其映像工具
yaffs2文件系统分析 yaffs2文件系统分析
yaffs和yaffs2文件系统工具
YAFFS 嵌入式文件系统 YAFFS 嵌入式文件系统