一、 Linux的启动流程分析
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 的各个服务之启动 (script 方式);
7. init 运行 /etc/rc.d/rc.local 文件;
8. init 运行终端机模拟程序 mingetty 来启动 login 程序,最后就等待使用者登陆啦;
2. BIOS, boot loader 与 kernel 加载
(1) BIOS, 开机自我测试与 MBR
个人计算机架构下,你想要启动整个系统首先就得要让系统去加载 BIOS (Basic Input Output System),并通过 BIOS 程序去加载 CMOS 的资讯,并且通过 CMOS 内的配置值取得主机的各项硬件配置。
(2) Boot Loader 的功能
• 提供菜单:使用者可以选择不同的启动项目,这也是多重启动的重要功能!
• 加载核心文件:直接指向可启动的程序区段来开始操作系统;
• 转交其他 loader:将启动管理功能转交给其他 loader 负责。
§ 加载核心侦测硬件与 initrd 的功能
(3) 虚拟文件系统 (Initial RAM Disk) 一般使用的档名为 /boot/initrd。
3. 第一个进程 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 的处理流程
事实上 /etc/inittab 的配置也有点类似 shell script 啦,因为该文件内容的配置也是一行一行的从上往下处理的, 因此我们可以知道 CentOS 的 init 依据 inittab 配置的处理流程会是:
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 启动图形介面啦!
4. init 处理系统初始化流程 (/etc/rc.d/rc.sysinit)
开始加载各项系统服务之前,得先做好整个系统环境,我主要利用 /etc/rc.d/rc.sysinit 这个 shell script 来配置好我的系统环境的
1. 取得网络环境与主机类型:
读取网络配置档 /etc/sysconfig/network ,取得主机名称与默认通讯闸 (gateway) 等网络环境。
2. 测试与挂载内存装置 /proc 及 U盘 装置 /sys:
除挂载内存装置 /proc 之外,还会主动侦测系统上是否具有 usb 的装置, 若有则会主动加载 usb 的驱动程序,并且尝试挂载 usb 的文件系统。
3. 决定是否启动 SELinux :
我们在第十七章谈到的 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 文件中。
5. 启动系统服务与相关启动配置档 (/etc/rc.d/rc N & /etc/sysconfig)
6. 用户自定义开机启动程序 (/etc/rc.d/rc.local)
7. 根据 /etc/inittab 之配置,加载终端机或 X-Window 介面
8. 启动过程会用到的主要配置文件:
§ 关于模块: /etc/modprobe.conf
§ /etc/sysconfig/*
authconfig:
i18n:在配置一些语系的使用方面
keyboard & mouse:是在配置键盘与鼠标的形式;
• network:配置是否要启动网络,以及配置主机名称还有通讯闸 (GATEWAY) 这两个重要资讯呢!
• network-scripts/:主要用在配置网络卡
9. Run level 的切换
run level 有关的启动其实是在 /etc/rc.d/rc.sysinit 运行完毕之后
二、 内核与内核模块
核心与核心模块放在:
核心: /boot/vmlinuz 或 /boot/vmlinuz-version;
核心解压缩所需 RAM Disk: /boot/initrd (/boot/initrd-version);
核心模块: /lib/modules/version/kernel 或 /lib/modules/$(uname -r)/kernel;
核心原始码: /usr/src/linux 或 /usr/src/kernels/ (要安装才会有,默认不安装)
如果该核心被顺利的加载系统当中了,那么就会有几个资讯纪录下来:
核心版本: /proc/version
系统核心功能: /proc/sys/kernel
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 、内核模块的查看:lsmod
使用 lsmod 之后,系统会显示出目前已经存在於核心当中的模块,显示的内容包括有:
模块名称(Module);
模块的大小(size);
此模块是否被其他模块所使用 (Used by)。
3.内核模块的加载与移除
加载:
[root@www ~]# insmod [/full/path/module_name] [parameters]
移除:
[root@www ~]# modprobe [-lcfr] module_name
选项与参数:
-c :列出目前系统所有的模块!(更详细的代号对应表)
-l :列出目前在 /lib/modules/`uname -r`/kernel 当中的所有模块完整档名;
-f :强制加载该模块;
-r :类似 rmmod ,就是移除某个模块罗~
4.内核模块的额外参数配置: /etc/modprobe.conf
三、 Boot Loader: Grub
1. boot loader 的两个 stage
(1)Stage 1:运行 boot loader 主程序:
第一阶段为运行 boot loader 的主程序,这个主程序必须要被安装在启动区,亦即是 MBR 或者是 boot sector 。但如前所述,因为 MBR 实在太小了,所以,MBR 或 boot sector 通常仅安装 boot loader 的最小主程序, 并没有安装 loader 的相关配置档;
(2)Stage 2:主程序加载配置档:
第二阶段为透过 boot loader 加载所有配置档与相关的环境参数文件 (包括文件系统定义与主要配置档 menu.lst), 一般来说,配置档都在 /boot 底下。
2.grub 的配置文件 /boot/grub/menu.lst 与菜单类型
(1)/boot/grub/menu.lst 配置文件:
root@www ~]# vim /boot/grub/menu.lst
default=0 <==默认启动选项,使用第 1 个启动菜单 (title)
timeout=5 <==若 5 秒内未动键盘,使用默认菜单启动
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
(2)直接指定核心启动:
先指定核心文件放置的 partition,再读取文件 (目录树),
最后才加入文件的实际档名与路径 (kernel 与 initrd);
root (hd0,0) <==代表核心文件放在那个 partition 当中
kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
initrd /initrd-2.6.18-92.el5.img
(3)利用 chain loader 的方式转交控制权
所谓的 chain loader (启动管理程序的链结) 仅是在将控制权交给下一个 boot loader 而已, 所以 grub 并不需要认识与找出 kernel 的档名 ,『 他只是将 boot 的控制权交给下一个 boot sector 或 MBR 内的 boot loader 而已 』 所以通常他也不需要去查验下一个 boot loader 的文件系统!
3.initrd 的重要性与创建新 initrd 文件
一般来说,需要 initrd 的时刻为:
根目录所在磁碟为 SATA、U盘 或 SCSI 等连接介面;
根目录所在文件系统为 LVM, RAID 等特殊格式;
根目录所在文件系统为非传统 Linux 认识的文件系统时;
其他必须要在核心加载时提供的模块。
4.测试与安装 grub.
grub shell :
用『 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 !
5. BIOS 无法读取大硬盘的问题
就是 BIOS 无法读取大容量磁碟内的 kernel 与 initrd 文件。
那如何解决呢?
就让 kernel 与 initrd 文件放置在大硬盘的最前头,由於于BIOS 至少可以读到大磁碟的 1024 磁柱内的数据,因此就能够读取核心与虚拟文件系统的文件罗。
那如何让 kernel 与 initrd 放置到整颗硬盘的最前面呢?
创建 /boot 独立分割槽,并将 /boot 放置到最前面即可!
四、 启动过程问题的解决
1.忘记 root 密码的解决之道:
在 Linux 环境中 root 口令忘记时还是可以救回来的!
只要能够进入并且挂载 / , 然后重新配置一下 root 的口令,就救回来啦!这是因为启动流程中,若强制核心进入 runlevel 1 时, 默认是不需要口令即可取得一个 root 的 shell 来救援的。整个动作有点像这样:
(1)重新启动!一定要重新启动!怎么重开都没关系;
(2)在启动进入 grub 菜单后,
(3)在你要进入的菜单上面点 'e' 进入详细配置;
(4)将光棒移动到 kernel 上方并点 'e' 进入编辑画面;
(5)然后出现如下画面来处理:
grub edit> kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/ rhgb quiet single
重点就是那个特殊字体的咚咚啦!按下 [enter] 再按下 b 就能够启动进入单人维护模式了。
(6)进入单人维护模式后,系统会以 root 的权限直接给你一个 shell ,此时你就能够运行『 passwd 』这个命令来重建 root 的口令啦!然后直接『 init 5 』就可以切换成为 X 窗口介面罗!就是这么简单。
2. init 配置文件错误
(1)grub edit> kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/ rhgb quiet init=/bin/bash