linux系统GRUB启动流程
内核的设计风格:
内核的设计风格:
- 单内核:把所有的功能都做到内核,例子: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,例如grup
- 依据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,这个有三个阶段:
- Stage1:装在MBR,主要是为引导第二阶段,不是引导操作系统的
- Stage1_5: 识别常见不同类型的文件系统,这样才能在第二阶段找到/boot/grub/
-
Stage2: 真正启动操作系统,位于/boot/grub/
- 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 密文密码
- grup的配置文件grup.conf
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进行系统初始化
- 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
> 系统最后启动的一个服务,准确说,应该执行的一个脚本
,