Liunx内核组成
操作系统内核分两种:
- 微内核
- 单内核
其中linux是单内核设计,而windows和solaris则是微内核设计,总的来说微内核设计优于单内核设计,但是linux的单内核设计有充分的吸取了微内核设计的理念,linux内核支持内核模块化动态装载或卸载,这样就可以根据实际需求动态加载内核模块(kernel object),这样也就使得linux内核可以做到很小,也为嵌入式提供了内核支持。
整个内核的组成部分:
- 核心文件:/boot/vmlinuz-{kernel_version}-release
- ramdisk: 存在真正根的驱动,挂载真正根,并非必须,但前提是内核得编译进文件系统的系统驱动,但是redhat系列默认不编译进内核
–- centos5: /boot/initrd-VERSION-release.img
–- centos6,7: /boot/initramfs-VERSION-release.img - 内核模块文件:/lib/modules/VERSION-release
至于为什么在centos5和centos6,7的ramdisk不同,那是因为centos5把ramdisk当作磁盘使用,我们知道linux存在虚拟内存的说法,为了能够平衡ram和disk的速率差异,linux内存管理中常常存在buffer/cache的方式来管理内存,centos5把ramdisk当成disk,那就需要buffer和cache,而这本身就是把内存当成磁盘的使用方式,所以就会产生双buffer/cache的现象,这是资源的浪费。而centos6,7就修改了这种设置,把ramdisk当成文件系统,这样就不存在这样的资源的浪费。
内核空间启动流程
系统初始化流程(内核级别)
POST–>BootSequence(BIOS)–>BootLoader(MBR)–>kernel(ramdisk)–>rootfs(read only)–>/sbin/init
POST加电自检
POST加电自检是微机一种硬件检测机制,完整的POST自检包括对CPU、系统主板、基本的640KB内存、1MB以上的扩展内存、系统ROM BIOS的测试;CMOS中系统配置的校验;初始化视频控制器,测试视频内存、检验视频信号和同步信号,对CRT接口进行测试;对键盘、软驱、硬盘及CD-ROM子系统作检查;对并行口(打印机)和串行口(RS232)进行检查。自检中如发现有错误,将按两种情况处理:对于严重故障(致命性故障)则停机,此时由于各种初始化操作还没完成,不能给出任何提示或信号;对于非严重故障则给出提示或声音报警信号,等待用户处理。
BootSeqence
BootSeqence 是启动顺序,通常通过设置写在ROM上的BIOS(Basic Input and Output System) 来设置启动项。
Bootloader
Bootloader 引导加载器,这是一端写在程序,最传统也是应用的最广泛的就是MBR,MBR共512bytes,其中446bytes作为bootloader,64bytes作为分区表,2bytes (55AA)表示有效,其中bootloader分为多种:
- windowns系统的为ntloader
- linux系统有两种bootloader:
–- LILO: Linux Loader,这是最早出现的bootloader,本身已渐渐被淘汰,它无法引导1024柱面后的分区,但是随着安卓机子的出现,它慢慢迎来了第二春,大部分安卓机的bootloader都是LILO.
–- GRUB: Grand Uniform Bootloader,目前主流的Linux系统的bootloader。
我们主要解释下GRUB Bootloader:
- stage 1: stage 1 存在MBR上的bootloader上,主要是为了stage 2做准备。
- stage 1.5: 在MBR随后的分区存放,主要用于与stage2所在的文件系统进行交互
- satge 2: 通过Boot Loader加载所有配置文件及其相关的参数信息,存放grub引导程序,并读取/boot/grub/grub.conf,引导kernel运行。
kernel(ramdisk)
我们需要知道的一件就是内核存在/boot下,我们需要加载/boot需要加载这个文件系统的驱动,但是驱动在文件系统上,这是一个死循环,这时就需要一个独立的存在我们需要文件系统的驱动的ramdisk的小系统运行,它来挂载真正的根文件系统,来加载真正的内核,加载完成易主给真正的内核,让内核真正接管起整个系统。但我们也知道,如果内核本身就存在这个文件系统的驱动,那内核本身就可以访问文件系统,就不需要ramdisk的参与,但是文件系统不止一种,这样会使内核异常臃肿。
rootfs(read only)
以自读的方式挂载根文件系统,结下来会在用户空间初始化中重新挂载根文件系统。
/sbin/init
这是1号进程,从这里开始就转入了用户空间初始化过程,内核也退出了整个引导过程,只有当需要使用特权命令的时候才会需要内核操作,接下来的都是init的天下了。
用户空间初始化流程
以最经典的centos5为例,centos6,7都采用不同的方式完成了centos5做的用户空间初始化的工作。
1 | ###表示当前缺省运行级别为3(initdefault); |
2 | id:3:initdefault: |
3 | |
4 | ###启动时自动执行/etc/rc.d/rc.sysinit脚本(sysinit) |
5 | # System initialization. |
6 | si::sysinit:/etc/rc.d/rc.sysinit |
7 | |
8 | l0:0:wait:/etc/rc.d/rc 0 |
9 | l1:1:wait:/etc/rc.d/rc 1 |
10 | l2:2:wait:/etc/rc.d/rc 2 |
11 | l3:3:wait:/etc/rc.d/rc 3 |
12 | l4:4:wait:/etc/rc.d/rc 4 |
13 | l5:5:wait:/etc/rc.d/rc 5 |
14 | l6:6:wait:/etc/rc.d/rc 6 |
15 | |
16 | |
17 | ###在2、3、4、5级别上以ttyX为参数执行/sbin/mingetty程序,打开ttyX终端用于用户登录,如果进程退出则再次运行mingetty程序(respawn) |
18 | # Run gettys in standard runlevels |
19 | 1:2345:respawn:/sbin/mingetty tty1 |
20 | 2:2345:respawn:/sbin/mingetty tty2 |
21 | 3:2345:respawn:/sbin/mingetty tty3 |
22 | 4:2345:respawn:/sbin/mingetty tty4 |
23 | 5:2345:respawn:/sbin/mingetty tty5 |
24 | 6:2345:respawn:/sbin/mingetty tty6 |
这是最经典的SysV风格:
整个配置文件以 id:runlevels:action:process
格式设置
- id:一个任务的标识符
- runlevel: 在哪个级别启动此文件
- action:在什么条件下启动此任务
- process:任务
runlevel:
- 0: 关机
- 1: 但用户模式,也称维护模式
- 2: 多用户模式,会启动网络功能,但不启动nfs,维护模式
- 3: 多用户模式,完整功能,文本界面
- 4: 预留模式
- 5: 多用户模式,图形化界面
- 6: 重启,reboot
action:
- wait:等待切换至此任务所在的级别时执行一次
- respawn: 一旦此任务终止,就自动重新启动
- initdefault: 设定默认运行级别,此时process就省略
- sysinit:设定系统初始化方式,此处一般指定/etc/rc.d/rc.sysinit脚本
/etc/rc.d/rc.sysini完成的任务:
-(1)设置主机名
-(2)设置欢迎信息
-(3)激活udev和selinux
-(4)挂载/etc/fstab文件中定义的所有文件系统
-(5)检查根文件系统,并以读写方式重写方式挂载根文件系统
-(6)设置系统时钟
-(7)根据/etc/sysctl.conf文件来设置内核参数
-(8)激活lvm及软raid设备
-(9)激活swap设备
-(10)加载额外设备的驱动程序
-(11)清理流程
/etc/rc.d/rc 0
…
/etc/rc.d/rc 6
意味着去启动或关闭/etc/rc.d/rc#.d目录下的服务脚本所控制服务
- K*:要停止的服务:K##,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的
- S*:要启动的服务:S##,优先级,数字越小,越是优先启动;被依赖的服务先启动,而后启动依赖的服务
/usr/sbin/mingetty tty1
…
/usr/sbin/mingetty tty6
这里控制着共可以启动多少个虚拟终端
- (1)mingetty会调用login程序
- (2)打开虚拟终端的程序了mingetty,还有诸如getty等
总结
设置默认运行级别–>运行系统初始化脚本,完成系统初始化–>关闭对应级别下需要关闭的服务–>开启对应级别下需要启动的服务->设置登录终端[–>启动图形化终端]
附加:
centos6:
init程序:upstart 但还是被命名为/sbin/init
/etc/init/*conf,/etc/inittab(仅用于定义默认运行级别)
centos7:
init程序:systemd
/usr/lib/systemd/system/,/etc/systemd/system/
这两种都是全新的启动体系,但都必须完成centos5 inittab中定义的任务。