liunx 开机流程与模块管理

  1. 系统开机的经过可以汇整成底下的流程的:
    1. 加载 BIOS 的硬件信息与进行自我测试,并依据设定取得第一个可开机的装置;
    2. 读取并执行第一个开机装置内 MBR 的 boot Loader (亦即是 grub, spfdisk 等程序);
    3. 依据 boot loader 的设定加载 Kernel ,Kernel 会开始侦测硬件与加载驱动程序;
    4. 在硬件驱动成功后,Kernel 会主动呼叫 init 程序,而 init 会取得 run-level 信息;
    5. init 执行 /etc/rc.d/rc.sysinit 档案来准备软件执行的作业环境 (如网络、时区等);
    6. init 执行 run-level 的各个服务以启动 ;
    7. init 执行 /etc/rc.d/rc.local 档案;
    8. init 执行终端机仿真程序 mingetty 来启动 login 程序,最后就等待用户登入啦;
  2. boot loader 主要的功能如下:
    • 提供选单:用户可以选择不同的开机项目,这也是多重引导的重要功能!
    • 载入核心档案:直接指向可开机的程序区段来开始操作系统;
    • 转交其他 loader:将开机管理功能转交给其他 loader 负责。
  3. 问题:假如linux安装在sata硬盘上,系统在加载核心时,没有sata硬盘的驱动,无法挂在根目录中的相关驱动,导致无法加载核心。
    • 解决方法:有一个虚拟文件系统,一般档名为/boot/initrd,这个档案的特色是,他也能够透过boot loader 来加载到内存中, 然后这个档案会被解压缩并且在内存当中仿真成一个根目录, 且此仿真在内存当中的文件系统能够提供一支可执行的程序,透过该程序来加载开机过程中所最需要的核心模块, 通常这些模块就是 USB, RAID, LVM, SCSI 等文件系统与磁盘接口的驱动程序啦!等载入完成后,会帮助核心重新呼叫 /sbin/init 来开始后续的正常开机流程。
  4. 问题:是否没有 initrd 就无法顺利开机?
    • 解答:不见得的!需要 initrd 最重要的原因是,当开机时无法挂载根目录的情况下, 此时就一定需要 initrd ,例如你的根目录在特殊的磁盘接口 (USB, SATA, SCSI) , 或者是你的文件系统较为特殊 (LVM, RAID) 等等,就会需要 initrd。如果你的 Linux 是安装在 IDE 接口的磁盘上,并且使用默认的 ext2/ext3 文件系统, 那么不需要 initrd 也能够顺利的开机进入 Linux 的!
  5. 第一支程序 init 及配置文件 /etc/inittab 与 runlevel
    1. Run level:执行等级有哪些?
      • 0 - halt (系统直接关机)
      • 1 - single user mode (单人维护模式,用在系统出问题时的维护)
      • 2 - Multi-user, without NFS (类似底下的 runlevel 3,但无 NFS 服务)
      • 3 - Full multi-user mode (完整含有网络功能的纯文本模式)
      • 4 - unused (系统保留功能)
      • 5 - X11 (与 runlevel 3 类似,但加载使用 X Window)
      • 6 - reboot (重新启动)
    2. init 的处理流程
      1. 先取得 runlevel 亦即默认执行等级的相关等级 (以鸟哥的测试机为例,为 5 号);
      2. 使用 /etc/rc.d/rc.sysinit 进行系统初始化
      3. 由于 runlevel 是 5 ,因此只进行『 l5:5:wait:/etc/rc.d/rc 5』,其他行则略过
      4. 设定好 [ctrl]+[alt]+[del] 这组的组合键功能
      5. 设定不断电系统的 pf, pr 两种机制;
      6. 启动 mingetty 的六个终端机 (tty1 ~ tty6)
      7. 最终以 /etc/X11/perfdm -nodaemon 启动图形接口啦!
    3. init 处理系统初始化流程 (/etc/rc.d/rc.sysinit)
      1. 取得网络环境与主机类型:
        • 读取网络配置文件 /etc/sysconfig/network ,取得主机名与默认通讯闸 (gateway) 等网络环境。
      2. 测试与挂载内存装置 /proc 及 USB 装置 /sys:
        • 除挂载内存装置 /proc 以外,还会主动侦测系统上是否具有 usb 的装置, 若有则会主动加载usb 的驱动程序,并且尝试挂载 usb 的文件系统。
      3. 决定是否启动 SELinux:
        • 检测是否需要帮所有的档案重新编写标准的 SELinux 类型 (auto relabel)。
      4. 启动系统的随机数生成器:
        • 随机数生成器可以帮助系统进行一些密码加密演算的功能,在此需要启动两次随机数生成器。
      5. 设定终端机 (console) 字形:
      6. 设定显示于开机过程中的欢迎画面 (text banner);
      7. 设定系统时间 (clock) 与时区设定:需读入 /etc/sysconfig/clock 设定值
      8. 接口设备的侦测与 Plug and Play (PnP) 参数的测试:
        • 根据核心在开机时侦测的结果 (/proc/sys/kernel/modprobe ) 开始进行 ide / scsi / 网络 / 音效等接口设备的侦测,以及利用以加载的核心模块进行 PnP 装置的参数测试。
      9. 用户自定义模块的加载
        • 使用者可以在 /etc/sysconfig/modules/*.modules 加入自定义的模块,则此时会被加载到系统当中
      10. 加载核心的相关设定:
        • 系统会主动去读取 /etc/sysctl.conf 这个档案的设定值,使核心功能成为我们想要的样子。
      11. 设定主机名与初始化电源管理模块 (ACPI)
      12. 初始化软件磁盘阵列:主要是透过 /etc/mdadm.conf 来设定好的。
      13. 初始化 LVM 的文件系统功能
      14. 以 fsck 检验磁盘文件系统:会进行 filesystem check
      15. 进行磁盘配额 quota 的转换 (非必要):
      16. 重新以可擦写模式挂载系统磁盘:
      17. 启动 quota 功能:所以我们不需要自定义 quotaon 的动作
      18. 启动系统虚拟随机数生成器 (pseudo-random):
      19. 清除开机过程当中的临时文件:
      20. 将开机相关信息加载 /var/log/dmesg 档案中。
  6. 动系统服务与相关启动配置文件 (/etc/rc.d/rc N & /etc/sysconfig)
    1. /etc/rc.d/rc 这个档案
      • 透过外部第一号参数 ($1) 来取得想要执行的脚本目录。亦即由 /etc/rc.d/rc 5 可以取得/etc/rc5.d/ 这个目录来准备处理相关的脚本程序;
      • 找到 /etc/rc5.d/K??* 开头的档案,并进行『/etc/rc5.d/K??* stop 』的动作;
      • 找到 /etc/rc5.d/S??* 开头的档案,并进行『/etc/rc5.d/S??* start 』的动作;
    2. etc/rc5.d/这个档案
      • 档名全部以 Sxx 或 Kxx ,其中 xx 为数字,且这些数字在档案之间是有相关性的!全部是连结档,连结到 stand alone 服务启动的目录 /etc/init.d/ 去
      •  /etc/rc5.d/[SK]xx 其实就是跑到/etc/init.d/ 去找到相对应的服务脚本, 然后分别进行start (Sxx) 或 stop (Kxx) 的动作而已啦!
      • 因为各不同的服务其实还是互有关系的,先启用了某些服务,其他服务才能再启用。所以有Sxx和Kxx
  7. 用户自定义开机启动程序 (/etc/rc.d/rc.local)
    • 有任何想要在开机时就进行的工作时,直接将他写入 /etc/rc.d/rc.local , 那么该工作就会在开机的时候自动被加载喔!
  8. 根据 /etc/inittab 以设定,加载终端机或 X-Window 接口
    • /etc/init/start-ttys.conf --------该配置文件定义六个终端窗口
  9. 开机过程会用到的主要配置文件
    • 我们在 /sbin/init 的运作过程中有谈到讲多执行脚本,包括 /etc/rc.d/rc.sysinit 以及 /etc/rc.d/rc 等等, 其实这些脚本都会使用到相当多的系统配置文件,这些开机过程会用到的配置文件则大多放置在/etc/sysconfig/ 目录下。 同时,由于核心还是需要加载一些驱动程序 (核心模块),此时系统自定义的装置与模块对应文件 (/etc/modprobe.conf) 就显的挺重要了喔!
    • 关于模块: /etc/modprobe.conf
      •  cat /etc/modprobe.conf
      •   alias eth0 8139too <==让 eth0 使用 8139too 的模块
    • /etc/sysconfig/*
      • authconfig:这个档案主要在规范使用者的身仹认证的机制,包括是否使用本机的 /etc/passwd,/etc/shadow 等,以及 /etc/shadow 密码记录使用何种加密算法,还有是否使用外部密码服务器提供的账号验证(NIS, LDAP) 等。 系统默认使用 MD5 加密算法,并且不使用外部的身仹验证机制;
      • clock:此档案在设定 Linux 主机的时区,可以使用格林威治时间(GMT),也可以使用本地时间(local)。基本上,在 clock 档案内的设定项目『ZONE 』所参考的时区位于/usr/share/zoneinfo 目录下的相对路径中。而且要修改时区的话,还得将/usr/share/zoneinfo/Asia/Taipei 这个档案复制成为 /etc/localtime 才行!
      • i18n:i18n 在设定一些诧系的使用方面,例如最麻烦的文字接口下的日期显示问题,乱码时更动这个 i18n 的档案,将里面的 LC_TIME改成 en 即可!
      • keyboard & mouse:keyboard 与 mouse 就是在设定键盘与鼠标的形式;
      • network:network 可以设定是否要启动网络,以及设定主机名还有通讯闸 (GATEWAY) 这两个重要信息
  10. Run level 的切换
    • 不同的 run level 叧是加载的服务不同罢了, 亦即是 /etc/rc5.d/ 还有 /etc/rc3.d 内的Sxxname 与 Kxxname 有差异而已。
    • 从 run level 5执行init3:
      1. 先比对 /etc/rc3.d/ 及 /etc/rc5.d 内的 K 与 S 开头的档案;
      2. 在新的 runlevel 亦即是 /etc/rc3.d/ 内有多的 K 开头档案,则予以关闭;
      3. 在新的 runlevel 亦即是 /etc/rc3.d/ 内有多的 S 开头档案,则予以启动;
    • 查询当前运行等级    runlevel
  11. 核心与核心模块 
    1. 核心与核心模块放在哪
      • 核心: /boot/vmlinuz 或 /boot/vmlinuz-version;
      • 核心解压缩所需 RAM Disk: /boot/initrd (/boot/initrd-version);
      • 核心模块: /lib/modules/version/kernel 或 /lib/modules/$(uname -r)/kernel;
      • 核心原始码: /usr/src/linux (要安装才会有!否则预设不安装的!)
    2. 如果该核心被顺利的加载系统当中了,那么就会有几个信息记录下来:
      • 核心版本: /proc/version
      • 系统核心功能: /proc/sys/kernel
    3. 添加系统与支持的新硬件
      1. 重新编译核心,并加入最新的硬件驱动程序原始码;
      2. 将该硬件的驱动程序编译成为模块,在开机时加载该模块
  12. 核心模块与相依性
    1. /lib/modules/$(uname -r)/kernel  内容介绍
      • arch :与硬件平台有关的项目,例如 CPU 的等级等等;
      • crypto :核心所支持的加密的技术,例如 md5 或者是 des 等等;
      • drivers :一些硬件的驱动程序,例如显示适配器、网络卡、 PCI 相关硬件等等;
      • fs :核心所支持的 filesystems ,例如 vfat, reiserfs, nfs 等等;
      • lib :一些函式库;
      • net :与网络有关的各项协议数据,还有防火墙模块 (net/ipv4/netfilter/*) 等
      • sound :与音效有关的各项模块;
    2. /lib/modules/$(uname -r)/modules.dep 记录了在核心支持的模块的各项相依性,
      • depmod [-Ane]
        • -A :不加任何参数时, depmod 会主动的去分析目前核心的模块,并且重新写入/lib/modules/$(uname -r)/modules.dep 当中。若加入 -A 参数时,则depmod会去搜寻比 modules.dep 内还要新的模块,如果真找到新模块,才会更新。
        • -n :不写入 modules.dep ,而是将结果输出到屏幕上(standard out);
        • -e :显示出目前已加载的不可执行的模块名称
    3. 例如:一个网卡驱动程序,档名为 a.ko,该如何更新核心相依性
      1. cp a.ko /lib/modules/$(uname -r)/kernel/drivers/net
      2. depmod
  13. 核心模块的观察
    •  lsmod ----------------查看目前核心加载了多少的模块
    • modinfo ------------------查阅具体模块的信息
      •  modinfo [-adln] [module_name|filename]
        • -a :仅列出作者名称;
        • -d :仅列出该 modules 的说明 (description);
        • -l :仅列出授权 (license);
        • -n :仅列出该模块的详细路径。
  14. 核心模块的加载与移除
    • 不会主动的分析模块相依性,如果有相依性问题,会报错,加载不上
    • insmod [/full/path/module_name] [parameters]-------------自行加载模块
    • 例:载入 cifs.ko 这个『文件系统』模块
      • insmod /lib/modules/$(uname -r)/kernel/fs/cifs/cifs.ko
      • lsmod | grep cifs
    • rmmod [-fw] module_name---------------一处模块
      • -f :强制将该模块移除掉,不论是否正被使用;
      • -w :若该模块正被使用,则 rmmod 会等待该模块被使用完毕后,才移除他!
    • 会主动的分析模块相依性
      • modprobe [-lcfr] module_name
        • -c :列出目前系统所有的模块!(更详细的代号对应表)
        • -l :列出目前在 /lib/modules/`uname -r`/kernel 当中的所有模块完整文件名
        • f :强制加载该模块;
        • -r :类似 rmmod ,就是移除某个模块啰~
  15. 核心模块的额外参数设定: /etc/modprobe.conf
    • vi /etc/modprobe.conf
      • alias eth0 ne  eth0与eth1同时使用ne,设置与同的IO与IRQ
      • alias eth1 ne
      • options eth0 io=0x300 irq=5
      • options eth1 io=0x320 irq=7
  16. Boot Loader: Grub
    • 开机装置的第一个sector(扇区)只有446字节,放不下boot loader 整个程序,所以linux 的boot loader的程序代码执行与设定值加载分两个阶段来执行。
    • stage1、执行boot loader主程序,必须要安装在开机区,亦即是MBR或者boot loader。仅安装最小程序,并没安装loader相关配置文件
    • stage2、主程序加载配置文件,配置文件都在/boot下    ls -l /boot/grub
    • grub 的配置文件 /boot/grub/menu.lst 与选单类型
      • grub 的优点
        • 认识与支持较多的文件系统,并且可以使用 grub 的主程序直接在文件系统中搜寻核心档名;
        • 开机的时候,可以『自行编辑与修改开机设定项目』,类似 bash 的指令模式;
        • 可以动态搜寻配置文件,而不需要在修改配置文件后重新安装 grub 。亦即是我们叧要修改完 /boot/grub/menu.lst 里头的设定后,下次开机就生效了!
    • /boot/grub/menu.lst 配置文件:
      • default=0
        • 这个必须要与 title 作为对照,在配置文件里面有几个 title ,开机的时候就会有几个选单可以选择。 由于 grub 启始号码为 0 号,因此 default=0 代表使用『第一个 title 项目』来开机的意思。 default 的意思是,如果在读秒时间结束前都没有动到键盘, grub 默认使用此 title 项目(在此为 0 号) 来开机。
      • timeout=5
        • 开机时会进行读秒,如果在 5 秒钟内没有按下任何按键,就会使用上面提到的 default 后面接的那个 title 项目来开机的意思。
      • splashimage=(hd0,0)/grub/splash.xpm.gz
        • 背景图片
      • hiddenmenu
        • 这个说的是,开机时是否要显示选单?目前 CentOS 默认是不要显示选单, 如果您想要显示选单,那就将这个设定值批注掉!
      • root :
        • 代表的是『核心档案放置的那个 partition 而不是根目录』喔!不要搞错了! 以鸟哥的案例来说,我的根目录为 /dev/hda2 而 /boot 独立为 /dev/hda1 ,因为与 /boot 有关, 所以磁盘代号就会成为 (hd0,0) 啰。
      • kernel :
        • 至于 kernel 后面接的则是核心的档名,而在档名后面接的则是核心的参数。 由于开机过程中需要挂载根目录,因此 kernel 后面接的那个 root=LABEL=/1 指的是『 Linux 的根目录在哪个 partition 』的意思。 还记得第八章谈过的 LABEL 挂载功能吧? 是的,这里使用 LABEL 来挂载根目录。至于 rhgb 为色彩显示而 quiet 则是安静模式 (屏幕不会输出核心侦测的信息)。
      • initrd :
        • 就是前面提到的 initrd 制作出 RAM Disk 的档案档名啦!
    • 利用 chain loader 的方式转交控制权
      • vi /boot/grub/menu.lst
        • title Windows partition
          • hide (hd0,4) <==隐藏 (hd0,4) 这个分割槽 (可选)
          • root (hd0,0) <==设定使用此分割槽    (看系统装在哪个分区)
          • 或 rootnoverify (hd0,0) <==不检验此分割槽
          • chainloader +1 <== +1 可以想成第一个扇区,亦即是 boot sector
          • makeactive <==设定此分割槽为开机碟(active)---由于 Windows 的开机碟需要设定为活动 (active) 状态
  17. initrd 的重要性与建立新 initrd 档案
    • mkinitrd [-v] [--with=模块名称] initrd 文件名 核心版本
      • -v :显示 mkinitrd 的运作过程
      • --with=模块名称:模块名称指的是模块的名字而已,不需要填写档名。举例来说,目前核心版本的 ext3 文件系统模块为底下的文件名:
      • /lib/modules/$(uname -r)/kernel/fs/ext3/ext3.ko那妳应该要写成: --with=ext3 就好了 (省略 .ko)说,
      • initrd 档名:妳所要建立的 initrd 档名,尽量取有意义又好记的名字。
      • 核心版本 :某一个核心的版本,如果是目前的核心则是『$(uname -r) 』
    • 例:增加 8139too 这个模块的 initrd 档案
      1.  mkinitrd -v --with=8139too initrd_vbirdtest $(uname -r)
  18. 测试与安装 grub
    •  grub-install [--root-directory=DIR] INSTALL_DEVICE
      • --root-directory=DIR 那个 DIR 为实际的目录,使用 grub-install 默认会将grub 所有的档案都复制到 /boot/grub/* ,如果想要复制到其他目录与装置去,就得要用这个参数。
      • INSTALL_DEVICE 安装的装置代号啦!
    • 例:将 grub 安装在目前系统的 MBR 底下,我的系统为 /dev/hda:
      •  grub-install /dev/hda
      • 我的 /home 为独立的 /dev/hda3 ,如何安装 grub 到 /dev/hda3
      •  grub-install --root-directory=/home /dev/hda3
    • 档案都安装进来了!但是注意到,我们并没有配置文件喔!那要自己建立!最后还要以 grub shell 来安装 grub 主程序到 MBR 或者是boot sector 上面去喔!
      • 例:在原本的 menu.lst 当中新增三个开机选单,分别如下说明:
        • 假设 /dev/hda1 内含有 boot loader ,此 loader 如何取得控制权?
        • 如何重新读取 MBR 内的 loader ?
        • 利用你原本的系统核心档案,建立一个可强制进入单人维护模式的选单
      • 实施过程:
        • vim /boot/grub/menu.lst
          •   default=0
                timeout=30
                splashimage=(hd0,0)/grub/splash.xpm.gz
                #hiddenmenu
                title CentOS (2.6.18-92.el5)
                root (hd0,0)
                kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
                initrd /initrd-2.6.18-92.el5.img
                title /dev/hda1 boot sector <==本例中的第一个新增选单
                root (hd0,0)
                chainloader +1
                title MBR loader <==新增的第二个选单
                root (hd0) <==MBR 为整颗磁盘的第一个扇区,所以用整颗磁盘的代号
                chainloader +1
                title single user mode <==新增的第三个选单(其实由原本的 title 复制来的)
                root (hd0,0)
                kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet single
                initrd /initrd-2.6.18-92.el5.img
          • 下次开机时,你就会发现有四个选单可以选择,而预设会以第一个选单来开机喔!
        • 将 grub 主程序再次的安装到 /dev/hda1 的 boot sector ,也想要重新安装grub 到 MBR 上面去
          • grub指令介绍
            • 用『root (hdx,x) 』选择含有 grub 目录的那个 partition 代号;
            • 用『find /boot/grub/stage1 』看看能否找到安装信息档案;
            • 用『find /boot/vmlinuz 』看看能否找到 kernel file (不一定要成功!)
            • 用『setup (hdx,x) 』或『setup (hdx) 』将 grub 安装在 boot sector 或 MBR;
            • 用『quit 』来离开 grub shell !
          • 实施过程:
            • [root@www ~]# grub
                  1. 先设定一下含有 grub 目录的那个 partition 啊!
                   grub> root (hd0,0)
                   2. 搜寻一下,是否存在 stage1 这个信息档案?
                   grub> find /grub/stage1
                   (hd0,0)
                   因为 /boot 是独立的,且 grub 找到不是目录树,而是装置内的档案。
                  3.搜寻一下是否可以找到核心? /boot/vmlinuz-2.6.18-92.el5 ?
                   grub> find /vmlinuz-2.6.18-92.el5
                   (hd0,0)
                   4. 将主程序安装上去吧!安装到 MBR 看看!
                   grub> setup (hd0)
                  5. 那么重复安装到我的 /dev/hda1 呢?亦即是 boot sector 当中?
                   grub> setup (hd0,0)
        • 最后总结一下:
             1. 如果是从其他 boot loader 转成 grub 时,得先使用 grub-install 安装 grub 配置文件;
             2. 开始编辑 menu.lst 这个重要的配置文件;
             3. 透过 grub 来将主程序安装到系统中,如 MBR 的 (hd0) 或 boot sector 的 (hd0,0) 等等
原文地址:https://www.cnblogs.com/guojintao/p/5744295.html