根文件系统
一、什么是根文件系统
根文件系统首先是一种文件系统,该文件系统不仅具有普通文件系统的存储数据文件的功能,但是相 对于普通的文件系统而言它还是内核启动时所挂载(mount)的第一个文件系统,系统引导启动程序会 在根文件系统挂载之后从中把一些初始化脚本(如inittab、rcS)和服务加载到内存中去运行。我们要 明白文件系统和内核是完全独立的两个部分。在嵌入式中移植的内核下载到开发板上,是没有办法真正 的启动Linux操作系统的,会出现无法加载文件系统的错误。
根文件系统之所以在前面加一个”根“,说明它是加载其它文件系统的”根“,既然是根的话,那么 如果没有这个根,其它的文件系统也就没有办法进行加载的。它包括了Linux启动时所必须的目录和关 键性的文件,例如Linux启动时都需要有init目录下的相关文件,在 Linux挂载分区时Linux一定会 找/etc/fstab这个挂载配置文件等,根文件系统中还包括了应用程序(如ls、mkdir、rm、ifconfig等命 令)和 GNU C 库(glibc、eglibc或uclibc)等。任何包括这些Linux 系统启动所必须的文件都可以成 为根文件系统。Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件 系统,则系统会出错而退出启动。成功之后可以自动或手动挂载其他的文件系统。因此,一个系统中可 以同时存在不同的文件系统。
-
为什么需要跟文件系统
- init进程的应用程序在根文件系统上
- 根文件系统提供了根目录 /
- 内核启动后的应用层配置(etc目录)在跟文件系统上(几乎可以认为发行版是linux内核+根文件系统(rootfs))
- shell命令程序在跟文件系统上
一套linux体系、只有内核本身是不能工作的,必须要有rootfs(上的etc目录下的配置文件、/bin、/sbin等目录下的shell命令、还有/lib目录下的库文件等。。。。)相配合。
-
根文件系统的实质
- 根文件系统是特殊用途的文件系统。
- 根文件系统也必须属于某种文件系统格式。
- 文件系统到底是用来干嘛的
文件系统是一些代码,是一套软件,这套软件的功能就是对存储设备的扇区进行管理,将这些扇区的访问变成了对目录和文件名的访问。我们在上层按照特定的目录和文件名去访问一个文件时,文件系统会将这个目录+文件名转换成对扇区号的访问。
不同的文件系统的差异在于对于这些扇区的管理策略和方法不同,(坏块管理、碎片管理)
二、根文件系统的形式
-
镜像文件的形式
- 使用专用工具软件制作的可供烧录的镜像文件。
- 镜像中包含了跟文件系统中的所有文件。
- 烧录此镜像类似于对相应分区格式化
- 镜像文件系统具有一定的格式。格式是内化的,跟文件的后缀名是无关的。
-
文件夹的形式
- 根文件系统其实就是一个包含特定内容的文件夹而已。
- 根文件系统可由任一个空文件夹添加必要文件构成而成。
- 跟文件系统的雏形就是在开发主机中构造的文件夹形式的。
镜像文件形式的根文件系统主要目的是用来烧录到块设备上,设备上的内核启动后去挂载它。镜像形式的根文件系统是由文件夹形式的根文件系统使用专用的镜像制作工具制作而成的。
最初在开发主机目录中随便mkdir创建了一个空文件夹,然后向其中添加了一些必要的文件(包括etc目录下的运行时配置文件、/bin目录下的可执行程序、/lib目录下的库文件等等。。。)后就形成了一个文件夹形式的rootfs。然后这个文件夹形式的rootfs可以被kernel通过nfs方式来远程挂载使用,但是不能用来烧录块设备。我们为了将这个rootfs烧录到块设备中于是用一些专用的转件工具将其制作成可供烧录的一定格式的根文件系统镜像。
文件夹形式的rootfs是没有合适的,制作成镜像后就有了一定的rootfs格式了,格式是由我们的镜像制作过程和制作工具来确定的。每一种格式的镜像制作工具的用法都不同。
三、自己制作ext2格式的根文件系统
-
mke2fs介绍
是linux中的一个应用程序,在Ubuntu中是默认安装了的。这个应用程序就是用来制作ext2、ext3、ext4、等格式的根文件系统的。
一般用来制作各种不同格式的rootfs应用程序的名字都很相似,类似于mkfs.xxx;
在Ubuntu14.04中的mkfs.ext2等都是mke2fs的符号链接。
-
操作步骤
- 创建rootfs.ext2文件并且讲之挂载到一个目录下方便访问他。
- 我们向镜像中写入一个普通文件linuxrc ,这个文件就会成为我们制作的镜像中的/linuxrc。内核挂载了这个镜像后就会尝试去执行/linuxrc。然后执行时必然会失败。我们将来实验看到的现象应该是挂载成功,执行linuxrc失败。
- 将来我们真正去做有用的rootfs时,就要在这一步添加真正可以执行的linuxrc程序,然后还要添加别的/lib目录下的库文件,/etc目录下的配置文件等。
- 卸载掉,然后镜像就做好了
《参考资料:http://blog.youkuaiyun.com/zhengmeifu/article/details/24174513》
创建rootfs:dd if=/dev/zero of=rootfs.ext2 bs=1024 count=2048
挂载:losetup /dev/loop1 rootfs.ext2
mke2fs -m 0 /dev/loop1 2048
mount -t ext2 /dev/loop1 ./rootfs/
添加linuxrc:cd rootfs
touch linuxrc
cd ../
卸载:
umount /dev/loop1
losetup -d /dev/loop1
四、nfs方式启动自制简易文件夹形式的rootfs
-
什么是nfs
- nfs(network file system)是一种网络通讯协议,由服务器和客户端组成。
- nfs的作用。利用nfs这种协议,可以做出很多种直接性应用。我们这里使用nfs主要是使用rootfs的挂载。开发板中运行kernel做nfs的客户端,主机Ubuntu中搭建nfs服务器。在主机Ubuntu的nfs服务器中导出我们制作的文件夹形式的rootfs目录,则在客户端中就可以去挂载这个文件夹形式的rootfs进而去启动系统。
-
搭建nfs服务器
参照文档
-
配置内核以支持nfs作为rootfs
-
设置nfs启动方式的bootargs (注意修改ip)
在uboot中设置如下启动参数(IP根据实际使用更改) setenv bootargs root=/dev/nfs nfsroot=192.168.1.141:/root/porting_x210/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200 bootargs有两种设置方式,镜像方式和nfs启动的方式。上面的就是nfs方式启动的bootargs,以镜像方式启动的bootargs是下面这一种。 setenv bootagrs console=ttySAC2,115200 root=/dev/mmcblk02p rw init=/linuxrc rootfstype=ext2
-
在menuconfig中配置支持nfs启动方式
1、配置网络部分,主要是使能CONFIG_IP_PNP以在2中能够看到Root file system on NFS选项 Networking support Networking options TCP/IP networking IP: kernel level autoconfiguration [*] IP: DHCP support [*] IP: BOOTP support 2、配置开启nfs服务 File systems ---> Network File Systems ---> <*> NFS client support [*] NFS client support for NFS version 3 [*] NFS client support for the NFSv3 ACL protocol extension [*] NFS client support for NFS version 4 (EXPERIMENTAL) [*] NFS client support for NFSv4.1 (DEVELOPER ONLY) [*] Root file system on NFS
-
五、linuxrc又是什么
-
/linuxrc是一个可执行的应用程序
- /linuxrc是应用层的,和内核源码一点关系都没有。
- /linuxrc是在开发板当前内核系统下是可执行的的,因此在ARM SOC的Linux系统下,这个应用程序就是用 arm-linux-gcc 编译链接而成的;如果在PC机linux系统下,那么就是用gcc编译链接而成的。
- /linuxrc如果是静态编译链接的那么直接可以运行,如果是动态编译链接的那么我们还必须给他提供必要的库文件才能运行。但因为/linuxrc这个程序是由内核直接调用执行的,因此用户没机会去导出库文件的路径。因此在实际上这个/linuxrc没发动态链接,一般都是动态链接。
-
/linuxrc执行时引出用户界面
- 操作系统启动后在一系列的自己运行和配置之后,最终会给我们用户一个操作界面(cmdline or GUI),这个用户界面就是由/linuxrc带出来的。
- 用户界面等很多事并不是在/linuxrc程序中负责的,用户界面有自己的应用程序,但是用户界面的应用程序是直接或间接的被/linucrc调用执行的。用户界面的程序就是进程2,3,4·······这就是我们说的进程一(init进程,也就是linuxrc)是其他所有应用程序进程的父进程。
-
/linuxrc负责系统启动后的配置
- 操作系统启动起来后不可以直接使用,需要进行配置。
- 操作系统启动后的应用层的配置(一般叫做运行时配置,英文简写etc)是为了让我们的操作系统用起来更方便,更适合我个人的爱好或者实用性。
-
/linuxrc在嵌入式Linux中一般就是busybox
- busybox是一个C语言写出来的项目,里面包含了很多.c 和 .h 文件。这个项目可以被配置编译成各个平台下面可以运行的应用程序。我们如果用arm-linux-gcc来编译,就可以得到一个可以在我们开发板linux内核上运行的应用程序。
- busybox这个程序开发出来就是为了在嵌入式环境下构建rootfs使用的,也就是说他就是专门开发的init进程的应用程序。
- busybox为我们当前的linux系统提供了一整套的shell命令程序集。譬如vi、cd、mkdir、ls等。在桌面版的linux发行版中(Ubuntu、readhat等)中vi、cd、ls等都是一个一个的单独的应用程序。但是在嵌入式linux中,为了省事我们把vi、cd等所有常用的shell命令集合到一起构成了一个shell命令包,起名叫busybox。
六、rootfs中还应该有什么
-
最重要的就是上面的/linuxrc
-
dev目录下的设备文件
-
在linux中一切皆文件,因此一个硬件设备也被虚拟化成一个设备文件来访问,在linux系统中 /dev/xxx 就表示一个硬件设备。我们要操作这个硬件时就是open打开这个设备文件。然后read/write/ioctl操作这个设备,最后close关闭这个设备。
-
在最小的rootfs中 /dev目录也是不可少的,这个目录中至少有其中一两个文件是rootfs必须的。
-
sys和proc目录。在最小rootfs中也是不可省略的,但是这两个只要创建了空文件夹即可,里面是没东西的,也不用有东西。这两个目录也是和驱动有关的。属于linux中的虚拟文件系统。
-
usr是系统的用户所有的一些文件的存放地,这个东西将来busybox会自动生成。
-
etc目录中的所有文件全部都是运行时配置文件,会直接或间接的被/linuxrc调用执行完成操作系统的运行时配置。etc目录是制作rootfs目录的关键。
-
lib目录也是rootfs中很关键的一个,不能省略的一个,lib目录下存放的是当前操作系统中的动态个静态链接库。我们主要是为了动态链接库。
-
七、VFS简介
-
什么是VFS
- VFS是linux内核的一种设计理念、设计机制、VFS就是Vitrual file system 虚拟文件系统
- 具体的一些文件系统如FAT、NTFS、ext2、ext3等,的只要设计目的是为了管理磁盘(块设备)
- VFS借鉴了文件系统的设计理念(通过文件系统将底层难以管理的物理磁盘的扇区式访问,转换为目录+文件名的方式来访问)将硬件设备的访问也虚拟化成了对目录+文件+文件的访问。所以有了VFS后我们可以通过设备文件(目录+文件名,譬如/dev/mmcblk0p2)的方式来访问系统中的设备。
- 以上只是VSF的部分功能,但是VFS还有其他很多功能。
-
VFS的意义
- 解决了对设备的访问,将对硬件设备的访问核对普通文件的访问接口统一化了(linux中一切皆文件)。
- 将操作系统上层(应用层)对下层不同文件系统类型访问细节屏蔽掉了。因此如果没有VFS那我们写cp命令(其他命令也一样)的时候就不得不去考虑你cp的这个文件在什么文件系统类型下。所以cp命令非常复杂,因此要考虑具体的文件系统类型。有了VFS后情况就不同了。VFS成了一个隔离层,隔离了下层的不同文件系统的差异性,对上层应用提供一个统一的接口。
- VFS将不同文件系统和下层硬件设备驱动(块设备)驱动之间的细节也给屏蔽了。不同类型的文件系统在本身设计时是不用考虑各种不同的硬件设备的具体操作差异的,这里有一个类似于VFS的设计理念。
-
VFS和我们学习的关系
- VFS机制和rootfs挂载,和其他文件系统发的挂载都是有关联的
- 内核中有一些 sys proc 这种虚拟文件系统,这种东西也是和VFS机制有关的。
- /dev/目录下的设备文件都和VFS有关,所以学习驱动绕不开VFS。