“文件系统”与“根文件系统”详解
要不我们就统一简称为FS和RFS:
文件系统:File System => FS;
根文件系统:Root File System => RFS。
首先你考虑一点描述语句:根文件系统也是一种“文件系统”,可以认为是一种“特殊的”“文件系统”,为什么是叫“特殊的”呢?因为这种“根文件系统”承载着某些“特殊的功能”(其实“文件系统”相同的话,所具备的功能都是一样的),那就是“操作系统”可能需要通过某种“布局”来管理相关设备的,诸如软盘设备、硬盘设备、虚拟磁盘设备等等,这里可能就是用了一种已被定义好了“数据结构”的“布局”,即“文件系统”,而出现的“根文件系统”,可能是用来担当主要或重要角色。
形象点来说,Windows下的C盘分区是有一定文件系统的,如FAT32、NTFS,这当然也都是文件系统呀。在安装Windows操作系统时,会要求你先“格式化”C盘[当然我们目前考虑操作系统是被安装在C盘中],采用一种“文件系统”比如NTFS、FAT32等,这一步呀,就类似于安装“根文件系统”,也就是说在C盘中的NTFS文件系统会被称作是“根文件系统”,而在D盘等中的NTFS文件系统会被称作是“文件系统”或你想加上前缀名称也不是不可以,比如“普通文件系统”,而我们从名称上来说的话,因为这里出现了一个字眼“根”,所以我们就有两种名称的叫法了,自然就是FS与RFS,所以这种名称叫法就会让人感觉很是“云里雾里”,而后“不知所云”的],这个“格式化”过程就是将C盘上的存储空间按预先定义好的一种FS的“数据结构”去“初始化”这些磁盘,[这里假设MINIX
FS也可被Windows用来“格式化”C盘呀]比如建立引导块、建立超级块、建立两类位图块、建立i节点位图块、建立好数据区块等)也就是说,这个磁盘分区必须已经按一定数据结构的方式把磁盘空间“组织”好,以便“某种系统”(OS或FS,好象是FS更准确吧)能“访问”该分区,所以在
0.11内核中会有两种区分:mount_root() 和
sys_mount(),分别指“挂载根文件系统”、“挂载文件系统”[这里我觉得不应该用一个词:安装!我所理解的意思是,“安装”就是指把某种东西
“放”到另一种东西上面去,比如你要安装某种软件到C盘,这种软件的安装程序可能在D盘,这时你会启动D盘上该软件的安装程序,然后安装程序就会把软件默认安装到C盘上,所以这个过程会叫做“安装”,安装前C盘上没有该软件的任何信息,安装后C盘上就会有该软件的信息啦],所以呢,要使用
sys_mount()功能,某种设备(具体来说就是某一分区)必须已经被某种FS的格式“安装”好,然后该设备才会被“挂载”(mount)到“一个地
方”去。
那我们就以MINIX FS和FAT FS来分析吧。
在0.11内核代码中,从mount_root(void)中的注释可知,该函数会被“系统调用函数”sys_setup()调用,而在系统开机初始化设置时函数sys_setup()会被调用。为什么不会调用sys_mount()呢?那我们又何时使用sys_mount()函数呢?其实
sys_mount()函数也是“系统调用函数”。我们在linux系统中,当你在某个shell的命令行中输入mount后回车,你会看到以下提示信
息:
mount: usage: mount dev dir
你大概应该清楚了,而这是“正确的提示信息”,因为我们用错mount用法了(另外,在/bin目录下,可以看到有mount这样一个文件,mount应
该就是一个单独的程序了吧:-),好多地方都说mount是shell内部命令,而我更可能会认为cd才是shell的内部命令之一)。
那我们从sys_mount()函数的注释中可以知道,该函数是“安装文件系统调用函数”(我个人觉得这句话不太好理解),而我知道函数的功能,所以我会这么理解:这个函数是一“系统调用函数”,其功能是“将一个‘文件系统’即FS‘挂载’到(现有‘根文件系统’即RFS的)一个“目录”上,即目录文件的i节点。所以呢,这个就与“mount dev
dir”这样的提示信息对应起来了;另外,我们需要知道,dev表示的是某个设备上的一个分区,而dir表示的是某一个“现有的”文件系统中的“目录文件”,注意一定是“现有的”,在这里就是我们说的“根文件系统”,所以,你要使用mount功能,就得有以下条件:
1、在一个现有“文件系统”(根文件系统RFS)下面
2、该RFS中已经有了一些设备文件的存在,比如 /dev 下面的 hd0,hd1,等等
3、2中的/dev其实就是由RFS来管理的
4、还需要有一个目录存在,而该目录也是在该RFS中的即由RFS来管理的
5、当然你要有实际的磁盘设备存在(/dev/hd0只是表示一个“虚”的设备文件名而已)且该设备已被“FS”格式化好了
6、最后你就会用mount dev dir这样的方式,将实际的磁盘分区“挂载”到dir中
假如,你有一个硬盘(假设大小是512MB),就只是一个分区,该分区中的FS是 FAT FS(假设unix可以直接访问,大不了看成是与minix fs是一样的,只是名称不同而已,以下就是把它看成就是一个minix fs来分析的)。
所以当你启动了“0.11系统”(这个说法比较简化,意思就是你进入了sh命令行)后,其实RFS就已经被“自动”“挂载”好了(就是
mount_root()),这时,你需要在该“0.11系统”中访问那个硬盘,假设硬件上你已经安装好了硬盘了,然后你会在sh命令行中进行“安装”过
程了,假如是:
mount /dev/hd0 /mnt/fatc
即将第一个硬盘的第一个分区(目前只有一个分区)“挂载”到“RFS”中的根目录下的mnt目录中的fatc目录上。所以,你可以直接“进入”到 fatc 目录中去访问该硬盘里的文件了。
成功了!挂载成功,大功告成!
因为你了解内核代码,所以你应该知道mount一系列过程的,你要知道以下几点:
1、/dev/hd0, /mnt/fatc都是RFS中的“文件”(统称),前者是设备文件,后者是目录文件。
[体现在i节点结构中,就是各自的inode->i_mode中会区分是“设备类型文件”还是“目录类型文件”,且前者的
inode->zone[0]存有该设备的设备号(还有inode->i_dev也是设备号,但实际含义不一样),后者的
inode->i_mount就被置位啦,注意因为这个i节点就是一个“被‘安装’/‘挂载’好了FS的i节点]
2、/ 这是目录,但这个是RFS的目录,且是根目录。
3、/mnt/fatc “相当于”就是那个硬盘分区中FS的根目录。但其实该硬盘中的根目录也是/。
[假设当你去访问那个分区“根”目录(其实也是/,但你能直接进去吗?)中的某个文件hello.c,时,你会在现有sh命令行中,cd
/mnt/fatc回车后 ls hello*
-l,然后你会发现有hello.c这个文件,其实你就应该需要知道RFS是怎么“定位”寻找到该hello.c文件的,当中有一个重要的过程就是需要取
每一个文件的inode信息即iget()函数,该函数中发现某文件的inode->i_mount被置位时,就“特别小心”了,为什么?因为该
inode表示被“挂载”了一个文件系统,所以RFS会“切换”到那个FS的根目录中去(使用了ROOT_INO,super_block.s_dev这样的参数),然后再在该FS中按正常的过程继续寻找所需要的文件,所以你能找到]
“正常的过程”就是指:要么从一个FS的根目录中开始查找文件,要不从一个文件系统当前用户进程的当前工作目录中开始查找文件。
所以就有一个重要的说法(我是这么理解的):跨文件系统访问文件。这一过程涉及面较广,主要数据结构有:i节点、超级块。
4、最后,当你不需要使用该分区或是你想把硬盘拿走,则你会使用 umount 功能啦,这就对应 sys_umount()这一“系统调用函数”,那你就要知道该函数做了些什么事了。
最后,总的来说:
mount_root()挂载了一个MINI FS又被称为是RFS。
然后你可以在该RFS中再挂载别的FS。RFS与系统“共存亡”,自动被“挂载”,自动被“卸载”。
所以,FAT等也可以是根文件系统,当然也是文件系统。
所以,当你在你电脑上安装了多操作系统时,假设在C盘(FAT32 FS)被装了 win98,在D盘(NTFS
FS)被安装了winxp,那么,当你进入了win98时,你FAT32好象就是RFS,那么NTFS就是FS了;当你进入了winxp时,NTFS好象就是RFS,那么FAT32就是FS了。
(为什么C盘是要FAT32呢,因为win98不支持ntfs fs,而你又是装的win98)
希望你能对RFS与FS有所了解。
转自:http://www.oldlinux.org/oldlinux/viewthread.php?tid=10875