文章目录
启动顺序及过程
1):载入BIOS的硬件信息,并取得第一个开机装置的代号;
2):读取第一个开机装置的MBR的boot Loader (grub)的开机信息;
3):载入OS Kernel信息,解压Kernel,尝试驱动硬件;
4):Kernel执行init程序并获得run-lebel信息(如3或5);
5):init执行/etc/rc.d/rc.sysinit;
6):启动内核外挂模块(/etc/modprobe.conf);
7):init执行run-level的各种Scripts,启动服务;
8):init执行/etc/rc.d/rc.local;
9):执行/bin/login,等待用户Login;
10):Login后进入Shell;
开机自检加载BIOS
打开计算机电源,计算机会首先加载BIOS信息(BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等)。读取信息后,计算机就知道接下来应该去读取哪个硬件设备了。在BIOS将系统的控制权交给硬盘的第一个扇区之
后,就开始由Linux来控制系统了。
读取MBR
硬盘上第0柱面0磁道1扇区被称为MBR,也就是MasterBootRecord,即主引导记录,它的大小是512字节,里面存放了预启动信息、分区表信息及分区标志等。
分为两部分:第一部分为引导(PRE-BOOT)区,占了 446个字节;
第二部分为分区表(PARTITIONPABLE),共有66个字节,记录硬盘的分区信息(其中前64字节是分区表信息,后2个字节是分区的结束标志)。
预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是BootLoader,具体到 Linux系统,就是grub。
查看 MBR的信息:
[root@aliyun ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G 4.0G 34G 11% / devtmpfs 911M 0 911M 0% /dev tmpfs 920M 0 920M 0% /dev/shm tmpfs 920M 320K 920M 1% /run tmpfs 920M 0 920M 0% /sys/fs/cgroup tmpfs 184M 0 184M 0% /run/user/0 #以root身份运行的dd命令,读取驱动器的前512字节,并写入mbr.bin文件。 [root@aliyun ~]# dd if=/dev/vda1 of=mbr.bin bs=512 count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.000117254 s, 4.4 MB/s #用od命令以十六进制和ASCII码形式打印出这个二进制文件。 [root@aliyun ~]# od -xa mbr.bin 0000000 0000 0000 0000 0000 0000 0000 0000 0000 nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul * 0001000 [root@aliyun ~]#
Boot Loader
BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。通常,BootLoader依赖于硬件而实现的,不同体系结构的系统存在着不同的Boot Loader。
Linux的引导扇区内容是采用汇编语言编写的程序,其源代码在arch/i386/boot中(不同体系的CPU有其各自的boot目录),有4个程序文件:
bootsect.S
引导扇区的主程序,汇编后的代码不超过512字节,即一个扇区的大小。
setup.S
引导辅助程序。
edd.S
辅助程序的一部分,用于支持BIOS增强磁盘设备服务。
video.S
辅助程序的另一部分,用于引导时的屏幕显示。
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader。
系统读取内存中的 grub配置信息(一般为 menu.lst或 grub.lst),并依照此配置信息来启动不同的操作系统。
加载 kernel内核
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出”UncompressingLinux”的提示。
当解压缩内核完成后,屏幕输出 “OK,
booting the kernel”。
系统将解压后的内核放置在内存之中,并调用 start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
init进程依据inittab文件设定运行级别
内核被加载后,第一个运行的程序便是/sbin/init,在引导linux系统的过程中“/sbin/init”是内核第一个加载的程序,因此init进程对应的PID号永远为“1”。
此时该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是”:id:3:initdefault:”,这就表明Linux需要运行在等级3上。
Linux的运行等级如下:
0:关机;
1:单用户模式;
2:无网络支持的多用户模式;
3:有网络支持的多用户模式;
4:保留,未使用;
5:有网络支持多用户模式;
6:重新引导系统,即重启;
init进程执行rc.sysinit
在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。可以在(/etc/rc.d)中查看一下rc.sysinit文件。
线程init的最终完成状态是能够使得一般的用户程序可以正常地被执行,从而真正完成可供应用程序运行的系统环境。
它主要进行的操作有:
(1)执行函数do_basic_setup(),它会对外部设备进行全面地初始化。
(2)构建系统的虚拟文件系统目录树,挂接系统中作为根目录的设备。
(3)打开设备/dev/console,并通过函数sys_dup()打开的连接复制两次,使得文件号0,1,2,全部指向控制台。这三个文件连接就是通常所说的”标准输入”stdin,”标准输出”stdout”和”标准出错信息”stderr这三个标准I/O通道。
(4)准备好以上一切之后,系统开始进入用户层的初始化阶段。内核通过系统调用execve()加载执 T子相应的用户层初始化程序,依次尝试加载程序”/sbin/initl”,”
/etc/init”,” /bin/init’,和”/bin/sh。只要其中有一个程序加载获得成功,那么系
统就将开始用户层的初始化,而不会再回到init()函数段中。至此,init()函数结束,
Linux内核的引导部分也到此结束。
启动内核模块
具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。
执行不同运行级别的脚本程序
根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。
执行/etc/rc.d/rc.local
rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。可以把你想设置和启动的东西放到这里。
[root@aliyun ~]# cat /etc/rc.local #!/bin/bash # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES # # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # # In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. # # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure # that this script will be executed during boot. touch /var/lock/subsys/local /etc/init.d/mysqld start /etc/init.d/httpd start systemctl start vsftpd.service
执行/bin/login程序
启动mingetty,进入登录状态,系统已经进入到了等待用户输入username和password的时候了,已经可以用自己的帐号登入系统了。