Linux根文件系统制作与各种挂载方式的实现

时间:2022-02-23 09:06:05

Linux根文件系统的制作


什么是文件系统

计算机的文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中。
文件系统通常使用硬盘和光盘这样的存储设备,并维护文件在设备中的物理位置。但是,实际上文件系统也可能仅仅是一种访问数据的界面而已,实际的数据是通过网络协议(如NFS、SMB、9P等)提供的或者内存上,甚至可能根本没有对应的文件(如proc文件系统)。
严格地说,文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。摘自<<*>>
磁盘需要首先分区,然后再在格式化成指定文件系统。Linux操作系统支持的文件系统有ext2,ext3,ext4,nfs,yaffs2等等,这些文件系统都可以在内核源代码中找到其定义和实现。
Linux根文件系统制作与各种挂载方式的实现

什么是根文件系统

和Windows的C,D,E等盘符相似,Linux操作系统也可以将磁盘,Flash等存储设备划分为若干个区,在不同分区下存放不同类型的文件。比如Windows的C盘中就存放着启动系统所必须的一系列文件,而在Linux系统中,内核映像文件(在嵌入式系统众,内核一般单独存放在一个分区中),内核启动后运行的第一个程序(init),给用户提供操作界面的shell程序,应用程序所依赖的库等。这些必需的基本的文件集合就被称为根文件系统。它们都放在一个分区中,在系统启动后就会首先挂载这个分区,也就是挂载根文件系统。

为什么需要根文件系统

要回答这个问题,我们需要了解Linux操作系统的启动流程。Linux操作系统由三部分组成,分别是Bootloader,Linux kernel,File system.系统上电时首先执行的是Bootloader程序,主要做的任务是对硬件的初始化,并加载linux内核,linux内核启动后,就必须要挂载根文件系统,根文件系统的作用在上个小标题可以看到。没有文件系统的支持,即使linux内核运行起来了,我们也不能对内核进行操作。

如何制作根文件系统


准备阶段:需要用到的安装包有

Linux内核源代码包
根文件系统需要用到的配置文件包
用来移植根文件系统的常用命令的busybox安装包
通过samba服务器将所有要用到的安装包都拷贝到虚拟机中
我所使用的操作系统是红帽企业版6,也就是RHEL 6。

1.创建根文件系统与目录


1.1创建目录

mkdir /home/rootfs
cd /home/rootfs
mkdir bin dev sbin proc sys usr var tmp mnt etc
mkdir usr/bin usr/sbin usr/lib lib/modules

创建根目录下的各种子目录以及用户目录下的命令,库,模块等目录。

1.2创建设备文件

cd /home/rootfs/dev
mknod -m 666 console c 5 1
mknod -m 666 null c 1 3

在devices目录下创建两个必备的设备文件

1.3添加配置文件

将拷贝到linux下的配置文件安装包解压并讲解压后etc目录下的文件都复制到创建的根文件系统下的etc目录中

tar -xvzf etc.tar.gz
cp ./etc/* /home/rootfs/etc -rf

1.4添加内核模块

进入解压后的linux源代码目录,执行第一条命令,指定架构和交叉编译工具链,编译生成的.ko文件就是我们需要用到的内核模块,但是它们是散落在linux内核代码目录下的各个子目录中的,所以需要执行第一条命令,将所有的内核模块都聚集起来并指定安装的目录,路径自然是要指定为我们所创建的根文件系统下了。这里指的根文件系统是所有文件和目录的集合。

cd /home/linux
make modules ARCH=arm CROSS_COMPILE=arm-linux-
make modules_install ARCH=arm INSTALL_MOD_PATH=/home/rootfs

1.5配置并编译busybox

所谓的制作根文件系统,就是创建各种目录,并且在里面创建各种文件。比如在/bin,/sbin目录下存放着各种可执行程序,在/etc目录下面存放配置文件,在/lib目录下面存放库文件。而busybox就是用来创建这些目录下的可执行文件,不包括配置文件和库文件。busybox为各种小型的或者嵌入式系统提供了一个比较完整的工具集。busybox是一个遵循GPL协议的开源项目,源代码可以在网上免费下载。

tar -xvzf /home/busybox1.13.3.tar.gz
cd /home/busybox1.13.3
make menuconfig
Build Options ---> [*]Build BusyBox as a static binary
(arm-linux-)Corss Compiler prefix
Installation Options ---> [*]Don't use /usr
(/home/rootfs)BusyBox installation prefix
make
make install

上面这段代码包括了解压以及通过图形界面来配置busybox。选择编译时静态链接库,交叉编译工具链的前缀,不安装到系统的/usr目录下,以及编译后安装到/home/rootfs,即我们制作的根文件系统下。退出后保存配置,然后就可以编译,安装了。安装完成后,可以在根文件系统比如/bin目录下看到很多可执行的文件。如果没有看到,那么请仔细检查在配置busybox时的指定路径名是否正确。到这里,整个根文件系统就制作好了。

2.挂载根文件系统到内核

2.1initramfs挂载

2.1.1搭建TFTP服务器

这里涉及到如何搭建TFTP服务器,以及如何通过TFTP服务器将制作好的内核映像下载到开发板。
RHEL红帽操作系统安装软件方式有两种,一种是RPM机制,一种是yum机制。RPM安装软件不是很方便,因为可能安装完一个后还要后续再安装它的依赖,所以采用yum安装,yum可以自动安装软件需要的依赖,非常方便,Yum机制类似于Ubuntu的apt-get install。首先在仓库中找到tftp服务器软件,安装以后在根文件系统创建一个tftpboot目录,将开发板要下载的内核镜像文件放入其中,同时在tftp服务器的配置文件中指定链接的目录路径,以及将失能失效。最后重启服务器,这样tftp服务器就搭建完毕。

yum list|grep tftp
yum install tftp-server.i686
mkdir /tftpboot
chmod 777 /tftpboot
vim /etc/xinetd.d/tftp
disbale=no
server_args= -s /tftpboot

/etc/init.d/tftp restart

配置linux内核,选择使用initramfs方式来挂载文件系统。编译后将生成的uImage复制到创建/tftpboot目录下

cd /home/rootfs
ln -s ./bin/busybox init
cd /home/linux
make menuconfig ARCH=arm
General setup --->[*]Initial RAM filesystem and RAMdisk(initramfs/initrd) support
(/home/rootfs)Initramfs source file(s)
make uImage ARCH=arm CROSS_COMPILE=arm-linux-
cp /home/linux/arch/arm/boot/uImage /tftpboot

最后还需要设置一下开发板uboot的环境变量,设置加载内核后uboot传递给内核的启动参数。

printenv
setenv bootargs noinitrd console
=ttySAC0,115200
saveenv
tftp c0008000 uImage
bootm c0008000

2.2NFS挂载

使用NFS来挂载的好处是显而易见的, 如果通过initramfs方式将文件系统挂载到内存,速度是很快,但是如果当你需要改动根文件系统下的文件或者目录时,你就需要每次都重新编译一次内核,编译内核是很慢的。 所以在开发阶段,使用NFS来挂载根文件系统,当需要改动时,通过网络实时生效,非常便捷省事。切换到Linux内核目录,启动图形配置界面,选择不使用initramfs方式来挂载文件系统,选择以NFS方式来挂载文件系统,保存退出后编译内核生成uImage镜像文件。

cd  /home/linux
make menuconfig ARCH=arm
General setup --->[]Initial RAM filesystem and RAMdisk(initramfs/initrd) support
File sysytem --->[*]Network filesystem--->[*]root filesystem on NFS
make uImage ARCH=arm CROSS_COMPILE=arm-linux-

设置开发板的启动参数
1.root=/dev/nfs:并非真的设备,而是一个告诉内核经由网络取得根文件系统的旗标
2.nfsroot 参数nfsroot这个参数告诉内核以哪一台机器,哪个目录以及哪个网络文件系统选项作为根文件系统使用,命令格式: nfsroot=[:]–指定网络文件系统服务端的互联网地址(IPaddress)。如果没有给定此栏位,则使用由nfsaddrs变量(见下面)所决定的值。此参数的用途之一是允许使用不同机器作为反向地址解析协议(RARP)及网络文件系统服务端。通常你可以不管它(设为空白)。 2)–服务端上要作为根挂入的目录名称。如果字串中有个‘%s’符记(token),此符记将代换为客户端互联网地址之ASCII表示法。
3.nfsaddrs 命令格式nfsaddrs=::::::
1)–客户端的名称。如果空白,则使用客户端互联网地址之ASCII-标记法,或由启动协议接收的值;2)–要使用的网络设备名称。如果为空白,所有设备都会用来发出反向地址解析请求,启动协议请求由最先找到的设备发出。网络文件系统使用接收到反向地址解析协议或启动协议回应的设备。如果你只有一个设备那你可以不管它。
3)–用以作为自动配置的方法。如果是rarp或是bootp则使用所指示的协议;如果此值为`both’或空白,若配置核心时有打开这两种协议则都使用;none表示不使用自动配置,这种情况下你必须指定前述栏位中所有必要的值。 此参数可以作为nfsaddrs的参数单独使用(前面没有任何字符),这种情况下会使用自动配置。然而,此种情况不能使用none作为值。

setenv bootargs noinitrd console=ttySAC0,115200 init=/init 
root=/dev/nfs rw nfsroot=192.168.199.115:/home/rootfs ip=192.168.199.120:192.168.199.115:192.168.199.1:255.255.255.0::eth0:off
saveenv

2.2.1搭建NFS服务器

想要让内核通过网络挂载文件系统,就需要搭建NFS服务器。NFS服务器软件的安装方式和上面的tftp服务器的方式一致,这里就不再赘述。

yum list | grep nfs
yum install nfs-utils

2.2.2启动NFS服务

NFS 依赖 rpcbind 服务,设置为其自动启动
由于nfs服务依赖于rpc(远程过程调用)服务,所以在启动nfs服务之前,需要先启动rpc服务

chkconfig rpcbind on
service rpcbind start
service nfs start
tail /var/log/message
chkconfig nfs on

2.2.3配置NFS服务器

配置文件的意思是指定共享目录,也就是说我们将虚拟机中的根文件系统通过网络共享给开发板的linux内核使用。*代表所有IP都可以访问这个目录,权限包括可读可写,保存到磁盘等。配置完要重启NFS服务器生效。

vim /etc/exports
/home/rootfs *(rw,sync,no_root_squash)

/etc/init.d/nfs restart

下载内核后使用bootm命令启动内核,内核启动后便会通过网络来挂载根文件系统

tftp c0008000 uImage;bootm c0008000

最后附上整个过程的思维导图

Linux根文件系统制作与各种挂载方式的实现

暂时就先这样了,以后再把学习笔记和遇到的问题都慢慢搬移上来。