您的位置:首页 > 运维架构 > 网站架构

《深入Linux内核架构与底层原理》读书笔记二——Linux系统启动的知识

2018-02-17 00:03 302 查看
1、固件1.1 Legacy BIOS即传统的BIOS,使用16位编码,寻址能力因此受限。此BIOS下的设备驱动执行方式是使用中断向量和固定大小的中断服务空间,典型的一个中断服务只能使用128KB的空间,即驱动大小不能超过128KB。使用16位的汇编代码编写驱动。1.2 EFI BIOS由INTEL主推的新一代BIOS固件,使用C实现,寻址能力扩展到了32位,甚至64位。有以下特点:EFI BIOS上的设备驱动既不是由汇编写的,也不是使用C写的,而是使用的EFI虚拟指令集,最大的好处是实现了驱动程序的CPU无关性。
同样的EFI驱动程序不需要重新编译就可以复用在不同的CPU平台上。
EFI只是系统启动前的一个过渡阶段,在完成自己的任务后,会将主动权交给真正的操作系统,自身的大部分功能则会停止运行。
1.3 UEFI由包括INTEL在内的很多公司共同发起的一个项目,在EFI的基础上提供了图形化的操作界面。2、磁盘分区管理2.1 ROM与BootloaderBIOS固件存放于ROM中,开机后会自动执行。
Bootloader存放于磁盘上,在执行前需要先进行加载。
2.2 MBR磁盘分区技术当BIOS固件发现一个磁盘时,会检查自己是不是拥有该磁盘的驱动,有的话就具备了读写该磁盘的能力,会读取磁盘的分区情况。MBR磁盘分区方案,磁盘的前512字节存储了一些启动代码和整个磁盘的分区表。受限于空间,仅支持4个分区。为突破该限制,又发展出主分区、逻辑分区的技术。MBR信息存储于磁盘的LBA0,即逻辑块0 。获取或备份MBR分区数据的方法:dd if=/dev/sda of=mbr.bin bs=512 count=1
2.3 GPT磁盘分区技术GPT头信息存储于磁盘的LBA1,出于兼容考虑,跳过了LBA0。64位系统使用16384字节的GPT分区表(占用32扇区)。GPT分区则从34号扇区开始使用。
3、Bootloader和内核二进制文件3.1 BootloaderBootloader是BIOS启动后首先执行的磁盘程序,负责加载真正的操作系统,其职责包括:为内核传递参数
管理多个操作系统的启动
查看基本的硬件信息
识别分区
操作磁盘
以及更多其他功能
目前最常见的Bootloader是GRUB2. 一个典型的使用GRUB2启动Linux系统的过程如下:grub> set root=(hd0,1)grub> linux /boot/vmlinuz-4.4.0-63-generic root=/dev/sda1grub> initrd /boot/initrd.img-4.4.0-63-genericgrub> boot
3.2 内核二进制文件内核的核心文件是vmlinuz,是一个支持自解压的压缩文件。除内核文件外,还需要模块文件,各个模块之间存在依赖关系。一个功能可以选择编译进内核二进制文件,也可以选择编译成模块或者选择不编译。
4、Linux的启动原理一个Linux系统永远由Bootloader、Kernel、文件系统这三个元素组成。其中文件系统一般要有两个,一个是initrd,另一个是实际运行的根文件系统。4.1 initrd或initamfs文件系统initrd与initramfs本质上是一样的,仅是因为打包方式不同。前者直接使用gzip压缩,后者是使用cpio。
作为使用cpio打包的initramfs文件系统,修改一个cpio文件的方式是解压、修改,再压缩,然后就又可以作为一个文件系统使用了。
Linux提供了一个lsinitrd命令,可以直接查看initrd(initramfs)里的内容。

initrd是一个过渡文件系统,其存在的目的就是挂载真正的根文件系统。Linux内核启动的initrd里的第一个程序是:initinitrd init程序是一个脚本文件,其执行的任务流程大概如下图所示:
1建立一个sysroot根目录。用于挂载后面真实的根文件系统。
2设置命令的环境变量。
3mount proc文件系统到/proc,这是内核动态状态的一个表现和设置的入口。
4mount sysfs到/sys,这是内核资源的有组织的表现和设置入口。
5mount devtmpfs到/dev,这是临时表征当前设备节点的文件系统,可以加速系统的启动
6准备/dev目录中的一些节点,如stdin,stdout,stderr
7提供为内核输入额外参数的机会
8解析内核参数并执行
9启动systemd-udevd,并配置其要响应的行为。
10循环处理$hookdir/initqueue下的任务。
11mount根文件系统。
12找到根文件系统的init程序。
13停止systemd-udevd服务程序。
14做一些清理操作。
15切换到根文件系统的init程序,启动完成。
4.2 EFI启动桩这是EFI在启动系统方面的一个尝试,其在压缩后的Linux内核的前面加上了一段可执行程序,以替代原Bootloader的工作。不过因为目前该功能比较弱,暂时还不具备生产环境使用的条件。
4.3 启动管理程序系统第一个启动的进程是init进程,确切地讲,是在系统启动过程中内核中的init进程被用户空间的init进程远的执行。在init执行完操作后,一般会调用初始化系统脚本来初始化整个系统的应用程序或服务器。Sys V init:runlevel这是一套最早得到广泛使用的服务启动组织管理程序。针对网络服务:xinetdxinetd默认会管理监听系统所有的端口。当某个端口有请求到达时,启动对应的端口处理服务进程。缺点是在服务首次启动时,响应比较慢,其次是在管理已经启动了的服务时也没有一个好的管理策略。upstart为克服init的同步顺序启动带来的效率低下问题,upstart实现了异步事件驱动的启动模式,在某些模式下提高了系统的启动速度。由于另一个技术systemd的迅速发展,upstart基本已经被其淘汰。systemd由于其质量优秀、功能丰富,基本上已经取代了init和upstart,systemd将启动过程尽可能地并行化,并且将很多原来由shell执行的逻辑移到了systemd程序中来,提高执行速度。
目前systemd除了管理启动过程,还对用户端封闭了几乎所有的系统服务。
systemd是系统的第一个启动过程,也是最后一个关闭的进程,它是所有用户进程的根进程。
systemd定义了一整套脚本语义。每个要启动的进程服务都要定义一个unit文件。systemd提供了service,socket,device,mount,automount,swap,target,path,timer,snapshot,slice和scope共12种语义用于启动信息的定义和管理。
systemd定义了一个target的概念,代表一群unit的集合,相当于是一组需要启动的进程。
systemd是守护进程;systemctl用来定义systemd的服务和行为;systemd-analyze用来分析启动的效率。
systemd完全使用内核的cgroup接口进行开发的。
CentOS7系统中默认使用的systemd服务有以下5个:
# ps -ef|grep systemdroot         1     0  0 20:48 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 21root       457     1  0 20:48 ?        00:00:00 /usr/lib/systemd/systemd-journaldroot       484     1  0 20:48 ?        00:00:00 /usr/lib/systemd/systemd-udevdroot       598     1  0 20:48 ?        00:00:00 /usr/lib/systemd/systemd-loginddbus       601     1  0 20:48 ?        00:00:00 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
4.4 Linux内核启动顺序(1)Bootloader将内核加载到内存后,将控制权交给内核。内核是自解压的,解压完成后,会将内核文件搬运至其最终执行的位置。(2)执行CPU ID检查、machine ID检查、创建初始化页表、设置C语言代码运行环境、跳转到内核第一个真正的C函数startkernel开始执行。(3)先用大内核锁锁住内核,保证独占,然后调用平台相关的初始化操作,完成内核启动后使用的内存初始化、页表结构、MMU、中断、内存区域、计时器、Slab、VFS等。最后跳转到init内核进程。(4)内核的init进程将自身替换为用户端的init进程进行执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: