内容源于: 鸟哥的linux私房菜
链接如下:
启动流程与主要启动记录区(MBR)
CMOS 与 BIOS
- CMOS是记录各项硬件参数且嵌入在主板上面的储存器
- BIOS则是一个写入到主板上的一个韧体(再次说明, 韧体就是写入到硬件上的一个软件程序).这个BIOS就是在启动的时候,计算机系统会主动运行的第一个程序了!
整个启动流程到操作系统之前的动作应该是这样的:
- BIOS:启动主动运行的韧体,会认识第一个可启动的装置(即存储设备,如硬盘,光盘等等);
- MBR:第一个可启动装置的第一个磁区内的主要启动记录区块,内含启动管理程序;
- 启动管理程序(boot loader):一支可读取核心文件来运行的软件;
- 核心文件:开始操作系统的功能...
由上面的说明我们会知道,BIOS与MBR都是硬件本身会支持的功能,至於Boot loader则是操作系统安装在MBR上面的一套软件了.由於MBR仅有446 bytes而已,因此这个启动管理程序是非常小而美的. 这个boot loader的主要任务有底下这些项目:
- 提供菜单:使用者可以选择不同的启动项目,这也是多重启动的重要功能!
- 加载核心文件:直接指向可启动的程序区段来开始操作系统;
- 转交其他loader:将启动管理功能转交给其他loader负责.
并且启动管理程序除了可以安装在MBR之外, 还可以安装在每个分割槽的启动磁区(boot sector)
我们举一个例子来说,假设你的个人计算机只有一个硬盘,里面切成四个分割槽,其中第一、二分割槽分别安装了Windows及Linux, 你要如何在启动的时候选择用Windows还是Linux启动呢?假设MBR内安装的是可同时认识Windows/Linux操作系统的启动管理程序, 那么整个流程可以图示如下:
在上图中我们可以发现,MBR的启动管理程序提供两个菜单,菜单一(M1)可以直接加载Windows的核心文件来启动; 菜单二(M2)则是将启动管理工作交给第二个分割槽的启动磁区(boot sector).当使用者在启动的时候选择菜单二时, 那么整个启动管理工作就会交给第二分割槽的启动管理程序了. 当第二个启动管理程序启动后,该启动管理程序内(上图中)仅有一个启动菜单,因此就能够使用Linux的核心文件来启动罗. 这就是多重启动的工作情况啦!我们将上图作个总结:
- 每个分割槽都拥有自己的启动磁区(boot sector)
- 图中的系统槽为第一及第二分割槽,
- 实际可启动的核心文件是放置到各分割槽内的!
- loader只会认识自己的系统槽内的可启动核心文件,以及其他loader而已;
- loader可直接指向或者是间接将管理权转交给另一个管理程序.
那现在请你想一想,为什么人家常常说:『如果要安装多重启动, 最好先安装Windows再安装Linux』呢?这是因为:
- Linux在安装的时候,你可以选择将启动管理程序安装在MBR或各别分割槽的启动磁区, 而且Linux的loader可以手动配置菜单(就是上图的M1, M2...),所以你可以在Linux的boot loader里面加入Windows启动的选项;
- Windows在安装的时候,他的安装程序会主动的覆盖掉MBR以及自己所在分割槽的启动磁区,你没有选择的机会, 而且他没有让我们自己选择菜单的功能.
因此,如果先安装Linux再安装Windows的话,那MBR的启动管理程序就只会有Windows的项目,而不会有Linux的项目 (因为原本在MBR内的Linux的启动管理程序就会被覆盖掉). 那需要重新安装Linux一次吗?当然不需要,你只要用尽各种方法来处理MBR的内容即可. 例如利用全中文的spfdisk(http://spfdisk.sourceforge.net/)软件来安装认识Windows/Linux的管理程序, 也能够利用Linux的救援模式来挽救MBR即可.
文件系统
superblock,inode,block
superblock,inode,block数据简略说明:
- superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
- inode:记录文件的权限与属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
- block:实际记录文件的内容,若文件太大时,会占用多个 block .
每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码.所以如果能够找到文件的 inode 的话,那么自然就会知道这个文件所放置数据的 block 号码, 当然也就能够读出该文件的实际数据了.
data block (数据区块)
block 基本限制:
- 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化)
- 每个 block 内最多只能够放置一个文件的数据
- 若文件大于 block 的大小,则一个文件会占用多个 block 数量
- 若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)
- 在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已
Block 大小 1KB 2KB 4KB 最大单一文件限制 16GB 256GB 2TB 最大文件系统总容量 2TB 8TB 16TB inode table (inode 表格)
inode 数据内容:
- 该文件的存取模式(read/write/excute)
- 该文件的拥有者与群组(owner/group)
- 该文件的容量
- 该文件创建或状态改变的时间(ctime)
- 最近一次的读取时间(atime)
- 最近修改的时间(mtime)
- 定义文件特性的旗标(flag),如 SetUID...
- 该文件真正内容的指向 (pointer)
inode 的特色点:
- 每个 inode 大小均固定为 128 bytes
- 每个文件都仅会占用一个 inode 而已
- 承上,因此文件系统能够创建的文件数量与 inode 的数量有关
- 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容
系统将 inode 记录 block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区,如下图所示:
- 12 个直接指向: 12*1K=12K
- 间接: 256*1K=256K
- 双间接: 256*256*1K=2562K=64M
- 三间接: 256*256*256*1K=16777216K=16384M=16G
Superblock (超级区块)
Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了.
记录的信息主要有:
- block 与 inode 的总量
- 未使用与已使用的 inode / block 数量
- block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes)
- filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息
- 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1
block bitmap (区块对照表)
block bitmap 记录使用与未使用的 block 号码,并在进行文件添加修改时候对应的修改 block 的使用状况
inode bitmap (inode 对照表)
inode bitmap 记录使用与未使用的 inode 号码,并在进行文件添加修改时候对应的修改 inode 的使用状况
boot sector 与 superblock 的关系
block 为 1024 bytes (1K) 时:
如果 block 大小刚好是 1024 的话,那么 boot sector 与 superblock 各会占用掉一个 block , 所以整个文件系统图示就会如同图 1.3.1 所显示的那样,boot sector 是独立于 superblock 外面的!
如果 block 大于 1024 的话:
那么 superblock 将会在 0 号,在第一个 block 内 superblock 仅占有 1024-2047 ( 由 0 号起算的话)之间的咚咚,至于 2048bytes 以后的空间就真的是保留啦!而 0-1023 就保留给 boot sector 来使用
索引式文件系统(indexed allocation)
在索引式文件系统(indexed allocation)中将 inode 与 block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而 这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了.
FAT 格式
闪盘使用的文件系统一般为 FAT 格式.FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 block 在一开始就读取出来.每个 block 号码都记录在前一个
block 当中, 他的读取方式有点像底下这样:
上图中我们假设文件的数据依序写入1->7->4->15号这四个 block 号码中, 但这个文件系统没有办法一口气就知道四个 block 的号码,他得要一个一个的将 block 读出后,才会知道下一个
block 在何处. 如果同一个文件数据写入的 block 分散的太过厉害时,则我们的磁盘读取头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的
内容!此时文件读取的效能将会变的很差所致. 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起.
Ext2 文件系统
件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用 resize2fs 等命令变更文件系统大小),否则 inode 与 block 固定后就不再变动
Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统,整个来说,Ext2 格式化后有点像底下这样:
文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动管理程序,如此一来我们就能够将不同的启动管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的
MBR, 这样也才能够制作出多重引导的环境!
目录
在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录.
inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码
block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据.如下图所示:
文件
在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小的 block 数量给该文件
目录树读取
由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 filesystem 的最顶层 inode 号码会由 2 号开始喔!),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block 内的文件名数据,再一层一层的往下读到正确的档名.举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?
[root@www ~]# ll -di / /etc /etc/passwd
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc
1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
在鸟哥的系统上面与 /etc/passwd 有关的目录与文件数据如上表所示,该文件的读取流程为(假设读取者身份为 vbird 这个一般身份使用者):
- / 的 inode:
透过挂载点的信息找到 /dev/hdc2 的 inode 号码为 2 的根目录 inode,且 inode 规范的权限让我们可以读取该 block 的内容(有 r 与 x) ;- / 的 block:
经过上个步骤取得 block 的号码,并找到该内容有 etc/ 目录的 inode 号码 (1912545);- etc/ 的 inode:
读取 1912545 号 inode 得知 vbird 具有 r 与 x 的权限,因此可以读取 etc/ 的 block 内容;- etc/ 的 block:
经过上个步骤取得 block 号码,并找到该内容有 passwd 文件的 inode 号码 (1914888);- passwd 的 inode:
>读取 1914888 号 inode 得知 vbird 具有 r 的权限,因此可以读取 passwd 的 block 内容;- passwd 的 block:
最后将该 block 内容的数据读出来.