梳理一下uboot是如何从nandflash挂载文件系统的

只是找到了比较一点点的线索, 如下:

首先要有的概念是,内核在挂载文件系统之前,自己会做一个虚拟fs。


1. Uboot:
从flash启动
set bootcmd nand read 0x30000000 0x60000 0x200000\;bootm 0x30000000
set bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0


2.1 Kernel-mountfs
//Do_mounts.c
void __init prepare_namespace(void)
{
ROOT_DEV = name_to_dev_t(root_device_name)

if (strncmp(root_device_name, "/dev/", 5) == 0)
root_device_name += 5;

mount_root();//根据ROOT_DEV创建/dev/root节点并挂载。

}
|||
|||
|||
dev_t name_to_dev_t(char *name)
{
strcpy(s, name);//mtdblock3
part = simple_strtoul(p, NULL, 10); // 3
res = try_name(s, part); // mtdblock3, 3
}

void __init mount_root(void)
{
create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags);
}
||
||
||
static dev_t try_name(char *name, int part)
{
sprintf(path, "/sys/block/%s/dev", name);
fd = sys_open(path, 0, 0); //open sys/block/mtdblock3/dev
if (fd < 0)
goto fail;

//# cat sys/block/mtdblock3/dev
// 31:3
sscanf(buf, "%u:%u", &maj, &min) ;
res = MKDEV(maj, min);

//# cat sys/block/mtdblock3/range
//1
sprintf(path, "/sys/block/%s/range", name); // sys/block/mtdblock3/range
fd = sys_open(path, 0, 0);
if (fd < 0)
goto fail;
len = sys_read(fd, buf, 32);
range = simple_strtoul(buf, &s, 10); // 1
if (part < range)
return res + part;

}

void __init mount_block_root(char *name, int flags)
{
char *fs_names = __getname();
get_fs_names(fs_names);
retry:
for (p = fs_names; *p; p += strlen(p)+1) {
do_mount_root(name, p, flags, root_mount_data);
switch (err) {
case 0:
goto out;
}
}
out:
putname(fs_names);
}

static int __init do_mount_root(char *name, char *fs, int flags, void *data)
{
sys_mount(name, "/root", fs, flags, data);
sys_chdir("/root");
ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
}

2.2 Kernel-driver
//linux/arch/arm/plat-s3c24xx/common-smdk.c

static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 0x00020000,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x00200000,
},
[3] = {
.name = "root",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};

static struct s3c2410_nand_set smdk_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
.partitions = smdk_default_nand_part,
},
};

static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};

void __init smdk_machine_init(void)
{
s3c_device_nand.dev.platform_data = &smdk_nand_info; //平台设备信息

}

//mtdblock_ro.c
static struct mtd_blktrans_ops mtdblock_tr = {
.name = "mtdblock",
.major = 31, //mtdblock主设备号
.part_bits = 0,
.blksize = 512,
.readsect = mtdblock_readsect,
.writesect = mtdblock_writesect,
.add_mtd = mtdblock_add_mtd,
.remove_dev = mtdblock_remove_dev,
.owner = THIS_MODULE,
};

posted @ 2016-01-21 00:27  oucaijun  阅读(1919)  评论(0编辑  收藏  举报
下载TeamViewer完整版 下载TeamViewer