linux-x86-发行版一般启动顺序
一般linuxPC发行版都经历了BIOS,MBR,BootLoader,内核,一系列过程,下面说的就是这个过程
针对嵌入式设备启动请参考嵌入式启动顺序
为什么强调PC发行版呢?因为现在有专门为arm做的linux发行版问世了
PC一般用的是intel 或者amd 处理器,架构一般为 x86 或者 x86_64
按电源键
性质:
硬件
功能:
这时候会在处理器上的reset引脚上产生一个高电平信号?
然后 处理器就开始工作
设置 pc 寄存器 为 固定的值 ,0XFFFF0,这是 BIOS所在的起始位置
然后 下一步就开始执行 BIOS
问题:
不过既然有电信号,供电哪里来的?
处理器在按电源键之前就一直被供电吗?
1/BIOS
性质:
代码
非易失性存储器位置:
BIOS是一组固化到计算机主板上rom芯片的程序,但是现在都不用ROM了,用的都是EEPROM
易失性存储器位置:
0XFFFF0 // 这个地址 对应的是什么设备??? // 应该不是内存条吧,应该是x86芯片中自带的iram?
功能:
BIOS在启动的时候会读取CMOS里面的内容,了解硬件信息(如启动设备的顺序)
做开机自检(如确定时钟速度)
初始化硬件(如设定即插即用设备)
读 第一个启动设备的 Boot Sector ,并验证BRID是否为0X55AA,如果不是,则下一个,如果是,则控制权移交MBR
读 第二个启动设备的 Boot Sector ,并验证BRID是否为0X55AA,如果不是,则下一个,如果是,则控制权移交MBR
...
读 第N个启动设备的 Boot Sector ,并验证BRID是否为0X55AA,如果不是,则启动失败,如果是,则控制权移交MBR
其他:
BIOS升级就是重新刷写EEPROM
BIOS在整个计算机只有一个,对应一台电脑上的多个硬盘硬盘
CMOS是一块RAM芯片,但是一直被纽扣电池供电,所以一直不掉数据
CMOS里面设置了BIOS读取启动设备的顺序,时间,等其他内容.
2/MBR
每个启动设备的 第一个扇区(512字节) 被称为Boot Sector
而每个合格的启动设备 的 Boot Sector 都会包括且初始化为三部分
MBR(446字节) DPT(64字节) BRID(2字节)
而 我们说的 MBR 就是 Boot Sector 的一部分
性质:
代码
非易失性存储器位置:
启动设备的 Boot Sector 的 前446字节
易失性存储器位置:
不清楚 // 内存条
功能:
1. 提供菜单(转交哪个BootLoader控制或者加载内核)
2. 转交其他BootLoader
其他:
MBR在每个系统磁盘会有一个,对应一个磁盘上的多个系统分区
如果磁盘A和B上都有MBR,且引导不同的系统,那么我们让其从不同的MBR启动,是通过修改 Boot Sector 中的 BRID
哪个盘里面的 BRID 为 0X55AA,从哪里的 MBR 启动
MBR也能加载内核吗?不清楚,待确认
注意: 这个 第一扇区的 MBR 可以被 (GRUB 的 stage1) (GRUB2 的 boot.img) 取代
且取代 MBR的部分可以放到其他活动分区的第一扇区
3/BootLoader
性质:
代码,有很多实现, LILO GRUB GRUB2 等
// x86 这个启动流程中的 bootloader 目前(2020-5-17 21:42:52)一般选用 grub2
非易失性存储器位置:
不清楚 // 在硬盘或者U盘上 , 应该是被放到了 根文件系统中的 /boot 目录
易失性存储器位置:
不清楚 // 内存条
功能:
加载内核或其他的bootloader
其他:
GRUB2可以识别文件系统 /识别 下面/dev/sda1分区中的 顶层目录下的 grub2/grub.cfg
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
并根据启动文件的内容来执行命令
1. 选择不同的 menuentry
2. 执行menuentry 下的命令 insmod linux16 initrd16
GRUB的启动可以配置,配置文件中可以通过 (内核启动成功后的根文件系统中查看,在 /boot/grub2/grub.cfg)
/etc/grub2.cfg -> ../boot/grub2/grub.cfg
如果该阶段为grub2,则阶段2MBR中的内容也是grub2的一部分,该阶段及阶段2的内容可以在linux发行版启动之后在shell命令行下做修改.
[root@centos77 grub2]# find . -name "*.img" | xargs ls -l
-rw-r--r--. 1 root root 512 Jan 16 17:06 ./i386-pc/boot.img
-rw-r--r--. 1 root root 26703 Jan 16 17:06 ./i386-pc/core.img
[root@centos77 grub2]# find . -name "*.img" | xargs file
./i386-pc/core.img: data
./i386-pc/boot.img: x86 boot sector; partition 4: ID=0xd4, starthead 205, startsector 4277266767, 0 sectors, code offset 0x63
[root@centos77 grub2]# pwd
/boot/grub2
4/内核
性质:
代码
非易失性存储器位置:
/boot/vmlinuz
易失性存储器位置:
不清楚
功能:
//之前BootLoader已经成功加载内核和initrd,并将控制权交给内核的第一条指令
1/内核自解压 // 自解压代码并没有被压缩.且自解压代码在vmlinuz 镜像的头部
2/内核运行检测硬件
3/内核挂载initrd到rootfs
4/执行initrd虚拟根文件系统的init
4.1/加载驱动,/lib/modules/下的驱动文件(包括USB/RAID/LVM/SCSI)
4.2/挂载实际的根文件系统(硬盘上的文件系统,一般是ext3格式)
4.3/卸载虚拟根文件系统(initrd)
5/执行/sbin/init(init执行的时候会读取配置文件/etc/inittab 和 /etc/profile)
5.1 获取runlevel信息
5.2/执行/etc/rc.d/rc.sysinit
5.3/执行runlevel对应的服务
5.4/执行/etc/rc.d/rc.local
5.5/启动login进程
5.6/根据level,来是否执行xwindow
问题:
启动图形界面的时候,我们可以看到是有提示符 login 的 ,但是当时并没有启动login进程,当时有提示login 的进程为 getatty等类似进程
然后一闪而过,开始启动图形界面,getatty进程exec 了 图形界面 进程
init 程序 在文件系统中,不是内核的一部分
init内核线程挂载文件系统成功,然后do_execve(/sbin/init) ,开始执行 /sbin/init,就已经将控制权转移到了/sbin/init.
当然,内核还是在跑着的,体现在
1.内核线程
2.用户进程执行软件中断后陷入内核后,执行内核代码
3.中断处理
所以 linux 是一直在 内核 和 用户应用程序 控制权的交换中运行的
但是 综合来说, linux 设计的原则 是 master-salve 模式,所以 内核 和 用户应用程序是不平等的,在特权级上
- 到此,已经启动完成
- 目前展示的内核启动过程是 存在 initrd 时的启动过程,
- 内核不要initrd的参与也可以正常启动
- 下面讲述的是之前的过程中提到的概念
initrd简介
性质:
文件系统文件
非易失性存储器位置:
/boot/initrd.img-3.5.0-23-generic
易失性存储器位置:
不清楚
功能:
在 boot loader 配置了 initrd 的情况下,内核启动被分成了两个阶段,
第一阶段挂载 initrd,并执行 initrd 文件系统中的"某个文件",完成加载驱动模块等任务,加载根文件系统
第二阶段才会执行真正的根文件系统中的 /sbin/init 进程。
第一阶段启动的目的是为第二阶段的启动扫清一切障碍
最主要的是加载根文件系统存储介质的驱动模块。
我们知道根文件系统可以存储在包括IDE、SCSI、USB在内的多种介质上,但是访问这些东西要驱动,可是驱动在这些东西上,所以就构成了一个悖论.
问题:
挂载了 initrd ,完成 initrd相关的 驱动加载之后,什么时候卸载的 initrd.还是没卸载
问题
文件系统是指令运行的基本环境吗?
不是,像自解压程序,直接操作了硬件,但是,往后的操作没有直接操作硬件,而是通过文件系统调用了驱动,然后操作了硬件.
另外,你可以参考 github 上的一个工程, mykernel , 就没有挂载文件系统,但是一直都在运行
参考文档
鸟哥的Linux私房菜-基础篇
Linux 初始 RAM 磁盘(initrd)概述
EFI/UEFI BIOS 入门 : All For Beginners
UEFI和Legacy及UEFI+Legacy启动的区别