首页 > 代码库 > 根文件系统
根文件系统
1:以s5pv210为例:
irom-->uboot-->linux内核-->根文件系统
irom是为了启动uboot而uboot是为了启动linux内核;只有linux内核开发板时不能工作的,需要配合根文件系统来工作;
首先根文件系统为flash设备提供了一个挂载点/,在根文件下统下/目录下需要一个linuxrc文件,内核在执行linuxrc之前,一直处于内核态,直到执行根文件系统中
的linuxrc这个应用程序,才由内核态转入用户态,这个linuxrc程序就是进程0,在由进程0,生1、2、3.。。。
看下面程序
1 static noinline int init_post(void)
2 __releases(kernel_lock)
3 {
4 /* need to finish all async __init code before freeing the memory */
5 async_synchronize_full();
6 free_initmem();
7 unlock_kernel();
8 mark_rodata_ro();
9 system_state = SYSTEM_RUNNING;
10 numa_default_policy();
11
12 if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
13 printk(KERN_WARNING "Warning: unable to open an initial console.\n");
14
15 (void) sys_dup(0);
16 (void) sys_dup(0);
17
18 current->signal->flags |= SIGNAL_UNKILLABLE;
19
20 if (ramdisk_execute_command) {
21 run_init_process(ramdisk_execute_command);
22 printk(KERN_WARNING "Failed to execute %s\n",
23 ramdisk_execute_command);
24 }
25
26 /*
27 * We try each of these until one succeeds.
28 *
29 * The Bourne shell can be used instead of init if we are
30 * trying to recover a really broken machine.
31 */
32 if (execute_command) {
33 run_init_process(execute_command);
34 printk(KERN_WARNING "Failed to execute %s. Attempting "
35 "defaults...\n", execute_command);
36 }
37 run_init_process("/sbin/init");
38 run_init_process("/etc/init");
39 run_init_process("/bin/init");
40 run_init_process("/bin/sh");
41
42 panic("No init found. Try passing init= option to kernel.");
43 }
sys_open((const char __user *)首先开启控制台
然后执行run_init_process(execute_command);命令 即执行linuxrc这个应用程序(execut_commant即/linuxrc),执行linuxrc就进入了一个死循环中,
2:linuxrc程序的本质:我们用的linuxrc文件就是采用busybox代码来生成的一个二进制文件,busybox包含了/etc目录下的配置文件,/bin、/sbin目录下的命令文件,以及/lib目录下的
当我们进入根文件系统,发现有很多命令,如ls、cp、rm等,这些都是应用程序,但这些都是通过链接到busybox实现的功能。如:
/bin/ls -> busybox
/bin/cp -> busybox
/bin/rm -> busybox
就连sbin/init进程也是链接到busybox的,所以busybox是很多命令程序和工具的集合。所以要分析init怎么运行,就要分析busybox。
解压busybox源码,在/init/init.c。(这个就是编译busybox后就是被init链接的代码)
函数调用流程:
busybox -> init_main() -> parse_inittab() -> run_actions()
解析inittab文件函数parse_inittab();
在parse_inittab()函数里,首先打开/etc/inittab这个文件,接着解析inittab。inittab配置文件的格式说明和例子在busybox的源码里面有,搜索一下就能找到。
这里参考http://blog.csdn.net/jianchi88/article/details/7682901博客;
3:根文件系统的实质
根文件系统其实是一套软件,一套代码,
首先,存储设备(块设备,像硬盘、flash等)是分块(扇区)的,物理上底层去访问存储设备时是按照块号(扇区号)来访问的。这就很麻烦。
其次,文件系统是一些代码,是一套软件,这套软件的功能就是对存储设备的扇区进行管理,将这些扇区的访问变成了对目录和文件名的访问。我们在上层按照特定的目录和文件名去访问一个文件时,文件系统会将这个目录+文件名转换成对扇区号的访问。
最后,不同的文件系统的差异就在于对这些扇区的管理策略和方法不同,譬如坏块管理、碎片管理。
4:根文件系统可以做成进行形式的烧录到flash中,也可以以文件夹的形式存在;
镜像形式的话,就需要专门的制作工具来制作:
如ext2、ext3、ext4格式的根文件系统需要 mke2fs这个工具来制作;可以参考这篇博客来制作ext2格式的根文件系统;
http://blog.csdn.net/zhengmeifu/article/details/24174513
制作最小的根文件系统:
(1) mkdir rootfs (后面文件系统就挂载在这里)
(2)dd if=/dev/zero of=rootfs.ext2 bs=1024 count=2408(2M大小)
(3)losetup /dev/loop0 rootfs.ext2 (如果loop0已被使用,可以使用loop1等。)
(4)mke2fs -m 0 /dev/loop1 2048
(5)mount -t ext2 /dev/loop1 ./rootfs/
(6)我们向镜像中写入一个普通文件linuxrc。这个文件就会成为我们制作的镜像中的/linuxrc。内核挂载了这个镜像后就会尝试去执行/linuxrc。然后执行时必然会失败。我们将来实验看到的现象就应该是:挂载成功,执行/linuxrc失败。
(7)将来真正去做有用的rootfs时,就要在这一步添加真正可以执行的linuxrc程序,然后还要添加别的/lib目录下的库文件,/etc目录下的配置文件等。
(8)卸载掉,然后镜像就做好了。
umount /dev/loop1
losetup -d /dev/loop1
5:制作文件夹形式的根文件系统,文件夹根文件系统是通过nfs来链接的:
为何要挂载NFS分区?
答:可以将PC机的一个目录虚拟,通过网络共享给2410开发板载linux使用,省去了将程序烧入flash的烦恼
介绍下如何挂载NFS分区
准备工作
1)安装nfs-kernel-server
ubuntu下执行apt-get install nfs-kernel-server
2)在根目录建立nfs文件夹,也可以建立在其他地方
3)Linux的IP为192.168.1.30
4) 开发板的IP为192.168.1.10
5)确认Redhat上装好了NFS软件包
在终端输入
[root@localhost examples]# rpm -q nfs-utils
nfs-utils-1.0.9-24.el5
6)配置NFS服务器
[root@localhost examples]# vi /etc/exports
打开配置文件后,一般空空如也,自己写,写入以下配置信息:
/home/example/rootfs 192.168.2.*(rw,sync,no_root_squash)
解析:
/home/example/rootfs -->共享的文件夹路径
192.168.1.* -->允许访问的IP号,当然也可以具体指定一个,比如192.168.2.11
(rw,sync,no_root_squash) -->权限等,具体参数的意思可以百度
所以配置信息还是比较简单。
7)启动/重启NFS服务器
不管NFS事先有没有启动,都可以用重启命令,如下:
[root@localhost examples]# /etc/init.d/nfs-kernel-server restart
OK,至此服务器端配置完毕,接下来在客户端开发板上使用,即所谓的挂载文件系统。
在挂载之前,需确认网络是否通了。将网线连上,通过ping命令确保网络正常,比如服务器IP设置为192.168.2.22,开发板IP设置为192.168.2.11,
两者子网掩码均为255.255.255.0,这样在开发板上通过命令ping 192.168.1.22即能看到响应。
8)挂载文件系统
在开发板上的mnt文件夹下新建nfs文件夹,用于映射服务器上共享的文件夹,当然你也可以在其他地方建,只要输入命令正确,命令如下:
mount -t nfs 192.168.2.22:/home/example/rootfs /mnt/nfs
解析:
mount -t nfs -->挂载命令,表示挂载NFS共享的文件夹
192.168.2.22:/home/example/rootfs -->服务器端共享的文件夹路径,格式为 IP:/共享文件夹路径
/mnt/nfs -->映射到本地的文件夹,即客户端开发板上的文件夹。
注:如果输入命令,出现如下错误“svc: failed to register lockdv1 RPC service (errno 111) ”,则改用如下命令:
mount -t nfs -o nolock 192.168.2.22:/home/example/rootfs /mnt/nfs
9)挂载完毕,使用
挂载完毕后,在服务端对共享文件夹里的操作,均能在客户端中映射的文件夹中看见。
Exa.
往服务端共享文件夹中拷贝一个文件,[root@localhost examples]# cp test.c rootfs/
则在客户端能也看见,在客户端命令:[root@localhost led]# cd /mnt/nfs/
[root@localhost nfs]# ls
test.c
OK,至此挂载完毕,其实就是通过NFS共享了一个文件夹。
根文件系统