Linux 启动过程
Linux启主要分为6个阶段:
- BIOS自检
- 内核的引导
- 运行init
- 初始化系统
- 建立终端
- 用户登录系统
BIOS自检
计算机在连接电源后,CPU立即开始工作,执行被厂商刻在ROM里面的BIOS(基本输入输出系统,Basic Input Output System)。 此时CPU处于实模式,
实模式:CPU处于ring0特权,可以执行所有指令,操作硬件。 寄存器的位数是16位,然后地址线是20位,CPU的寻址空间是2^20,也就是1MB,即使是更先进的CPU,支持64位寄存器或者超过20根的地址线,同样只能使用寄存器中的16位和其中的20根地址线。详情可以参考这篇文章
当CPU通电后,会做一些重置操作,讲DS寄存器赋值为0X FFFF , IP寄存器为 0X 0000,所以访问地址就对应着 0X FFFF0,地址0X FFFF0对应的空间 处于ROM的空间中,也就是开始执行BIOS程序。 上述图片是BIOS时期的CPU地址空间的映射布局。 重置完成后,BIOS进入BootLoader阶段
内核引导(BootLoader阶段)
在BootLoader阶段,系统会加载系统,BIOS会启动一个就被称为 boot loader的开机管理程序.(PS:每个操作系统都会安装一套boot loader到它自己的文件系统中。)
-
检测存储设备的第一个扇区是不是以0xAA55结尾的, 如果是以0xAA55结尾就说明这是一个操作系统的启动区。我们都知道一个扇区的大小一般是512字节,一个操作系统编译后的代码一般都是好几百MB,第一个扇区是无法装下操作系统所有的代码的,所以只会将操作系统的启动代码存储到第一个扇区内,这个扇区也叫做引导扇区,存储的内容叫做boot.img。 -
加载内核 GRUB和LILO都是常见的用于加载内核的引导加载程序。引导加载程序用于引导操作系统启动。当机器引导它的操作系统时,BIOS会读取引导介质上最前面的512字节(主引导记录)。在单一的MBR中只能存储一个操作系统的引导记录,所以当需要多个操作系统时就会出现问题,需要更灵活的引导加载程序。但是GRUB的功能更加强大一些,所以大部分系统使用的是GRUB,现如今GRUB也迭代到GRUB2了。所以本文主要针对GRUB2进行讲解
GNU GRUB(简称“GRUB”),前生为Grand Unified Bootloader,是一个来自GNU项目的启动引导程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。多个系统的相关配置信息被写入到了一个配置文件grub.cfg 中,包括系统的版本、系统镜像的位置等信息。
GRUB2的程序主要包括 boot.img和core.img。没错,这里的boot.img就是有之前的BIOS引导进来的,而core.img将会被boot.img加载进来。在core.img中又有许多部分,其中最先被加载的叫disk.img**,disk.img用来加载core.img中的其他模块,比如lzma_decompress.img、kernel.img等,这里的kernel是指grub2的内核,而不是操作系统的。 disk.img 加载lzma_decompress.img,lzma_decompress.img会对kernel.img进行解压,实模式的支持的内容空间不到1MB,而kernel.img*占的内存比较大,所以要从实模式切换到保护模式。
保护模式的做法: 1. 打开Gate20地址线,CPU可以使用其他的地址线了,意味着更大的寻址空间 2. 打开分段和分页,之前访问方式是不安全的,一个进程可以访问另一个进程的数据。所以引入了逻辑地址的方法,通过页表将逻辑地址转化为物理地址,而页表由操作系统内核维护,可以做到进程之间的安全隔离。
切换到保护模式后,lzma_decompress.img会执行kernel.img,开始真正的加载操作系统,kernel.img会调用grub_load_config() 方法来解析grub.cfg , 里面有一个grub_show_menu() 会让用户选择操作系统, 这前面的部分无论是Windows、Linux还是MacOS是大同小异的。
操作系统的镜像一般分为两个部分:一部分是比较小的内核文件,其中包含实模式(无权限限制,所有的段都是可以读、写和可执行的)的内核代码,启动时被加载到640KB内存边界以下;另一部分就是大块内核,被加载到低端1MB内存地址以上。这里是参考文献
运行init
init进程是内核引导过程完成时创建的第一个进程。Linux使用了init进程来对组成Linux的服务和应用程序进行初始化。init程序也有很多类型,主要与linux版本有关 Sysv:centOS 5 以前的配置,配置文件:/etc/inittab Upstart:CentOS 6 的配置,配置文件:/etc/inittab , /etc/init/*.conf Systemd:CentOS 7 的配置,配置文件: /usr/lib/systemd/system , /etc/systemd/system 。
init进程是系统所有进程的起点,init 程序首先是需要读取配置文件 /etc/inittab ,其中有对运行级别的配置 然后就是启动一些服务,这里需要讲到另外一个十分重要的知识点:运行级别
运行级别(runlevel)
所谓运行级别,简单点来说,就是指操作系统当前正在运行的功能级别。启动时,系统会根据不同运行级别分配不同的开机启动程序(服务)。
- 运行级别原理
在目录/etc/rc.d/init.d 下,有许多的服务器脚本程序,一般称为服务(service);在/etc/rc.d 下有7个名为rcN.d (N的取值为0-6)的目录,对应系统的7个运行级别;rcN.d 目录下都是一些符号链接文件,这些链接文件都指向init.d目录下的service脚本文件,这些链接文件的命名规则为K+nn+服务名或S+nn+服务名,其中nn为两位数字;系统会根据指定的运行级别进入对应的rcN.d目录,并按照文件名顺序检索目录下的链接文件:对于以K(Kill)开头的文件,系统将终止对应的服务;对于以S(Start)开头的文件,系统将启动对应的服务。 - 运行级别
运行级别 | 描述 |
---|
运行级别0 halt | 关机,默认情况下,系统运行级别不能设置为0,否则电脑一开机就进入关机模式,电脑将不能正常启动 | 运行级别1 Single user mode | 单用户模式,只支持root账户,主要用于系统维护,禁止远程登陆,类似于Windows下的安全模式 | 运行级别2 Multiuser,without NFS | 它是本地多用户模式,没有网络文件系统支持 | 运行级别3 Full Multiuser mode | 完全多用户模式,有网络文件系统,用户登录后进入控制台命令行模式,在没有网络的环境下等同于运行级别2 | 运行级别4 unused | 系统未使用,用作保留,一般不用,在一些特殊情况下可以用它来做一些事情,例如:在笔记本电脑的电池用尽时,可以切换到这一模式来做一些设置 | 运行级别5 X11 | 图形界面的多用户模式用户登录后直接进入X-Window系统 | 运行级别6 Reboot | 重启,默认情况下,运行级别不能设为6,否则电脑一开机就进入重启模式会一直不停地重启,系统将不能正常的启动 |
在任何运行级别下,用户都可以使用init 命令,来切换到其他的运行级别。
这里是参考文献
系统初始化
在init的配置文件中有这么一行: si::sysinit:/etc/rc.d/rc.sysinit 它调用执行了rc.sysinit 这个bash shell的脚本。完成系统的初始化工作,任何模式都会调用执行。 它主要完成的工作有:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。 rc.sysinit 执行时根据具体配置选择系统启动基本,例如:
l5:5:wait:/etc/rc.d/rc 5
这一行中调用了/etc/rc.d/rc 这个shell脚本,同时将参数5传给rc ,去执行/etc/rc.d/rc5.d/ 目录下的所有的rc启动脚本,/etc/rc.d/rc5.d/ 目录中的这些启动脚本实际上都是一些连接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/ 目录下。 /etc/rc.d/rc5.d/ 中的rc启动脚本通常是K或S开头的连接文件,对于以 S 开头的启动脚本,将以start参数来运行。
而如果发现存在相应的脚本也存在K打头的连接,而且已经处于运行态了(以/var/lock/subsys/ 下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。
这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。
至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig 或setup 中的***“System Services”***来自行设定,init详细过程参考
建立终端
rc执行完毕后,返回init。这时基本系统环境已经设置好了,各种守护进程(服务进程)也已经启动了。 init接下来会打开6个终端,以便用户登录系统。 在inittab中的以下6行就是定义了6个终端:
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
从上面可以看出在2、3、4、5的运行级别中都将以respawn方式运行mingetty程序,mingetty程序能打开终端、设置模式。 同时它会显示一个文本登录界面,这个界面就是我们经常看到的登录界面,在这个登录界面中会提示用户输入用户名,而用户输入的用户将作为参数传给login程序来验证用户的身份。
用户登录系统
用户登录主要方式:
Linux 的账号验证程序是 login,login 会接收 mingetty 传来的用户名作为用户名参数。 然后 login 会对用户名进行分析:如果用户名不是 root,且存在 /etc/nologin 文件,login 将输出 nologin 文件的内容,然后退出。 这通常用来系统维护时防止非root用户登录。只有/etc/security 中登记了的终端才允许 root 用户登录,如果不存在这个文件,则 root 用户可以在任何终端上登录。 /etc/usertty 文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。 在分析完用户名后,login将搜索/etc/passwd 以及/etc/shadow 来验证密码以及设置账户的其他信息,比如:主目录什么、使用何种shell。如果没有指定主目录,则将主目录默认设置为根目录;如果没有指定shell,则将shell类型默认设置为/bin/bash 。 Login程序成功后,会向对应的终端再输出最近一次登录的信息(在/var/log/lastlog 中有记录),并检查用户是否有新邮件(在/usr/spool/mail 的对应用户名目录下),然后开始设置各种环境变量。对于bash来说,系统首先寻找/etc/profile 脚本文件并执行它;然后如果用户的主目录中存在.bash_profile 文件,就执行它,在这些文件中又可能调用了其他配置文件,所有的配置文件执行后,各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,至此整个启动过程就结束了。
总结
|