Linux 开机流程分析

本文详细剖析了Linux的开机流程,从加载BIOS硬件信息到寻找启动磁盘,再到执行/sbin/init并取得默认运行级别。重点讲解了内核加载驱动程序、挂载根文件系统、启用内核模块和init服务的过程。同时,提到了initrd在系统启动中的作用,包括加载硬件驱动和协助挂载根文件系统。

一) Linux的开机流程

 

【step 1】  加载BIOS硬件信息,寻找启动磁盘(Boot Disk);

 

【step 2】   读取MBR中的内核加载程序(Kernel Loader, 一般是LILO或者GRUB),这个程序的作用就是加载存储在某个位置的操作系统内核;

 

【step 3】  加载操作系统核心Kernel。内核的主要工作就是检测所有的硬件设备,并为它们加载驱动程序。

 

     驱动程序有两种,即静态驱动程序(static driver)和动态驱动程序(dynamic driver)。前者以内核镜像文件的形式存在,后者则存储在文件系统上。此时,文件系统尚未挂载到系统中,所以只有静态驱动程序能被使用来驱动硬件设备。

     内核另一个任务是以只读方式挂载根文件系统。挂载根目录系统的过程请参看本文的第三部分。根文件系统必须包含如下几个目录,也就是说下面几个目录只能放在根目录下面:(1)/etc/;(2)/bin/;(3)/sbin/;(4)/lib/;(5)/dev/。如果这5个目录不在根目录下面,会导致系统启动失败。

     挂载了根文件系统后,系统就能安装适当的内核模块,启用某些功能,并且能调用之前所说的动态驱动程序来驱动默写硬件设备;系统还能启动存储于根文件系统中的init服务,以便让它来接受后续的启动工作。

 

【step 4】  Kernel执行进程/sbin/init,并取得默认的运行级别(run level),在Red Hat中,init从/etc/inittab中获取run level。

 

  【step 4.1 】init执行/etc/rc.d/rc.sysinit文件

      这个script的主要功能是进行Linux系统环境的配置,诸如界面文字字体、时间、系统记录等。这里实现的功能比较多,期间还要加载Linux系统的一些内置功能及变量,如PATH或umask。

  如:

   * 设置主机名

      if [ -f /etc/sysconfig/network ]; then
             . /etc/sysconfig/network
      fi

 

   * 初始化硬件设备,包括定义在/etc/modprobe.conf的模块,ISA PnP的硬件设备和USB设备。

 

   * 设置内核参数

      # Configure kernel parameters
      update_boot_stage RCkernelparam
      sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1

 

   * 设置系统时间

  

   * 启用置换内存空间

 

   * 检查并挂载所有文件系统,并且将根文件系统的挂载参数设置为可读可写

      # Remount the root filesystem read-write.
      update_boot_stage RCmountfs
      if remount_needed ; then
           action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw /
      fi

    

    * 启用软件磁盘阵列与LVM

 

    * 初始化串行端口设备

 

    * 清除过期的锁定文件与IPC文件

 

    * 重新设置硬盘参数

 

  【step 4.2】 init根据默认运行级别,调用/etc/rc.d/rc x,运行级别作为输入参数x。实际上这个script就是执行/etc/rc.d/rcx.d中的批次文件,来启动系统的各项服务;

 

  【step 4.4】 init执行文件/etc/rc.d/rc.local

   rc.local是整个启动过程中唯一一个可以修改的RC Script。如果希望在系统启动过程中执行什么命令,就可以把它们放在这里。

 

   init服务的整个过程都定义在/etc/inittab

 

【step 5】   系统执行/bin/login

 

【step 6】  shell接管主机

 

二)Linux系统开机流程图

 

 在邱世华的书《系统架构与目录解析》中,他绘制了一幅系统启动的流程图,我摘录于此,也可作为参考。

 

Linux

图1 Linux系统启动流程图

 

Initrd:由GRUB协助一并载入initrd文件,让kernel支持更多硬件。这是邱世华在书中给出的解释。对照上面文中对系统启动流程的描述,我推断Initrd主要完成下面工作:1)加载硬件设备的静态驱动程序;2)帮助内核挂载根文件系统,当然是以只读的方式。 

 

三)根目录的建立过程

     开机管理程序(GRUB)启动了操作系统,在加载kernel到内存中之后(step 3),kernel会自行在内存中建立一块叫做rootfs的区域供其本身使用(RAMDISK技术),而里面的功能都是kernel本身所提供的,也就是在编译kernel时所赋予的能力。

     kernel加载完成之后,下一个initrd会加载正确的模块,并且在正确地辨认出存储设备的硬件之后,将系统分割区准确地挂载到根目录上,产生出一般使用的【/】根目录。

 

四) 解析initrd

 

参考文献:《linux操作系统之奥秘》,作者:邱世华

4.1 内核(kernel)加载initrd的过程

 

      initrd的全称是initial ramdisk。顾名思义就是激活系统所需加载的文件系统。系统加载initrd的过程:

1) 当GRUB加载kernel时,kernel会先在内存中制造一个rootfs当做临时的空间供系统使用;

2) kernel会将initrd作为一个系统将其mount到rootfs上激活;

3) initrd将负责协助开机时加载kernel所无法提供的模块,包硬盘的驱动程序,及其他所有必须预先加载的驱动程序。

 

4.2 initrd的内容是什么?

 

      initrd文件其实是一个gzip压缩过的cpio备份文件。所以将其中的真实内容呈现出阿里,需要先解压缩,再进行备份文件的还原。具体的步骤如下。

 

step 1: 建立一个空目录,并将initrd文件拷贝一份到目录下;

# mkdir /tmp/initrd

# cp /boot/initrd-2.6.25-14.fc9.i686.img /tmp/initrd

 

step 2: 将initrd的拷贝文件改名为.gz文件;

# cd /tmp/initrd

# mv initrd-2.6.25-14.fc9.i686.img initrd-2.6.25-14.fc9.i686.gz

 

step 3: 将其解压缩;

# gunzip initrd-2.6.25-14.fc9.i686.gz

 

step 4: 将备份文件还原。

# cpio -id <initrd-2.6.25-14.fc9.i686

 

 4.3 initrd中的目录架构

  执行了上面的命令之后,就可以看到initrd文件的真面目了。

        [root@airhouse initrd]# ls -lF | grep -v initrd
        total 7508

       drwx------ 2 root root    4096 2009-10-12 10:37 bin/
       drwx------ 3 root root    4096 2009-10-12 10:37 dev/
       drwx------ 4 root root    4096 2009-10-12 10:37 etc/
       drwx------ 2 root root    4096 2009-10-12 10:37 firmware/
       -rwx------ 1 root root    2091 2009-10-12 10:37 init*
       drwx------ 4 root root    4096 2009-10-12 10:37 lib/
       drwx------ 2 root root    4096 2009-10-12 10:37 proc/
       lrwxrwxrwx 1 root root       3 2009-10-12 10:37 sbin -> bin/
       drwx------ 2 root root    4096 2009-10-12 10:37 sys/
       drwx------ 2 root root    4096 2009-10-12 10:37 sysroot/ 
       drwx------ 3 root root    4096 2009-10-12 10:37 usr/

 

      当kernel激活并加载initrd时,并没有任何系统的目录架构,这时会先以initrd所提供的目录当做系统的暂时目录。

 

      其中,最重要的当属文件init。kernel在访问initrd时,会以此文件按其内容依次完成,它负责所有从kernel交接给文件系统中操作系统的大小事务,从建立使用的目录到加载所有的模块都是靠这个script来完成。

 

      initrd还有一个重要的使命,就是加载各种需要在开启操作系统之前就抓到的设备。这些设备当然可以放入kernel中,但是这样造成kernel文件变大,如果加入initrd中,kernel只需要按照init文件一步一步执行就可以加载这些设备。

 

4.4 initrd的init文件

 

      initrd的所有工作是按照一个叫init的脚本文件进行的。它的主要内容如下。

 

      #!/bin/nash                                                       #nash指令

 

      mount -t proc /proc /proc                                  # 挂载主要的文件系统/proc和/sys
      setquiet
      echo Mounting proc filesystem
      echo Mounting sysfs filesystem
      mount -t sysfs /sys /sys

 

      echo Creating /dev                                            # 建立设备文件所需的文件系统
      mount -o mode=0755 -t tmpfs /dev /dev
      mkdir /dev/pts
      mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
      mkdir /dev/shm
      mkdir /dev/mapper


      echo Creating initial device nodes                     # 建立最初所需使用的硬件设备
      mknod /dev/null c 1 3
      mknod /dev/zero c 1 5
      mknod /dev/systty c 4 0
      mknod /dev/tty c 5 0
      mknod /dev/console c 5 1
      mknod /dev/ptmx c 5 2
      mknod /dev/tty0 c 4 0
      mknod /dev/tty1 c 4 1

      ... ...
      mknod /dev/ttyS0 c 4 64
      mknod /dev/ttyS1 c 4 65

      ... ...
      echo Setting up hotplug.
      hotplug

 

      echo Creating block device nodes.                     # 加载相关模块
      mkblkdevs
      echo "Loading ehci-hcd module"
      modprobe -q ehci-hcd
      echo "Loading ohci-hcd module"
      modprobe -q ohci-hcd
      echo Making device-mapper control node
      mkdmnod
      modprobe scsi_wait_scan
      rmmod scsi_wait_scan
      mkblkdevs


      echo Scanning logical volumes                            # 扫描LVM
      lvm vgscan --ignorelockingfailure
      echo Activating logical volumes
      lvm vgchange -ay --ignorelockingfailure  VolGroup00
      resume /dev/VolGroup00/LogVol01


      echo Creating root device.
      mkrootdev -t ext3 -o defaults,ro /dev/VolGroup00/LogVol00
      echo Mounting root filesystem.
      mount /sysroot

 

      echo Setting up other filesystems.                      # 切入实体操作系统
      setuproot
      loadpolicy
      echo Switching to new root and running init.
      switchroot
      echo Booting has failed.
      sleep -1

 

 

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值