目录
GRUB加载内核的过程
GRUB 的作用有以下几个:
-
加载操作系统的内核;
-
拥有一个可以让用户选择的的菜单,来选择到底启动哪个系统;
-
可以调用其他的启动引导程序,来实现多系统引导。
按照启动流程,BIOS 在自检完成后,会到第一个启动设备的 MBR 中读取 GRUB。在 MBR 中用来放置启动引导程序的空间只有 446 Byte,那么 GRUB 可以放到这里吗?答案是空间不够,GRUB 的功能非常强大,MBRM 空间是不够使用的。那么 Linux 的解决办法是把 GRUB 的程序分成了三个阶段来执行。
Stage 1:执行GRUB主程序
第一阶段是用来执行 GRUB 主程序的,这个主程序必须放在启动区中(也就是 MBR 或者引导扇区中)。但是 MBR 太小了,所以只能安装 GRUB 的最小的主程序,而不能安装 GRUB 的相关配置文件。这个主程序主要是用来启动 Stage 1.5 和 Stage 2 的。
Stage 1.5:识别不同的文件系统
Stage 2 比较大,只能放在文件系统中(分区),但是 Stage 1 不能识别不同的文件系统,所以不能直接加载 Stage 2。这时需要先加载 Stage 1.5,由 Stage 1.5 来加载不同文件系统中的 Stage 2。
还有一个问题,难道 Stage 1.5 不是放在文件系统中的吗?如果是,那么 Stage 1 同样不能找到 Stage 1.5。其实,Stage 1.5 还真没有放在文件系统中,而是在安装 GRUB 时,直接安装到紧跟 MBR 之后的 32KB 的空间中,这段硬盘空间是空白无用的,而且是没有文件系统的,所以 Stage 1 可以直接读取 Stage 1.5。读取了 Stage 1.5 就能识别不同的文件系统,才能加载 Stage 2。
Stage 2:加载GRUB的配置文件
Stage 2 阶段主要就是加载 GRUB 的配置文件 /boot/grub/grub.conf,然后根据配置文件中的定义,加载内核和虚拟文件系统。接下来内核就可以接管启动过程,继续自检与加载硬件模块了。
内核的设计风格:
内核的设计风格:
-
单内核:把所有的功能都做到内核,例子:Linux (LWP)
linux虽然是单内核的,但它逐渐往微内核里面靠,采用了模块化的设计,核心ko和共享模块so,核心能够动态加载各种的外围的内核模块,例如内核探测到一个磁盘,这个磁盘当前没有驱动,内核探测到磁盘的特性,加载相对应得模块,加载进来。而启动加载进来的是只是核心本身。内核模块放在/lib/modules/”内核版本号命名的目录”/,内核命名:vmlinuz-版本 -
微内核:内核很小,只有核心功能,其他功能做成子系统,当需要用到那个子系统由内核调度进来,例子:Windows, Solaris (线程)
虚拟文件系统:
根所在的分区叫做根文件系统rootfs,如果内核没有磁盘的驱动,那么就访问不了根文件系统了,所有的访问都是要通过根目录才可以访问,这样就访问不了/lib/modules,访问不了这个目录,就拿不到驱动,那么就有一个先后问题,要想访问磁盘,要先有驱动,而要想有驱动,就必须要能访问磁盘?
解决的办法:找一个中间人,一个文件,这个文件是动态生成的,在安装程序在安装完成以后,它会知道内核要访问的根在内核中有没有这个模块,也会知道这个磁盘到底需要哪一个驱动,然后动态生成这个中间人的文件,这么文件是一个独立文件系统,是一个根文件系统,这个是一个虚根,跟真正的根没有关系,只是临时过渡的根文件系统,可以装载到内存中,在内存中展开,将内存当磁盘来用,这个叫做ramdisk或者ramfs当内核能够访问真正的根了,挂载真正根文件系统了,让根文件系统建立起来,这个虚根就不要了,这个过程就是根切换,这个虚根的文件名initrd(ramdisk ),initramfs(ramfs)。所有这个并不一定需要的,只有当内核无法挂载根文件系统的时候才用得上
启动流程:
POST-->BIOS(BootSequence)-->MBR(bootloader,446)-->Kernel-->initrd(initramfs)-->(ROOTFS)/sbin/init(/etc/inittab)
-
加载BIOS的硬件信息与进行自我测试,并依据设置取得第一个可启动的设备
-
读取并执行第一个启动设备内的MBR的bootLoader,例如grub
-
依据bootLoader的设置加载Kernel,kernel检测硬件与加载驱动程序
-
在硬件驱动成功后,Kernel会主动调用init进程,而init进程会取得run-level信息
-
init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境
-
init执行run-level的各个服务的启动
-
init执行/etc/rc.d/rc.local文件
-
init执行终端机模拟程序mingetty来启动login进程,等待用户登录
内核从某个磁盘分区上识别的,在内核还没有启动之前是没有文件系统的,所以由MBR中的BootLoader来识别内核所在的分区
bootloader
-
LILO: LInux LOader
-
GRUB: GRand Unified Bootloader,这个有三个阶段:
-
grup的配置文件grup.conf
default=0 # 设定默认启动的title的编号,从0开始
timeout=5 # 等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz # grub的背景图片
hiddenmenu # 隐藏菜单
password 明文密码 #这里使用密码的话,在刚开机的时候如果需要进入编辑,需要输入密码
password --md5 密文密码 # 用grup-md5-crypt生成密文的密码
title Red Hat Enterprise Linux Server(2.6.18-308.el5)#内核标题,或操作系统名称,字符串,可自由修改
root (hd0,0) #内核文件所在的设备;对grub而言,所有类型硬盘一律hd,格式为(hd#,N);hd#, #表示第几个磁盘;最后的N表示对应磁盘的分区;
kernel /vmlinuz-2.6.18-308.el5 ro root=/dev/vol0/root rhgb quiet # 内核文件路径,及传递给内核的参数
initrd /initrd-2.6.18-308.el5.img # ramdisk文件路径
password --md5 密文密码 #如果这里有密码,那么启动内核的时候需要输入密码才可以
title Install Red Hat Enterprise Linux 5
root (hd0,0)
kernel /vmlinuz-5 ks=xxxx ksdevice=eth0 noipv6
initrd /initrd-5
password --md5 密文密码 -
Stage1:装在MBR,主要是为引导第二阶段,不是引导操作系统的
-
Stage1_5: 识别常见不同类型的文件系统,这样才能在第二阶段找到/boot/grub/
-
Stage2: 真正启动操作系统,位于/boot/grub/
Kernel的初始化过程
-
设备探测
-
驱动初始化(可能会从initrd(initramfs)文件中装载驱动模块)
-
以只读挂载根文件系统;
-
装载第一个进程init(PID:1)
/sbin/init:
配置文件/etc/inittab:
/etc/inittab的任务:
-
1、设定默认运行级别;
-
2、运行系统初始化脚本;
-
3、运行指定运行级别对应的目录下的脚本;
-
4、设定Ctrl+Alt+Del组合键的操作;
-
5、定义UPS电源在电源故障/恢复时执行的操作;
-
6、启动虚拟终端(2345级别);
-
7、启动图形终端(5级别);
运行级别:
0:halt
1: single user mode, 直接以管理员身份切入,
2:multi user mode, no NFS
3: multi user mode, text mode
4:reserved
5: multi user mode, graphic mode
6: reboot
查看运行级别的相关命令:
-
runlevel
-
who -r
init的处理流程
-
先取得runlevel
-
使用/etc/rc.d/rc.sysinit进行系统初始化
-
1、激活udev和selinux;
-
2、根据/etc/sysctl.conf文件,来设定内核参数;
-
3、设定时钟时钟;
-
4、装载键盘映射;
-
5、启用交换分区;
-
6、设置主机名;
-
7、根文件系统检测,并以读写方式重新挂载;
-
8、激活RAID和LVM设备;
-
9、启用磁盘配额;
-
10、根据/etc/fstab,检查并挂载其它文件系统;
-
11、清理过期的锁和PID文件;
-
etc/rc.d/rc.sysinit完成的任务:
-
根据runlevel进行相对应的动作,程序
-
设置好【ctrl】+【alt】+【del】这组的组合键功能
-
设置不断电系统的pf,pr两种机制
-
启动mingetty的6个终端机
-
最终以/etc/x11/perfdm -nodaemon启动图形界面
内容:
id:3:initdefault:设置默认运行级别
id:runlevels:action:process
* id: 标识符
* unlevels: 在哪个级别运行此行;
* action: 在什么情况下执行此行;
+ initdefault: 设定默认运行级别
+ sysinit: 系统初始化
+ wait: 等待级别切换至此级别时执行
+ respawn: 一旦程序终止,会重新启动
* process: 要运行程序;
启动系统服务以及相关的启动配置文件
服务类脚本: 可以使用start|stop|restart|status|reload|configtest这些参数的脚本,主要在/etc/rc.d/init.d,文件名去那边以Sxx或Kxx开头
每个文件都有#chkconfig和#description这两项
格式:
/# chkconfig: runlevels SS KK 当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevels表示默认创建为S*开头的链接,-表示没有级别默认为S*开头的链接;除此之外的级别默认创建为K*开头的链接;
S后面的启动优先级为SS所表示的数字;K后面关闭优先次序为KK所表示的数字;
/# description: 用于说明此脚本的简单功能; , 续行
chkconfig命令:
chkconfig --list: 查看所有独立守护服务的启动设定;独立守护进程!
chkconfig --list SERVICE_NAME:查看某一个服务
chkconfig --add SERVICE_NAME:为某一个服务创建S开头,K开头的链接
chkconfig --del SERVICE_NAME:删除某一个服务S开头,K开头的链接
chkconfig [--level RUNLEVELS] SERVICE_NAME {on|off}:关闭或开启某一个级别
如果省略级别指定,默认为2345级别;
守护进程的类型:
独立守护进程:独立的,不关联运行级别
瞬时守护进程:不需要关联至运行级别,所有的瞬时守护进程都由xinetd独立守护进程管理,xinetd也叫超级守护进程
/etc/rc.d/rc.local
> 系统最后启动的一个服务,准确说,应该执行的一个脚本
文章评论