linux基础笔记-8-系统启动流程

15.系统启动流程

  1. POST(power on self testing)
  2. BIOS(boot sequence)
  3. MBR(bootloader,446B)
  4. kernel(ko)
  5. initrd
  6. /sbin/init(rootfs),执行/etc/inittab中的服务。

学习磁盘及文件系统时说过,bootloader可以识别磁盘中的内核分区。
Linux内核启动的下一过程是启动第一个进程init(管理用户空间进程),但必须以根文件系统为载体,所以在启动init之前,还要挂载根文件系统。
根能够自识别。

回忆根文件系统必需的5个目录。

BootLoader

不同os的bootloader是不一样的,它由os安装程序提供,但mbr是不属于任何os的,是硬盘级别的。
win8后,mbr被微软锁定,不能引导其它os,其它os也不能引导windows,导致不能兼容其它系统。

linux的bootloader是很开放的,常用的有2种:
LILO(LInux LOader),不能引导1024柱面以后分区的内核,所以不支持大硬盘(一般8G),一般用在嵌入式里。

另一种是grub(GRand Unified Bootloader)。

Grub

两段式,或者三段式。有两个版本,grub2更新更广泛。这里以grub1为例。

  1. stage1:位于mbr中,目的是引导第2阶段,而不是引导os。代码很小,文件通常被叫做引导镜像(boot.img)。
  2. stage1.5:识别文件系统,文件名为/boot/grubFSNAME1_5。
  3. stage 2:定位和加载 Linux 内核(vmlinuz)到内存中,并转移控制权到内核。

第2阶段有配置文件/boot/grub/grub.conf,定义了可以引导哪些os和kernel,还可以选择要加载的图片。

rpm -q grub可查询信息。

/etc/grub.conf是个链接,指向/boot/grub/grub.conf.

cat /etc/grub.conf

default:设定默认os或kernel编号
timeout:等待用户选择的超时时间
splashimage:grub背景图片,格式为.xpm.gz,可以用作图软件gimp制作。
hiddenmenu:隐藏菜单,没有该字段则不隐藏。
password指定编辑密码

grub-md5-crypt命令直接生成密码,添加:
password --md5 CYPHER

每个title指定一个os或kernel

  • root一行记录内核文件所在设备,对grub而言硬盘类型全是hd,后跟第几个盘,第几个分区。
  • kernel一行指定内核文件路径以及传递参数,参数可执行cat /proc/cmdline查看
  • initrd一行记录ramdisk文件路径,里面是完整的linux系统,大小几m。

注意,/boot是单独分区的,但title的kernel和initrd两行路径并没有/boot,而是直接/vmlinuz,因为是通过grub直接访问的,而不是通过文件系统。

#模拟修复grub
fdisk -l # 找到系统盘sda的boot分区/dev/sda1
dd if=/dev/zero of=/dev/sda bs=446 count=1 #破坏bootloader
sync
#此时已经无法重启

# 第一种方式
#执行grub进入新的交互界面
grub
# 安装stage1
grub> root (hd0,0)
grub> setup (hd0)  #安装grub
grub> quit
shutdown -r now  #重启

#第二种方式
grub-install --root-directory=/ /dev/sda
# grub.conf的信息可能和命令不一致,比如系统盘
#练习  给其他硬盘装上grub
# 分3个区(内核,根,swap)
partprobe /dev/sda
mke2fs -j /dev/sda1
mke2fs -j /dev/sda2
mkswap /dev/sda3
# 把/mnt作为根
mkdir /mnt/boot
mount /dev/sda2 /mnt/boot
grub--install --root-directory=/mnt /dev/sda
# 这样就会自动创建/mnt/boot/grub/device.map
vim /mnt/boot/grub/grub.conf
# 现在,提供内核、initrd、init就可以启动了。
# 把grub.conf mv到别处模拟损坏的情况
shutdown -r now
# 会出现grub提示符
grub> find (hd0,0)/  #挨个寻找内核文件vmlinuz在哪,根据possible files判断,若是则执行root (hd0,0)。
grub> root (hd0,0)
grub> kernel /vmlinuz  # 若知道根可以附上root=...
grub> initrd /initrd-*.img
grub> boot   #尝试找根

内核

内核设计风格:

  • 单内核:所有功能做进内核,实现简单,目前向微内核靠拢。线程被称作轻量级进程(lwp);核心叫做kernel object(KO),支持动态加载模块。
  • 微内核:外围功能做成子系统,要求耦合度低,更安全,但实现复杂导致优势不明显。

linux属于单内核,windows、solaris属于微内核。
微内核才真正意义上支持多线程

linux支持20种内核架构,如arm。

查看内核:uname -r

内核的模块机制

系统启动时只是启动内核的核心,它很小,可以动态加载内核模块(KO),又称动态可加载内核模块(Loadable Kernel Module,LKM),KO位于/lib/modules,该目录下有内核版本号命名的目录,里面的模块都很大。
目录里的net是协议栈,/drivers/net才是网卡驱动。

lsmod命令,列出模块。

vmlinuz

/boot/vmlinuz是压缩的,可引导的、可执行的Linux内核,它一般是一个软链接。

du -sh /boot/vmlinuz*会显示大小只有几m。

内核初始化过程

  1. 设备检测
  2. 驱动初始化,可能从initrd文件中装载驱动模块。
  3. 以只读方式挂载根文件系统
  4. 装载第一个进程init

initrd

内核访问根,需要设备驱动设备文件系统
启动时,kernel不具备这两个条件,不能直接访问init,所以用到如下机制:
初始化时内核访问文件系统用到了根切换,其下有/proc,/sys,/dev,然后才能装载真正的文件系统。这里的中间层次是个文件,能把一块内存模拟为硬盘来用。这个文件叫做ramdisk或者ramfs。

可以把initrd理解为一个带有根文件系统的虚拟磁盘。
红帽5:ramdisk,文件名为initrd(initial ramdisk)。
红帽6:ramfs,文件名为initramfs

initrd装载进内存后,内核挂载真正的根文件系统,然后将此initrd从内存中卸掉。所以说initrd起到过渡的作用。

注意,initrd一定是和kernel位于同一分区,与kernel同时被bootloader装载,然后kernel借助它找到rootfs,进而找到/sbin/init


init

# 根切换
#chroot命令,把一个目录临时作为根。其下需要有/bin/bash
mkdir -pv /testroot/bin
cp /bin/bash /testroot/bin/
ldd /bin/bash     #  显示依赖库
mkdir -pv /testroot/lib
# 将依赖库依次cp进/testroot/lib
tree /testroot    #  查看
chroot /testroot  #  这样就完成了根切换

#  红帽5有一种shell叫做nash,提供命令switch_root

运行级别

windows有安全模式,linux有运行级别,不同模式/级别启动的服务不同。

linux运行级别:0-6

  • 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

/etc/inittab记录了默认运行级别,init会读取。

查看运行级别

  • runlevel命令显示运行级别,输出上一个级别和当前级别。
  • who -r也能显示运行级别

inittab

/sbin/init,读取配置文件/etc/inittab;它是串行启动服务的。

init并不是只有一种。红帽6以后使用upstart,是另一种init,由ubuntu开发,可以并行启动一些进程。
进程间通信基于d-bus,是事件驱动(event-driven)的。
另一种更好的是systemd(红帽6.2),实现了完整意义上并行启动多个进程,但不太稳定,6.3以后又换回upstart。

红帽6的/etc/init包含inittab拆分后的文件。而/etc/init.d是脚本目录。

man inittab可以查看字段意义

id:runlevel:action:process
runlevel为空则表示所有级别

action:在什么情况下执行此行
initdefault:设定默认运行级别
sysinit:系统初始化,会执行/etc/rc.d/rc.sysinit脚本,该脚本至关重要。
rc:run cmd
wait:等待级别切换完成
ctrlaltdel:关机
powerfail:停电
powerwaitok:电源恢复
respawn:一旦程序终止,重新启动。

inittab中的这一行用于系统初始化
si::sysinit:/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/fatab检查并挂载其它fs
11.清理过期的锁和pid文件

对于/etc/rc#.d/下的文件,rc.sysinit先关闭K*服务,再启动S*服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值