Linux boot的五个阶段
/* @author = s1n */
/* @文中首次出现的概念都会使用黑体加粗*/
1.BIOS
电源开启后,bios开始执行上电自检(POST:Power-On-Self-Test),而后按照boot sequence加载在软盘,cd-rom,硬盘,闪存等中的MBR(Master Boot Record),寻找bootloader,找到后加载到内存中,并将控制权移交给bootloader。MBR是一个大小仅有512字节的扇区,位于磁盘的第一个扇区其中bootloader的大小为446字节。 boot loader 可以具有菜单功能、直接加载核心文件以及控制权移交的功能等。
linux中将bootloader程序代码的配置和运行的过程分为两个阶段:
2.MBR与GRUB/LILO
/*GRUB和LILO都是引导加载程序,主要用于引导操作系统的启动。 */
/*在单一的MBR中只能存储一个操作系统的引导记录,所以当需要多个操作系统时,就会出现问题,需要更灵活的引导加载程序。*/
/*GRUB和LILO的区别: */
/* 1).GRUB拥有交互式命令界面; */
/* 2).GRUB支持网络引导; */
/* 3).LILO可以引导操作系统位置的信息存储在MBR中; */
1).运行bootloader主程序:
第一阶段为运行bootloader的主程序,这个主程序必须要被安装在启动区,即是MBR或者是boot sector 。但如前所述,因为MBR实在太小了,所以,MBR或boot sector通常仅安装bootloader的最小主程序, 并没有安装bootloader的相关配置档;
2).主程序加载配置文件:
第二阶段为透过 boot loader 加载所有配置档与相关的环境参数文件 (包括文件系统定义与主要配置档 menu.lst或grub.lst), 一般来说,配置档都在/boot/grub中。
1 [root@www ~]# ls -l /boot/grub 2 -rw-r--r-- device.map <==grub 的装置对应档(底下会谈到) 3 -rw-r--r-- e2fs_stage1_5 <==ext2/ext3 文件系统之定义档 4 -rw-r--r-- fat_stage1_5 <==FAT 文件系统之定义档 5 -rw-r--r-- ffs_stage1_5 <==FFS 文件系统之定义档 6 -rw------- grub.conf <==grub 在 Red Hat 的配置档 7 -rw-r--r-- iso9660_stage1_5 <==光驱文件系统定义档 8 -rw-r--r-- jfs_stage1_5 <==jfs 文件系统定义档 9 lrwxrwxrwx menu.lst -> ./grub.conf <==其实 menu.lst 才是配置档! 10 -rw-r--r-- minix_stage1_5 <==minix 文件系统定义档 11 -rw-r--r-- reiserfs_stage1_5 <==reiserfs 文件系统定义档 12 -rw-r--r-- splash.xpm.gz <==启动时在 grub 底下的背景图示 13 -rw-r--r-- stage1 <==stage 1 的相关说明 14 -rw-r--r-- stage2 <==stage 2 的相关说明 15 -rw-r--r-- ufs2_stage1_5 <==UFS 的文件系统定义档 16 -rw-r--r-- vstafs_stage1_5 <==vstafs 文件系统定义档 17 -rw-r--r-- xfs_stage1_5 <==xfs 文件系统定义档
/*关于grub的更进一步会在以后的笔记中详细的解释*/
总结一下,每个磁盘的第一个扇区为磁盘的MBR,MBR中前446字节记录的是boot loader,bootloader中安装的是grub的stage1,用于指向grub主程序咋磁盘中的位置。开机加电之后,BIOS按照boot sequence找到对应磁盘,然后搜索该磁盘的MBR。找到位于基本磁盘分区的grub程序,即进入stage2阶段,按照grub.conf配置文件对kernel以及initrd进行引导加载。当MBR被加载到RAM中之后,BIOS就会将控制权交给MBR。
接下来我们将mbr拷贝下来,看看其中的内容:
首先使用如下命令拷贝硬盘一块扇区的前512字节的内容。
# dd if=/dev/sda of=/tmp/mbr.bin bs=512 count=1
正确结果应得到如下输出
1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.0006952 s, 736 kB/s
使用file命令,查看mbr中的内容,可以利用tr命令将“;“均换为”\n”增加可读性
# file /tmp/mbr.bin | tr ';' '\n'
得到输出:
1 /tmp/mbr.bin: x86 boot sector 2 GRand Unified Bootloader, stage1 version 0x3, stage2 address 0x2000, stage2 segment 0x200 3 partition 1: ID=0x83, starthead 32, startsector 2048, 3906250 sectors 4 partition 2: ID=0x83, starthead 71, startsector 3908298, 78125000 sectors 5 partition 3: ID=0x83, starthead 85, startsector 82033298, 418084894 sectors, code offset 0x48
/*关于MBR内容的解释会在以后的笔记中详细的解释*/
3.加载内核(Kernel)
加载内核映像到内存中,内核映像并不是一个可执行的内核,而是一个可压缩的内核映像。所有内核将有一个自解压过程。在这个内核映像前面是一个例程,它实现少量硬件设置,并对内核映像中包含的内核进行解压缩,然后将其放入高端内存中。如果有初始化RAM磁盘映像,系统就会将它移动到内存中,并标明以后使用,然后到该例程会调用内核,并开始启动内核引导的过程。此时它会调用start_kernel()函数,进一步初始化设备。
系统的根文件在grub.conf中由”root=“所定义,我的虚拟机中的值为:
set root = ‘hd0,msdos1'
4.执行init
该程序会读取/etc/inittab文件然后决定系统运行的级别,列举如下
- 0 – halt
- 1 – Single user mode
- 2 – Multiuser, without NFS
- 3 – Full multiuser mode
- 4 – unused
- 5 – X11
- 6 – reboot
/*运行级别解释*/
/*运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动 */
/*运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆 */
/*运行级别2:多用户状态(没有NFS) */
/*运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式 */
/*运行级别4:系统未使用,保留 */
/*运行级别5:X11控制台,登陆后进入图形GUI模式 */
/*运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动 */
使用runlevel指令即可查看当前的运行级别
init进程是系统所有进程的起点,是所有进程的发起者和控制者。因为在任何基于Linux的操作系统中,它都是第一个运行的进程,所以,init进程的进程编号(PID)永远是1.内核在完成核内引导以后,即在本进程空间内加载init程序,它的进程号是1,主要用来执行一些开机初始化脚本和监视进程。如:init读取系统引导配置文件/etc/inittab中的信息进行初始化。所以他是一切进程的父进程,并且用它来杀死其他的进程。
5.最终配置
进一步根据系统运行时的级别,系统将运行不同级别的程序,例举如下
- Run level 0 – /etc/rc.d/rc0.d/
- Run level 1 – /etc/rc.d/rc1.d/
- Run level 2 – /etc/rc.d/rc2.d/
- Run level 3 – /etc/rc.d/rc3.d/
- Run level 4 – /etc/rc.d/rc4.d/
- Run level 5 – /etc/rc.d/rc5.d/
- Run level 6 – /etc/rc.d/rc6.d/
以redhat为例,其执行过程为
/etc/rc.d/rc.sysinit # 由init执行的第一个脚本 /etc/rc.d/rc $RUNLEVEL # $RUNLEVEL为缺省的运行模式 /etc/rc.d/rc.local /sbin/mingetty # 等待用户登录
rcN.d目录下都是一些符号链接文件,这些链接文件都指向init.d目录下的service脚本文件,命名规则为K+nn+服务名或S+nn+服务名,其中nn为两位数字。
系统会根据指定的运行级别进入对应的rcN.d目录,并按照文件名顺序检索目录下的链接文件
1).对于以K开头的文件,系统将终止对应的服务
2).对于以S开头的文件,系统将启动对应的服务
/*the end*/
/*接下来的5篇笔记将会对每个过程展开更加深入的讨论*/