• 【转载】Linux系统启动流程


    原文:Linux系统启动流程

    POST(Power On Self Test/上电自检)-->BootLoader(MBR)-->Kernel(硬件探测、加载驱动、挂载根文件系统、/sbin/init)
    -->init(/etc/inittab:设定默认级别、系统初始化脚本、启动及关闭对应级别的服务、启动终端)
    

    第1步

    计算机电源接通后,CPU默认执行 0ffffh:0000h 处的指令(8086是这样,386应该类似),而此内存地址应该存放的就是 BIOS ROM 。系统将有一个对内部各个设备进行检查的过程,这是由一个通常称之为POST(Power On Self Test/上电自检)的程序来完成,这也是BIOS程序的一个功能。完整的自检包括了对CPU、640K基本内存、1M以上的扩展内存、ROM、主板、CMOS存贮器、串并口、显示卡、软硬盘子系统及键盘的测试。在自检过程中若发现问题,系统将给出提示信息或鸣笛警告。

    如果没有任何问题,完成自检后BIOS将按照系统CMOS设置中的启动顺序搜寻软、硬盘驱动器及CDROM、网络服务器等有效的启动驱动器 ,读入操作系统引导记录(BootLoader),然后将系统控制权交给引导记录,由引导记录完成系统的启动。如果一直没有找到可启动的设备,那么本次启动宣告失败。

    第2步

    在上一步中,BIOS找到硬盘的MBR(位于硬盘的0磁道0扇区 大小为512字节,该区域不能被分配给任何分区),然后在MBR中寻找BootLoader(目前比较常用有LILO 和 GRUB,LILO已经不常用,BootLoader在MBR所占446字节,所以必须短小精悍,接下来64字节是分区表信息,最后2字节是用来标明该MBR是否有效),然后把BootLoader加载到内存中开始执行,BootLoader主要功能就是从硬盘找到内核文件,把内核文件加载到内存执行。

    MBR的三部分如下:

    • 第1-446字节:BootLoader。
    • 第447-510字节:分区表(Partition table)。
    • 第511-512字节:主引导记录签名(0x55和0xAA)。

    扩充:

    分区表的长度只有64个字节,里面又分成四项,每项16个字节。所以,一个硬盘最多只能分四个一级分区,又叫做”主分区”。

    每个主分区的16个字节,由6个部分组成:

    • 第1个字节:如果为0x80,就表示该主分区是激活分区,控制权要转交给这个分区。四个主分区里面只能有一个是激活的。
    • 第2-4个字节:主分区第一个扇区的物理位置(柱面、磁头、扇区号等等)。
    • 第5个字节:主分区类型。
    • 第6-8个字节:主分区最后一个扇区的物理位置。
    • 第9-12字节:该主分区第一个扇区的逻辑地址。
    • 第13-16字节:主分区的扇区总数。

    疑问? 内核文件在哪里?GRUB是怎么找到内核文件?

    内核文件(vmlinuz-2.6.18-308.el5)是位于/boot分区下(在我们给硬盘分区的时候都会把/boot单独分区),这时又有疑问了,这时候/都没有被挂载,又如何从硬盘上找到内核文件?

    这时看GRUB的配置文件/boot/grub/grub.conf 可以看到 root (hd0,0),这一行实际上就是指定boot目录所在的位置

    而kernel /vmlinuz-2.6.18-308.el5 ro root=LABEL=/ 这里指定的是内核文件所在的位置,而前面的/并不是真正的根,而是指的是boot目录所在的位置,那么其全路径为(hd0,0)/vmlinuz-2.6.18-308.el5,而这里的(hd0,0)指的是第1个硬盘的第1个分区,GRUB在识别硬盘的时候都是识别为hd开头的。

    总结: GRUB 不是通过文件系统来找内核文件的,因为这时候内核还没有启动所以也不存在什么文件系统,而是直接访问硬盘的第1个硬盘第1个分区(MBR里面存在分区表)的来找到内核文件。

    这时候又有个问题 GRUB是怎么识别分区表中这些分区的文件系统的? 且看/boot/grub目录下的文件:

    [root@server1 grub]# ll
    总计 257
    -rw-r--r-- 1 root root 63 2013-01-05 device.map
    -rw-r--r-- 1 root root 7584 2013-01-05 e2fs_stage1_5
    -rw-r--r-- 1 root root 7456 2013-01-05 fat_stage1_5
    -rw-r--r-- 1 root root 6720 2013-01-05 ffs_stage1_5
    -rw------- 1 root root 562 2013-01-05 grub.conf
    -rw-r--r-- 1 root root 6720 2013-01-05 iso9660_stage1_5
    -rw-r--r-- 1 root root 8192 2013-01-05 jfs_stage1_5
    lrwxrwxrwx 1 root root 11 2013-01-05 menu.lst -> ./grub.conf
    -rw-r--r-- 1 root root 6880 2013-01-05 minix_stage1_5
    -rw-r--r-- 1 root root 9248 2013-01-05 reiserfs_stage1_5
    -rw-r--r-- 1 root root 55808 2009-03-13 splash.xpm.gz
    -rw-r--r-- 1 root root 512 2013-01-05 stage1
    -rw-r--r-- 1 root root 104988 2013-01-05 stage2
    -rw-r--r-- 1 root root 7072 2013-01-05 ufs2_stage1_5
    -rw-r--r-- 1 root root 6272 2013-01-05 vstafs_stage1_5
    -rw-r--r-- 1 root root 8904 2013-01-05 xfs_stage1_5
    

    其实GRUB启动是分阶段的:

    第1个阶段 BIOS加载MBR里面的GRUB(属于第1阶段的文件),由于只有GRUB只占用446字节所以不能实现太多的功能,所以就有此阶段里面的文件来加载第1.5阶段的文件(/boot/grub下的文件)。

    第1.5个阶段 这个阶段里面的就是加载识别文件系统的程序,来识别文件系统,不加载就无法识别文件系统,进而就找不到boot目录,由于GRUB是无法识别LVM,所以你不能把/boot分区设置为LVM,所以必须要把/boot单独分区。

    第2个阶段 这里面才是正在的开始寻找内核的过程,然后是启动内核。

    第3步

    在上一步中,GRUB成功找到内核文件,并把内核加载到内存,同时把/boot/initrd-2.6.18-308.el5.img这个文件也加载进来,这个文件是做什么的呢?

    那么首先看看内核在这一步骤里面做的事情:

    1. 探测硬件
    2. 加载驱动
    3. 挂载根文件系统
    4. 执行第一个程序/sbin/init

    BIOS检查硬件,而内核是会初始化硬件设备,那么首先会探测硬件(第1步),知道是什么硬件了就该加载硬件驱动程序(第2步),不然是没办法指挥着硬件工作的,关键是内核去哪里找驱动程序(驱动程序是硬盘上,是内核模块.ko存在的)而此时根文件系统还没有挂载上,怎么办? 那可以②③对调,先挂载根文件系统,然后再加载驱动,那此时又有问题了,我不加载驱动程序又如何驱动着硬盘工作呢? 这个陷入了是先有蛋还是有先鸡的问题了,这该如何解决?

    这时候 这个文件/boot/initrd-2.6.18-308.el5.img(该文件是一个.gz的压缩文件) 就派上用场了,这个文件也是被GRUB加载内存当中,构建成一个虚拟的根文件系统,这个文件里面包含有硬件驱动程序(),这个文件是可以展开如下操作:

    [root@server1 boot]# cp initrd-2.6.18-308.el5.img ~
    [root@server1 boot]# cd
    [root@server1 ~]# ls
    initrd-2.6.18-308.el5.img
    [root@server1 ~]# mv initrd-2.6.18-308.el5.img initrd-2.6.18-308.el5.img.gz
    [root@server1 ~]# gzip -d initrd-2.6.18-308.el5.img.gz
    [root@server1 ~]# ls
    initrd-2.6.18-308.el5.img
    [root@server1 ~]# file initrd-2.6.18-308.el5.img
    initrd-2.6.18-308.el5.img: ASCII cpio archive (SVR4 with no CRC) 可以看到此时是一个cpio的归档文件
    [root@server1 ~]# mkdir test
    [root@server1 ~]# mv initrd-2.6.18-308.el5.img test
    [root@server1 ~]# cd test
    [root@server1 test]# ls
    initrd-2.6.18-308.el5.img
    [root@server1 test]# cpio -id < initrd-2.6.18-308.el5.img 利用cpio来展开该文件
    12111 blocks
    [root@server1 test]# ls
    bin dev etc init initrd-2.6.18-308.el5.img lib proc sbin sys sysroot
    [root@server1 test]# mv initrd-2.6.18-308.el5.img ../
    [root@server1 test]# ls 可以看到这不就是跟真实的根很像吗
    bin dev etc init lib proc sbin sys sysroot
    [root@server1 test]# ls lib/ 可以看到这目录下包含了ext3.ko的内核模块,该模块就可以驱动着硬盘进行工作了
    ata_piix.ko dm-mod.ko ext3.ko mptbase.ko scsi_mod.ko
    dm-log.ko dm-raid45.ko firmware/ mptscsih.ko scsi_transport_spi.ko
    dm-mem-cache.ko dm-region_hash.ko jbd.ko mptspi.ko sd_mod.ko
    dm-message.ko ehci-hcd.ko libata.ko ohci-hcd.ko uhci-hcd.ko
    [root@server1 test]#
    

    至此内核利用虚拟的根文件系统的ext3.ko内核模块,驱动了硬盘,然后挂载了真正的根文件系统,那么此时虚拟的根文件系统是否还有作用,它还可以挂载/proc文件系统等操作。

    此阶段中最后一个步骤 由内核来启动第一个程序/sbin/init,启动好之后剩下的工作就有init进程来完成了。

    第4步

    init进程首先会读取/etc/inittab文件,根据inittab文件中的内容依次执行

    设定系统运行的默认级别(id:3:initdefault:)

    执行系统初始化脚本文件(si::sysinit:/etc/rc.d/rc.sysinit)

    执行在该运行级别下所启动或关闭对应的服务(l3:3:wait:/etc/rc.d/rc 3)

    启动6个虚拟终端:

    • l0:0:wait:/etc/rc.d/rc 0
    • l1:1:wait:/etc/rc.d/rc 1
    • l2:2:wait:/etc/rc.d/rc 2
    • l3:3:wait:/etc/rc.d/rc 3
    • l4:4:wait:/etc/rc.d/rc 4
    • l5:5:wait:/etc/rc.d/rc 5
    • l6:6:wait:/etc/rc.d/rc 6
  • 相关阅读:
    修改滚动条样式
    svg转png
    封装普通数据为树菜单结构数据模式
    js调用打印机打印
    jq 上传下载进度条
    html内容溢出部分...
    html调用html的方法
    4 人类社会及其发展规律
    7 社会主义
    8 共产主义
  • 原文地址:https://www.cnblogs.com/zhehan54/p/5877941.html
Copyright © 2020-2023  润新知