• Linux启动之旅


    引言

    某出租房内,某台电脑的电源键被按下,于是开启了一段Linux启动之旅...

    light

    BIOS

    系统启动,首先进入BIOS。

      ● BIOS 为 Base Input/Output System(基本输入输出系统)的简写

      ● 其执行POST(Power on self test,上电自检),在发现问题时发出告警声

      ● 在启动设备(cd-rom,网络,硬盘等)中搜寻boot loader

      ● 将boot loader stage1程序加载进内存,并执行

      ● 之后BIOS将“控制权”交给boot loader stage1

    MBR

    一般情况下,系统从硬盘启动,硬盘中存放boot loader stage1程序的扇区被称为MBR。

      ● MBR 为 Master boot record (主引导扇区)的简称

      ● 它是启动硬盘(/dev/sda)的首个扇区

      ● 该512字节的扇区用于存放三个部分内容:

        1) boot loader stage1程序     446字节   

        2) 硬盘分区表                        64字节   

        3) 该扇区的有效标示              2字节

    我们可以使用dd命令获取该扇区内容

    linux-q62c:/home/lx/test # dd if=/dev/sda1 of=sector bs=512 count=1
    1+0 records in
    1+0 records out
    512 bytes (512 B) copied, 4.9448e-05 s, 10.4 MB/s

    然后使用strings命令进行读取:

    linux-q62c:/home/lx/test # strings sector
    ZRrK
    D|f1
    GRUB
    Geom
    Hard Disk
    Read
    Error

      ● boot loader stage1程序被执行之后,我们开始了GRUB之旅

    GRUB

    GRUB是主流的boot loader,GRUB分成多个阶段运行。boot loader stage1是GRUB的第一阶段,并不是其完全体。

      ● stage1的主要工作是加载stage1.5

      ● stage1.5加载kernel所在盘的文件系统,之后加载stage2

    在/boot/grub目录下,我们可以看到stage1.5阶段可加载的文件系统:

    linux-q62c:~ # ls /boot/grub/*stage1_5
    /boot/grub/e2fs_stage1_5 /boot/grub/minix_stage1_5
    /boot/grub/fat_stage1_5 /boot/grub/reiserfs_stage1_5
    /boot/grub/ffs_stage1_5 /boot/grub/ufs2_stage1_5
    /boot/grub/iso9660_stage1_5 /boot/grub/vstafs_stage1_5
    /boot/grub/jfs_stage1_5 /boot/grub/xfs_stage1_5

      ● 根据/boot/grub/menu.lst配置文件,stage2阶段显示可进入的系统列表

    default 0
    timeout 8
    gfxmenu (hd0,0)/boot/message

    title SUSE Linux Enterprise Desktop 11 SP1 - 2.6.32.12-0.7
    root (hd0,0)
    kernel /boot/vmlinuz-2.6.32.12-0.7-default root=/dev/disk/by-id/ata-Hitachi_HTS541616J9SA00_SB3441GRHSXZDE-part1 resume=/dev/disk/by-id/ata-Hitachi_HTS541616J9SA00_SB3441GRHSXZDE-part5 splash=silent showopts
    initrd /boot/initrd-2.6.32.12-0.7-default

    以上menu.lst文件中,列出了kernel和initrd镜像的路径

      ● GRUB的最后一步就是加载kernel和initrd镜像

    Kernel/initrd

    接下来kernel镜像被解压并执行,kernel完成初始化硬件、进程调度、内存管理等任务。

      ● kernel对硬件进行再次检测

      ● 加载必要的模块和驱动程序,其他驱动程序和模块组件(如USB、SATA等设备模块)由后续initrd提供

    因其他模块由initrd提供,kernel得以成功“瘦身”:

    linux-q62c:~ # ll /boot/vmlinuz-2.6.32.12-0.7-default
    -rw-r--r-- 1 root root 3231872 May 20 2010 /boot/vmlinuz-2.6.32.12-0.7-default 
    linux-q62c:~ # ll /boot/initrd-2.6.32.12-0.7-default 
    -rw-r--r-- 1 root root 5847144 Mar 8 23:47 /boot/initrd-2.6.32.12-0.7-default

      ● 加载initrd(initial RAM disk,虚拟文件系统),在内存中展开得到虚拟根分区

    此时initrd被展开,真正的磁盘还没有被挂载,通过以下命令可以手工展开initrd:

    linux-q62c:/boot # mkdir initrd.d
    linux-q62c:/boot # cd initrd.d/
    linux-q62c:/boot/initrd.d # cp ../initrd-2.6.32.12-0.7-default initrd.gz
    linux-q62c:/boot/initrd.d # gzip -d initrd.gz
    linux-q62c:/boot/initrd.d # cpio -i < initrd

    展开initrd后,我们可以看到其内容与真正根目录所包含的内容大致相同:

    linux-q62c:/boot/initrd.d # ls
    bin dev lib root tmp
    boot etc lib64 run_all.sh usr
    bootsplash init mkinitrd.config sbin var
    config initrd-2.6.32.12-0.7-default proc sys

      ● 执行initrd中的init脚本,完成加载模块、检查磁盘(fsck)等任务

      ● 挂载真正的根文件系统,之后执行/sbin/init程序

    /sbin/init

    /sbin/init是Linux启动后第一个用户态下的进程(PID为1),根据/etc/inittab配置文件,/sbin/init完成系统软件环境的设定,比如主机名、网络设定以及其他启动服务。

      ● 进行系统初始化

      ● 根据开机运行级别,启动相应级别的服务

    如下/etc/inittab文件中,默认的运行级别为5:

    # The default runlevel is defined here
    id:5:initdefault:

    l0:0:wait:/etc/init.d/rc 0
    l1:1:wait:/etc/init.d/rc 1
    l2:2:wait:/etc/init.d/rc 2
    l3:3:wait:/etc/init.d/rc 3
    #l4:4:wait:/etc/init.d/rc 4
    l5:5:wait:/etc/init.d/rc 5
    l6:6:wait:/etc/init.d/rc 6

    之后根据该级别,调用/etc/init.d/rc脚本,启动/etc/init.d/rc5.d/目录下的服务:

    linux-q62c:~ # ll /etc/init.d/rc5.d/
    ……
    lrwxrwxrwx 1 root root 9 Mar 8 23:29 K06syslog -> ../syslog
    lrwxrwxrwx 1 root root 14 Mar 8 23:29 K07earlysyslog -> ../earlysyslog
    lrwxrwxrwx 1 root root 10 Mar 8 23:29 K07network -> ../network
    lrwxrwxrwx 1 root root 21 Mar 8 23:51 K08SuSEfirewall2_init -> ../SuSEfirewall2_init
    lrwxrwxrwx 1 root root 7 Mar 8 23:29 K08dbus -> ../dbus
    lrwxrwxrwx 1 root root 21 Mar 8 23:51 S01SuSEfirewall2_init -> ../SuSEfirewall2_init
    lrwxrwxrwx 1 root root 8 Mar 8 23:14 S01acpid -> ../acpid
    lrwxrwxrwx 1 root root 7 Mar 8 23:21 S01dbus -> ../dbus
    ……

    以上所列文件中,以"S"开头的项为开机时启动的服务,以"K"开头的项为关机或重启时关闭的服务项。

      ● 根据运行级别,执行相应getty,进入登陆界面

    # getty-programs for the normal runlevels
    # <id>:<runlevels>:<action>:<process>
    # The "id" field MUST be the same as the last
    # characters of the device (after "tty").
    1:2345:respawn:/sbin/mingetty --noclear tty1
    2:2345:respawn:/sbin/mingetty tty2
    3:2345:respawn:/sbin/mingetty tty3
    4:2345:respawn:/sbin/mingetty tty4
    5:2345:respawn:/sbin/mingetty tty5
    6:2345:respawn:/sbin/mingetty tty6

    至此,系统启动过程完成,界面提示输入用户名和密码。

    小结

    Linux启动过程如下:

    BIOS   --->   MBR   --->   GRUB   --->   kernel/initrd   --->   init

    在GRUB阶段,可以通过命令与系统交互,自行加载kernel和initrd,亦可修改kernel加载参数;

    在initrd阶段,我们可以加载自定义的initrd文件,使其加载更多模块,亦可在此阶段拉起bash,进行修复文件系统、修改root密码等工作;

    我们还可以修改/etc/inittab等启动配置文件,自行设定启动环境、按需要增删启动服务项;

    ⋯⋯

    总之,Linux的启动过程可以被灵活的定制。是否已经跃跃欲试了?尝试一下吧,Just for fun!

    ------------------------------------------------------------

    本文基于Suse11sp1(x86_64),该发行版可从这里下载。

    linux-q62c:~ # cat /etc/SuSE-release;uname -r
    SUSE Linux Enterprise Desktop 11 (x86_64)
    VERSION = 11
    PATCHLEVEL = 1
    2.6.32.12-0.7-default

    Reference:  6 Stages of Linux Boot Process (Startup Sequence)

          Inside the Linux boot process

  • 相关阅读:
    ExecuteScalar 返回值问题
    c#中怎么用for循环遍历DataTable中的数据
    select多用户之间通信
    python快速学习6
    python快速学习5
    python快速学习4
    python快速学习3
    python快速学习2
    arm处理器
    软链接与硬链接
  • 原文地址:https://www.cnblogs.com/bangerlee/p/2388275.html
Copyright © 2020-2023  润新知