摘要:虽然经常安装操作系统,但你有没有想过,操作系统安装的时候都做了哪些工作?系统安装的本质是什么?在操作系统安装之前,系统是怎么从裸机上起来的?等等问题。本文主要以Centos系列的linux为例,向你详细解释操作系统安装的详细过程,引导程序,系统内核,livecd,installer等的区别和联系。本文主要为你解答这些问题


1.发行版本中包含的文件

首先,我们来看一下一个传统的发行版本linux中会包含哪些文件(一个linux发行版CD,本文是centos):

[huangyk@huangyk CentosInstall]$ ls
CentOS_BuildTag  EULA  images    Packages                  repodata              RPM-GPG-KEY-CentOS-Debug-6     RPM-GPG-KEY-CentOS-Testing-6
EFI              GPL   isolinux  RELEASE-NOTES-en-US.html  RPM-GPG-KEY-CentOS-6  RPM-GPG-KEY-CentOS-Security-6  TRANS.TBL

大部分都是与需要安装的软件包有关的信息,其中,在安装过程中起关键作用的主要有两个目录:images和isolinux,我们来看一下这两个目录中的内容:

isolinux目录的内容:

-r--r--r--. 1 root root     2048 7月   6 2012 boot.cat
-r--r--r--. 2 root root       84 7月   6 2012 boot.msg
-r--r--r--. 2 root root      334 7月   6 2012 grub.conf
-r--r--r--. 4 root root 31596586 7月   6 2012 initrd.img
-r--r--r--. 2 root root    24576 7月   6 2012 isolinux.bin
-r--r--r--. 2 root root      936 7月   6 2012 isolinux.cfg
-r--r--r--. 2 root root   165080 7月   6 2012 memtest
-r--r--r--. 2 root root   151230 7月   6 2012 splash.jpg
-r--r--r--. 1 root root     2215 7月   6 2012 TRANS.TBL
-r--r--r--. 2 root root   162860 7月   6 2012 vesamenu.c32
-r-xr-xr-x. 4 root root  3986608 7月   6 2012 vmlinuz
其中,isolinux.bin引导程序,负责将操作系统内核加载到内存,isolinux.cfg是isolinux.bin将会读取的配置文件

grub.conf是grub读取的配置文件,grub也是引导程序

mmtest和vmlinuz等是可以启动的系统内核,initrd.img是初始化所用的磁盘镜像,里面包含一个最小化的系统,包含了/dev,/etc,/bin等很多基本的目录,还有关键的init程序,负责驱动的加载和文件系统的初始化。

images目录的内容:

-r--r--r--. 2 root root    372736 7月   6 2012 efiboot.img
-r--r--r--. 2 root root  35997696 7月   6 2012 efidisk.img
-r--r--r--. 2 root root 136585216 7月   6 2012 install.img
dr-xr-xr-x. 2 root root      2048 7月   6 2012 pxeboot
-r--r--r--. 1 root root       888 7月   6 2012 TRANS.TBL
其中,最重要的是引导第二阶段安装需要用到的镜像文件install.img(rhel 5中是stage2.img),anaconda程序就在这个镜像文件中。

另外,如果想详细的了解安装文件中每个文件的作用,可以参考这里:http://blog.csdn.net/trochiluses/article/details/11774165


2.install.img内容分析


先用file命令查看install.img的文件系统类型,可知是suqashfs,用mount -o loop -t squashfs install.img ./img/的方式挂载出来。内容如下:

etc  firmware  lib  lib64  modules  proc  usr  var
由此可见,这也基本上是文件系统中重要文件的磁盘镜像:

 除了主执行体/usr/bin/anaconda,其它安装脚本模块均在/usr/lib/anaconda主目录下。我们看一下整个anaconda主目录的结构:
    /usr/bin/anaconda: 主程序,是python脚本。 
    /usr/lib/anaconda/installclasses:定义了在安装过程中用户可选择的安装类型。每个安装类型描述文件根据相应安装类型的特点,分别对安装步骤、分区策略以及安装包的取舍给出了不同的方案。里面有两个文件fedora.py和rhel.py,分别针对fedora和rhel的安装类型。其他的Linux发行版可以定义它们自己的安装类型。
    /usr/lib/anaconda/iw:图形安装模式的模块。包含所有图形界面类所在的模块,每个图形界面对应一个类,负责相应安装步骤图形界面的具体外观显示及与用户的交互,(可能)调用anaconda主目录下的相关安装行为模块完成具体的安装操作。
    /usr/lib/anaconda/storage:存储配置的响应目录(如分区,FCOE, iSCSI, RAID, ZFCP的配置等)。 
    /usr/lib/anaconda/textw:文本安装模式的模块。和iw子目录含义是一致的,只是包含的是文本安装模式的前端字符用户界面类所在的模块,每个字符用户界面对应一个类,负责与用户的交互,字符界面的采用了python的snack库。
    /usr/lib/anaconda-runtime: 有init和loader程序。这是两个静态编译的程序,不依赖其他库,就是编译anaconda源代码目录下的loader目录下的C代码得到。这两个程序会放在最后用来启动安装过程的Linux initrd image里面。
    /usr/anaconda主目录:如果说用户界面类是处理安装程序外观的话,则anaconda主目录下的各python模块执行每个安装界面背后具体的安装行为,包括那些无用户界面安装步骤的安装操作。
    由此可见,主执行体/usr/bin/anaconda调用的大量例程分布在/usr/lib/anaconda目录下,安装过程要用到的资源文件(例如背景图片)则分布在/usr/share/anaconda目录下。Python的许多内置模块则在目录/usr/lib/pythonXX下,其中XX指版本号。
    上面分析的是已经编译好的anaconda目录结构,现在概览一下anaconda源代码包的结构。Anaconda主要用Python编写,图形界面前端用pyGtk库(参考http://www.pygtk.org/)和Glade界面描述文件(参考http://glade.gnome.org/)编写。用来启动环境、加载模块、加载anaconda主体的loader程序用C编写,一些其他的硬件相关的部分也是用C编写。另外,bash和python脚本还用在一些管理性的任务中。


3.linux系统安装过程分析:


需要知道,安装程序只是一个普通的用户程序,安装程序在能够运行之前,必须要启动操作系统才行,而这个时候,物理硬盘上尚且没有操作系统。

所以,一个安装光盘里,需要有引导程序(负责将操作系统内核和initrd.img加载到内存),操作系统内核和initrd(负责程序运行环境的构建)。另外,如果是一个安装光盘,那么需要有安装程序;如果是livecd,需要有live磁盘镜像。也就是说,需要有已经安装的操作系统磁盘镜像,这就是img文件。从理论上说,操作系统的安装过程和启动过程在前几步是完全相同的。


系统安装过程如下:

启动操作系统内核——加载initrd.img——运行初始化程序——根据初始化initrd中init程序的内容,决定是启动livecd还是ananconda来运行安装程序;如果是livecd,那么里面如果有installer程序,可以手动开启installer程序来安装操作系统,注意,此时调用ananconda等程序来安装操作系统,是用户行为,不是系统子自发的行为,已经没有操作系统的引导过程了(因为操作系统已经起来了)。


POST加电自检-->BIOS(Boot Sequence)-->加载对应引导上的MBR(bootloader)-->主引导设置加载其BootLoader-->Kernel初始化-->initrd—>/etc/init进程加载/etc/inittab。


由于传统的安装过程是ananconda控制的,而ananconda又会执行kickstart的配置文件,所以,我们有必要来了解一下kickstart的配置文件语法和大体框架:

line1~line6:基本配置:

Line	 
1 	lang en_US.UTF-8
2 	keyboard us
3 	timezone US/Eastern
4 	auth --useshadow --enablemd5
5 	selinux --enforcing
6 	firewall --disabled

line8~11软件源配置:

Line 
8 	repo --name=a-base    --baseurl=http://mirror.centos.org/centos/5/os/$basearch
9 	repo --name=a-updates --baseurl=http://mirror.centos.org/centos/5/updates/$basearch
10 	#repo --name=a-extras  --baseurl=http://mirror.centos.org/centos/5/extras/$basearch
11 	repo --name=a-live    --baseurl=http://www.nanotechnologies.qc.ca/propos/linux/centos-live/$basearch/live

软件包清单:

%packages
syslinux
kernel

@admin-tools
#packages removed from @admin-tools
-sabayon
-system-config-kdump
#@admin-tools <end of package list>


@base
#package added to @base
squashfs-tools
#packages removed from @base
-amtu
-bind-utils

注意,其中admin-tools是一些列软件,“减号”表示在在一些列软件里需要除去什么软件。

【安装后需要执行的shell脚本】

241 %post
242 
243 #!/bin/bash
244 #
245 
246 # FIXME: it'd be better to get this installed from a package
247 cat > /etc/rc.d/init.d/centos-live << EOF_initscript
248 #!/bin/bash
249 #
250 # live: Init script for live image
251 #
252 # chkconfig: 345 00 99
253 # description: Init script for live image.
254 
255 . /etc/init.d/functions

注明: 你可以在/root/post-install找到该脚本. 这个脚本执行后的日志放在/root/post-install.log.当你从livecd启动之后,你能够重新审视这些脚本文件。


4.关于系统引导的疑问:

我们
4.1关于kernel,也就是vmlinuz:

kernel初始化所要工作的内容做下简单总结:  

       探测硬件->加载驱动(在initrd之中)->挂载根文件系统(initrd镜像中的init脚本完成)->rootfs(/sbin/init) 

vmlinux是很小的,仅仅包含一些最基本的东西,不包含驱动程序,大概只有4M

驱动程序在initrd之中,我们也可以把驱动坐在vmlinuz中,但是由于存放vmlinuz的设备多种多样,所以需要编入内核的驱动也有很多,会造成内核臃肿,所以产生了initrd文件,引导程序初始化ramdisk,解决驱动多样问题。


4.2initrd与initramfs有什么去别?


ramfs是一种非常简单的文件系统,它直接利用linux内核已有的高速缓存机制(所以其实现代码很小,也由于这个原因,ramfs特性不能通过内核配置参数屏蔽,它是内核的天然属性),使用系统的物理内存,做成一个大小可以动态变化的的基于内存的文件系统。大小大概是16M


在早期的linux系统中,一般只有硬盘或者软盘被用来作为linux根文件系统的存储设备,因此也就很容易把这些设备的驱动程序集成到内核中。但是现在的嵌入式系统中可能将根文件系统保存到各种存储设备上,包括scsi、sata,u-disk等等。因此把这些设备的驱动代码全部编译到内核中显然就不是很方便。大小大概是4M


4.3安装程序中,images目录下的各种磁盘镜像文件是如何挂载的?

尚未解决



Logo

更多推荐