很多人都有安装Linux的经历,无非就是插张光盘或者USB到主机上,然后按照提示一步一步进行配置,完了重启一遍,OK。但是这个过程中,系统到底做了些什么事情呢?下面就简单地来说一说。
普通的光盘是基于ISO-9660的标准发展起来的,在光盘上数据被组织为帧和扇区,一个扇区包含98帧,共2352字节,一个700M的CD大概包含了360000个扇区。在大约1994~1995年的时候,凤凰科技(Phoenix Technologies)和IBM的两个牛人(Curtis Stevens和Stan Merkin)在一个墨西哥餐厅边吃午饭边商量可启动盘(Bootable Disk)的规范,商量完后,两人根据餐馆的名字将可启动盘的规范命名为”El Torito“。这个规范实际上对ISO-9660进行了扩展,规范中定义了可启动光盘的数据结构与映像数据的配置及光盘制作的一些详细说明,同时也隐含地制定了能够读取可启动光盘的BIOS规范。1996年COMPAQ、Phoenix与Intel联合发布的BIOS启动规范(BIOS Boot Specification)1.01,该规范为BIOS厂家提供了制造支持可启动光盘的BIOS的标准。
可启动盘跟普通的数据盘到底有什么区别呢?为什么将它插到电脑上就能够引导系统呢?
根据标准,BIOS会在开机时将检查光盘的第17个扇区(sector 17),查找其中的代码,若找到启动记录卷描述表(Boot Record Volume Descripter),它就根据表中的地址继续查找启动目录(Booting Catalog),找到启动目录后 ,再根据其中描述的启动入口(Boot Entry)找到相应的启动盘映像(Bootable Disk Image)或启动引导文件,找到启动盘映像后,读取其中的数据,并执行相应的开机动作。
启动盘映像多很多种,如SYSLINUX、ISOLINUX、PXELINUX、EXTLINUX等,其中PXELINUX用于网络安装,EXTLINUX用于从ext2/ext3/ext4/btrfs文件系统启动。而启动光盘会使用到剩下的两种映像:SYSLINUX和ISOLINUX。
在上面我们提到了自启动光盘的规范”El Torito“,它支持两种启动模式:模拟模式和非模拟模式。
模拟模式将启动信息保存在一个1.44M的FAT格式的映像文件中,就如同将一张1.44M的软盘”镶嵌“到一张光盘中,系统从光盘中加载这个映像文件,然后跟使用软盘一样启动系统。因为受空间限制,这种模式不能用于启动完整的Linux操作系统,通常只用来做Rescue盘、Live USB或者其他轻量级的启动系统。模拟模式使用的映像就是SYSLINUX,但这种方式一般只用于1999年以前的电脑。
非模拟模式直接将启动信息保存在光盘上,而不是一个模拟的映像文件上,这时用的就是ISOLINUX。从3.72版本开始,ISOLINUX支持”hybrid mode“模式,能够在ISO映像中放一个启动程序,支持使用同一个映像文件从光盘或者USB启动。现在大部分情况我们用的都是这种方式。
ISOLINUX目录中一般包含下列文件
名称 | 说明 |
---|---|
isolinux.bin | 非模拟模式的启动引导程序。当使用mkisofs命令时,-b参数要指向这个文件 |
vmlinuz | 压缩的内核,引导系统安装。”VM“表示”Virtual Memory“ |
initrd.img | 内存映像文件(initial ramdisk)。解压后可以看出一个简洁的Linux根文件系统 |
isolinux.cfg | ISOLINUX的配置文件 |
boot.cat | 启动目录(booting catalog)文件,保存了所有可用的启动映像 |
*.msg | 一些命令用到的文本文件,比如启动界面的提示信息 |
*.lss | ISOLINUX的图像化启动界面 |
首先说一下配置文件。isolinux.cfg是一个纯文本文件,里面大概像下面这个样子:
default local
prompt 1
timeout 600
display boot.msg
label linux
kernel vmlinuz
append initrd=initrd.img
label rescue
kernel vmlinuz
append initrd=initrd.img rescue
label local
localboot 0xFF
label reinstall
kernel vmlinuz
append ks=hd:sdb1:/ks.cfg method=hd:sdb1:/ initrd=initrd.img ramdisk_size=8192 console=ttyS0,9600 headless cmdline
文件头部可以认为是一些全局设置,default表示超时后系统的默认启动项,prompt为1时表示始终显示启动提示信息,否则需要按某些键才会显示,timeout以0.1秒为单位,等待用户输入的超时时间。
文件后面以label开头的段落就是具体的启动项及参数配置。比如用户输入linux,那表示将用vmlinz为内核,带着参数initrd=initrd.img来启动系统;localboot 0x80表示如果用户输入local,则系统将从第一块硬盘的第一个分区启动,可选参数包括:
- 0x80 - 第一块硬盘的第一个分区 (C: in DOS)
- 0x81 - 第一块硬盘的第二个分区(D: in DOS)
- 0x00 - 一个软盘驱动器 (A: in DOS)
- ....
- 0xFF - 从BIOS中列举的下一个设备启动
再说一下initrd.img。initrd.img是一个使用gzip压缩的ext2格式的文件系统映像,它包含了Linux的根目录,解压后能够看到下面的目录结构:
bin dev etc firmware init lib lib64 modules proc sbin selinux sys tmp usr var
它一般被用来临时地引导硬件到实际内核能够接管并继续引导的状态,主要是用于加载ext3等文件系统及 SCSI 设备的驱动。比如,使用SCSI硬盘,而内核中并没有相关驱动,那么在装入SCSI模块之前,内核不能加载根文件系统,这时就可以从initrd的/lib/modules下加载驱动程序来读取硬盘数据。
将上面1~4节的内容汇总一下,可以大概得到Linux从光盘或USB安装过程第一阶段的内幕:
Step1. 电源上电后,BIOS根据设置的启动顺序从第一个设备开始启动,假设第一个设备已经被设置为光盘或者USB,启动程序执行/isolinux路径下的isolinux.bin,这个程序读取isolinux.cfg,在启动屏幕上显示所有的启动项。
Step2. 用户选择某个启动项(假设为reinstall)后,引导程序根据参数继续引导过程,加载内核映像vmlinuz和初始RAM磁盘initrd.img,在内存中构建了一个Linux启动所需的虚拟的根文件系统(rootfs)。
Step3. 内核执行initrd.img中的/init程序(这实际上是一个指向/sbin/init的软链接)。init会调用/sbin/loader程序,执行anaconda主程序。
至此,安装引导的第一个阶段结束,这个阶段的主要任务就是找到第二个阶段的引导程序并执行它。
安装的第二个阶段实际上就是anaconda的执行过程,非交互式安装建议直接参考ks.cfg的手册来理解,本文不再赘述,只简单介绍一下安装盘上相关文件和目录。
安装盘顶层目录除了前面提到的isolinux,还有几个主要的目录,如images、Packages、repodata,另外还有几个文件,如ks.cfg、.discinfo和.treeinfo。
文件或目录名 | 说明 |
---|---|
.discinfo | 安装盘识别信息,执行/usr/lib/anaconda-runtime/buildinstall时生成 |
.treeinfo | 记录不同安装方式安装程序所在的目录结构 |
ks.cfg | kickstart文件,非交互式安装的配置文件,包括系统账户、分区以及安装哪些rpm包等都在里面定义 |
images |
|
Packages | 包含所有的二进制RPM包 |
repodata | 包含RPM包的描述文件,如依赖关系,包含文件,校验码信息。有四个必要文件:filelists.xml.[gz],other.xml.[gz],primary.xml.[gz]和repomd.xml |
以上都是自己的一些理解,如果理解有错,希望不吝指出,谢谢。
Linux安装程序Anaconda分析 --- http://blog.csdn.net/zhoudaxia/article/details/7172020
使用isolinux制作liveUSB --- http://blog.csdn.net/trochiluses/article/details/17585525
Anaconda/Stage1DevelopmentGuide --- https://fedoraproject.org/wiki/Archive:Anaconda/Stage1DevelopmentGuide?rd=Anaconda/Stage1DevelopmentGuide
Anaconda/Kickstart --- https://fedoraproject.org/wiki/Anaconda/Kickstart
感谢wikipedia,syslinux.org以及google.com