- 操作系统的启动流程
- 操作系统启动的流程:
post-->BIOS(Boot Sequence)--->MBR(boot loader,446)-->kernel---> initrd ---> 查找根文件系统,启动根文件系统-->init(用户空间的第一个进程);
post
加电自检:将BIOS
中的程序映射进CPU
可以查找的内存中的地址空间,ROM
映射进RAM
里面,这些指令用于完成硬件设备的检查;- 关于
bootloader
:- 对于不同的操作系统来说是不同的,
Linux
与Windows
的bootloader
是不同的,windows
默认是锁定MBR
的,不允许其他的操作来替换;Linux
支持的bootloader
包括LILO(Linux Loader)
,不支持大硬盘或者分区,嵌入式一般使用这个; GRUB(Grand Unified bootloader)
:包含两个阶段;
stage1
:装载在MBR
中了,目的是用来引导第二个阶段的;stage1.5
:其中为了识别常用的stage2
的文件系统,引入stage1.5
,用于支持常见的文件系统;stage2
:第二个阶段在/boot/grub/stage2
里面,MBR
第一阶段所访问的/boot/grub/
是一个基本磁盘设备,可以进行硬访问,第二个阶段是不受446
字节的大小限制的设别,可以进行硬访问;
grub
的stage2
阶段的配置文件/boot/grub/grub.conf
:default=0
:表示默认启动第一个操作系统;timeout
:等待用户选择的超时时长splashimage=
:用于指定背景图图片;Hiddenmenu
:表示隐藏菜单;title
:表示内核标题,操作系统标题;root
:表示内核文件所在的设备,如果grub
找不到kernel
的位置,需要进入救援模式来手动探测内核所在的位置;grub
识别硬盘都是按照hd
开头,第一个为hd0
;kernel
:一行表示kernel
文件路径以及传递给内核的参数;这一行和/proc/cmdline
文件是一致的;这个knernel
是直接通过访问内核所在的分区来访问的,并不铜鼓根文件系统,因为i这时,根文件系统还没有被识别;如果没有进行单独分区,就需要使用/boot/
initrd
:表示ram disk
文件路径,是在操作系统安装的最后生成的,里面各种文件,除了内核文件之外都有;/boot
:是一个独立的分区,grub
访问内核时,文件系统还没有加载,所以直接访问磁盘上的/boot
,就不需要根来查找对应目录,也就不需要加载内核文件系统这个操作;
grub
的应用:编辑界面:在系统启动过程中,按e
进入编辑界面;a
可以用于修改内核参数;c
:可以用于进入命令行界面;b
:用于进行重新启动;- 如果需要添加
grub
密码:在title
上面添加password
,使用命令grub-MD5-crypt
:可以用于添加grub
加密后的密码,格式为password --md5
; - 如果密码文件放在了
title
下面.表示在装载内核时,需要输入密码;
- 如果需要添加
- 对于不同的操作系统来说是不同的,
BIOS
:里面设置这操作系统的顺序,一次去查找这些设备的MBR
,bootloader
查找操作系统所在的分区,并且加载内核,转载进入内存;最后kernel
获得控制权,识别文件系统,探测内核,识别关键设备;- 查看系统的运行级别:
who -r
:用于查看当前系统的运行级别;runlevel
:也是用于查看当前系统的运行级别的,前面的N
表示没有进行级别切换;
grub
的损坏和修复:- 使用命令破坏前
446
个字节,dd if/dev/zero of=/dev/sda count=1 bs=400
,建议使用虚拟机进行测试,不要再真机上面进行测试; - 使用
sync
进行同步; root(hd0,0)
硬盘等设备,通常被grub
识别为hd
开头的设备,通常MBR
位置0
分区;setup(hd0)
安装:- 或者直接使用
grub-install –root-directory=/grub
所在的位置;往其他硬盘上装载grub
; - 创建三个分区:创建一个
boot
目录,挂载一块磁盘,使用命令grub-install-root-directory=/mnt/dev/hda
; - 编辑
/mnt/boot/grub/grub.conf
- 添加:
- 使用命令破坏前
defaultlt=0
timeout=5
title Fake linux
root(hd0,0)
kernel /vmlinux
initrd /initrd.img
-
再次强调一下千万不要拿
grub.conf
开玩笑,不然系统就毁了;否则就得自己写一个;使用find (hd0,0)/
来查找内核所在的位置;首先指定root (hd0,0)
在执行kernel/vmlinux-2.6-补全文件
所在的位置;在指定initrd /initrd-2.6-补全
,然后使用boot
进行重启; -
内核初始化的过程:
- 1.设备探测;
- 2.驱动初始化,需要从
initrd
文件中装在驱动模块,redhat6
称为initramfs
- 3.以只读方式挂载根文件系统;
- 4.装载第一个进程
init
,PID
为1
的进程;
-
/sbin/init
:通常读取的文件是/etc/inittab
upstart
:一个可执行程序,速度比较快redhat6.0
以后开始使用,可以用于并行启动进程;systemd
:并行启动多个进程的init
进程,并行能力更强,但是可能不太稳定,基于事件启动;redhat5
和redhat6
上面的init
进程是不相同的,配置文件也不相同;init
都是inittaab
切割后的各种片,每一个文件都是基于事件驱动的方式来启动的;
-
redhat5
的/etc/inittab
文件:
- 三个冒号分开的四段:
ID
:表示标识符,必须与每一行都不相同;runlevel
:表示在那个级别下执行这个动作;action
:表示执行的动作,什么时候执行这个动作;sysinit
:表示系统初始化;wait
:表示级别切换到次级别时,执行一次;respawn
:一旦程序终止,会重新启动;
process
:要运行的进程程序;如果不指定级别,表示的就是所有级别;
K
开头的表示停止,S
开头的表示启动,文件里面的大多数表示的是链接文件,其实各个执行的级别后面代表的都是一个个服务或者脚本文件,然后通过一个脚本来同一控制这些脚本的执行;/etc/inittab
执行的任务:- 1.设定默认的运行级别;
- 2.运行系统的初始化脚本;
- 3.运行指定运行级别对应目录下的脚本;
- 4.设定
Ctrl+Alt+delete
组合键的操作; - 5.启动虚拟终端
(2345)
; - 6.启动图形终端(
5
级别); - 7.定义
UPS
电源在电源故障时,恢复时执行的脚本
- 三个冒号分开的四段:
-
/etc/rc.d/rc.sysinit
完成的任务:
#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.
#
HOSTNAME=$(/bin/hostname)
set -m
if [ -f /etc/sysconfig/network ]; then
. /etc/sysconfig/network
fi
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
HOSTNAME=localhost
fi
if [ ! -e /proc/mounts ]; then
mount -n -t proc /proc /proc
mount -n -t sysfs /sys /sys >/dev/null 2>&1
fi
if [ ! -d /proc/bus/usb ]; then
modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
else
mount -n -t usbfs /proc/bus/usb /proc/bus/usb
fi
#remount /dev/shm to set attributes from fstab #669700
mount -n -o remount /dev/shm >/dev/null 2>&1
#remount /proc to set attributes from fstab #984003
mount -n -o remount /proc >/dev/null 2>&1
. /etc/init.d/functions
* 1.激活`udev` 和 `selinux`;
* 2.根据`/etc/systl.conf`文件来设置内核参数;
* 3.设定时区时钟;
* 4.装载键盘映射;
* 5.启用交换分区;
* 6.设置主机名;
* 7.根文件系统检测,并且以只读方式重新挂载;
* 8.激活`RAID`设备和`LVM`设备;
* 9.启用磁盘配额;
* 10.根据`/etc/fstab`,检查并挂载其他文件系统;
* 11.清理过期的的锁和`PID`文件;
-
init
:用户空间的主导程序,用户空间的管理都由init
管理; -
内核的设计风格
-
在内核启动之前,文件系统是没有启动的,内核所在的分区是由
bootloader
来识别的,所以bootloader
需要来识别文件系统;根文件系统是访问其他目录或者文件的入口,根文件系统是自引用的,这个过程由内核完成,内核必须可以探测访问内核所在的分区,但是由于磁盘硬件的不同,这些驱动不可以全部做入内核,所以存在两种内核设计理念; -
单内核设计:把所有功能都做进内核,文件系统,进程管理等功能,逻辑上简单,但是导致内核系统十分庞大;
-
微内核设计:将上述功能做成一个子系统,驱动程序,文件系统作为子系统,一个子系统坏掉,不影响正常启动,彼此之间的协调很复杂;
-
Linux
是单内核设计支持LWP
轻量级进程,Linux
对于线程的支持并不是很好;内核代码十分庞大,按照自己的实际需要进行编译安装,Linux
同时也引入了微内核的思想;内核的设计是模块化的,有核心和其他模块组成,内核核心可以动态的加载所需要的内核模块,在/lib/modules/
里面内核版本号命名的目录/模块之间是有依赖关系,有一个文件来解决依赖;命令一般为vmlunuz-2.6.32
目录在里面有文件系统,驱动程序,加密解密程序等; -
linux
采用模块化设计,由核心模块和外为模块组成;- 内核的核心功能称为
ko
,内核核心本身很小,在需要使用的时候,如果已经完成过编译,就只需要进行加载就可以了; - 外围模块: 大多数模块都在目录
/lib/modules/内核版本号码
里面,也就是内核所需要的模块在某个设备上,而访问该设备的驱动程序也在这个设备上; - 所以需要在内核和需要访问的是设备之间添加一个程序文件,这个文件不是事先编译好的,而这个程序文件,也就是这个文件并不是事先在编译内核是就提供的,而是根据内核和
BISO
生成的相关硬件配置信息,在安装操作系统时生成的一个文件,这个设备可以成为桥接设备;- 这个设备文件提供一个独立的文件系统,用于内核来访问,这是一个伪文件系统,用于临时的根切换,同时将该文件系统的
/proc
,/sys
,/dev
,转到真正的根文件系统;
- 这个设备文件提供一个独立的文件系统,用于内核来访问,这是一个伪文件系统,用于临时的根切换,同时将该文件系统的
- 在
redhat6
的bash-shell
使用的是命令chroot
,但是在rhel5
上面使用的是nash
提供的命令switch-root
,
- 内核的核心功能称为
-
/lib/modules/内核版本号码
:
dep
:表示的都是内核依赖文件;alias
:表示的是内核别名文件;map
:表示的是内核映射关系;kernel
:
arch
:表示和平台相关的文件;crypto
:表示和加解密相关的文件;drivers
:表示和驱动相关的文件;fs
:表示和文件系统相关的文件;lib
:表示依赖的库文件;mm
:表示的是内存管理相关的文件;net
:表示网络相关的文件,通常是驱动协议,不是驱动程序;sound
:表示和声音相关的文件;
-
在
nash shell
中提供了一个switch root
来完成根切换;伪文件系统里面的文件可以讲内存中的一段空间模拟成硬盘来使用,这段空间称为ramdisk
或者ram filesystem
,使用这段空间来展开伪文件系统中的文件,内核访问根文件系统需要驱动程序和文件系统来进行访问; -
这段地址空间在
rhel5
上面称为ramdisk--->initrd
,在rhel6
上面ramfs-->initramfs
-
用户空间的命令用于实现根切换的命令是
chroot
;- 首先创建一个目录
chroot
- 然后创建
/bin/bash
,在chroot
里面的目录,也就是./bin/bash
- 使用
ldd /bin/bash
依赖的库文件,并且建立库文件的相对目录,复制库文件到对应的目录里面; - 按照上面的过程同时还可以复制一些常见的命令文件过去,在这个目录底下,就可以执行这些文件;
- 首先创建一个目录
-
bootloader
是完成kernel
和initrd
的加载的,最后将initrd
交给kernel
使用; -
Init
的功能:- 定义操作系统的运行级别:
0
:表示halt
,表示停止操作系统,但是不关闭电源;1
:single user root
表示单用户模式,直接登录管理员,不适用密码登录,使用s或者 S
或者single
都可以进入单用户模式;2
:multi user root
:表示多用户模式,启用网络功能,但是不启用NFS
等网络文件系统;3
:multi user root
:多用户模式,启用正常的系统功能,但是是文本模式;4
:reserved
:保留级别,暂时没有定义;5
:multi user root
:多用户启动图形界面;6
:reboot
:重启,如果定义为这个级别,系统会一直重新启动;
- 定义操作系统的运行级别:
-
/etc/rc.d/rc.sysinit
文件的内容:Si::sysinit:/etc/rc.d/rc.sysinit
.完成OS
的初始化,里面对应的K
开头的文件和S
开头的文件,都是按照级别等级需要执行的,这些脚本都是Linux
执行的服务脚本,对于这些脚本至少需要接受四个参数:start stop restart status
,以及reload configtest
;- 脚本的规范:
- 服务脚本都有相同意义的两行
chkconfig
:用来定义定义这个脚本来创建一个链接,三组数字分别表示为:- 启动的运行级别:也就是这些程序在哪些运行级别下面运行;
SS
启动的优先顺序:表示相对于其他应用程序的启动优先级;KK
关闭的优先顺序:表示相对于其他应用程序的关闭优先级别;description
:这个脚本文件完成的工作的一个大致的介绍;
- 服务脚本都有相同意义的两行
- 当
chkconfig
命令为此脚本来创建链接时,runlevels
表示创建默认为S
开头的连接,除此之外的级别默认创建为K
开头的链接;S
后面的启动优先级为SS
所表示的数字,K
后面关闭优先顺序为KK
所代表的数字;runlevel
后面可以为–
表示默认没有开头为S
的链接; chkconfig
命令:--list
:用于列出所有独立守护进程的启动设定,可以使用chkconfig –list SERVICE_NAME
查看某个具体的服务;--add SERVICE_NAME
:用于自动创建服务脚本所使用的链接;--del SERVICE_NAME
:用于删除服务的链接文件;--level runlecvels SERVICE_NAME {on | off}
:用于指定在那个级别开启或者关闭,如果省略级别指定默认为2345
级别;
/etc/rc.d/rc.local
文件,本质上是一个链接文件- 系统最后执行的一个脚本,可以用于自定义一些自己需要的服务,不方便写成脚本的
服务,感觉很有用;
- 系统最后执行的一个脚本,可以用于自定义一些自己需要的服务,不方便写成脚本的
-
使用
chkconfig
管理的服务通常称为独立守护服务,就是自己来管理自己应该在那些级别下面启动,在那些情况下开启; -
守护进程类型
-
独立守护进程:服务的关闭启动等是自己进行管理,这种类型的进程适合于长时在线的服务;
-
瞬时守护进程:不需要关联至运行级别;由
xinetd
来负责进行管理,xinetd
也称为超级守护进程,但是超级守护进程xinetd
是需要关联至运行级别的,超级守护进程是记录自己守护的瞬时守护进程是按需进行开启的,当需要访问时,xinetd
通知相关的瞬时守护进程,完成服务后,瞬时守护进程就会关闭;