() Linux 系统开机详细启动过程

运维小弟 2018-07-20 18:38

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;

01

开机自检加载BIOS

打开计算机电源,计算机会首先加载BIOS信息(BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、电脑PnP特性等等)。读取信息后,计算机就知道接下来应该去读取哪个硬件设备了。在BIOS将系统的控制权交给硬盘的第一个扇区之

后,就开始由Linux来控制系统了。

02

读取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 ~]#

03

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),并依照此配置信息来启动不同的操作系统。

04

加载 kernel内核

根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出\"UncompressingLinux\"的提示。

当解压缩内核完成后,屏幕输出 \"OK,

booting the kernel\"。

系统将解压后的内核放置在内存之中,并调用 start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。

05

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:重新引导系统,即重启;

06

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内核的引导部分也到此结束。

07

启动内核模块

具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。

08

执行不同运行级别的脚本程序

根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。

09

执行/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

10

执行/bin/login程序

启动mingetty,进入登录状态,系统已经进入到了等待用户输入username和password的时候了,已经可以用自己的帐号登入系统了。


电脑