Linux开机启动顺序分析

开机过程指的是从打开计算机电源直到 LINUX 显示用户登录画面的全过 程。分析 LINUX 开机过程也是深入了解 LINUX 核心工作原理的一个很好 的途径。
启动第一步--加载 启动第一步--加载 BIOS --
当你打开计算机电源,计算机会首先加载 BIOS 信息,BIOS 信息是如此 的重要,以至于计算机必须在最开始就找到它。这是因为 BIOS 中包含了 CPU 的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、 PnP 特性等等。在此之后,计算机心里就有谱了,知道应该去读取哪个硬 件设备了。在 BIOS 将系统的控制权交给硬盘第一个扇区之后,就开始由 Linux 来控制系统了。
启动第二步--读取 启动第二步--读取 MBR --
硬盘上第 0 磁道第一个扇区被称为 MBR,也就是 Master Boot Record, 即主引导记录,它的大小是 512 字节,可里面却存放了预启动信息、分区 表信息。可分为两部分:第一部分为引导(PRE-BOOT)区,占了 446 个字节;第二部分为分区表(PARTITION PABLE),共有 66 个字节, 记录硬盘的分区信息。 预引导区的作用之一是找到标记为活动 (ACTIVE) 的分区,并将活动分区的引导区读入内存。
系统找到 BIOS 所指定的硬盘的 MBR 后, 就会将其复制到 0×7c00 地址所 在的物理内存中。其实被复制到物理内存的内容就是 Boot Loader,而具 体到你的电脑,那就是 lilo 或者 grub 了。
启动第三步-- 启动第三步--Boot Loader --
Boot Loader 就是在操作系统内核运行之前运行的一段小程序。 通过这段 小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统 的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一 切准备。通常,BootLoade:是严重地依赖于硬件而实现的,不同体系结构 的系统存在着不同的 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 为例来讲解吧。 系统读取内存中的 grub 配置信息(一般为 menu.lst 或 grub.lst),并依照 此配置信息来启动不同的操作系统。
启动第四步--加载内核 启动第四步--加载内核 --
根据 grub 设定的内核映像所在路径,系统读取内存映像,并进行解压缩 操作。此时,屏幕一般会输出“Uncompressing Linux”的提示。当解压缩 内核完成后,屏幕输出“OK, booting the kernel”。 系统将解压后的内核放置在内存之中,并调用 start_kernel()函数来启动一 系列的初始化函数并初始化各种设备, 完成 Linux 核心环境的建立。 至此, Linux 内核已经建立起来了,基于 Linux 的程序应该可以正常运行了。 start_kenrel()定义在 init/main.c 中,它就类似于一般可执行程序中的 mai n()函数, 系统在此之前所做的仅仅是一些能让内核程序最低限度执行的初 始化操作,真正的内核初始化过程是从这里才开始。函数 start_kerenl() 将会调用一系列的初始化函数,用来完成内核本身的各方面设置,目的是 最终建立起基本完整的 Linux 核心环境。 start_kernel()中主要执行了以下操作: (1) 在屏幕上打印出当前的内核版本信息。 (2) 执行 setup_arch(),对系统结构进行设置。 (3)执行 sched_init(),对系统的调度机制进行初始化。先是对每个可用 CP U 上的 runqueque 进行初始化;然后初始化 0 号进程(其 task struct 和系统 空 M 堆栈在 startup_32()中己经被分配)为系统 idle 进程, 即系统空闲时占 据 CPU 的进程。 (4)执行 parse_early_param()和 parsees_args()解析系统启动参数。
(5)执行 trap_initQ,先设置了系统中断向量表。0-19 号的陷阱门用于 C PU 异常处理;然后初始化系统调用向量;最后调用 cpu_init()完善对 CPU 的 初始化,用于支持进程调度机制,包括设定标志位寄存器、任务寄存器、 初始化程序调试相关寄存器等等。 (6)执行 rcu_init(),初始化系统中的 Read-Copy Update 互斥机制。 (7)执行 init_IRQ()函数,初始化用于外设的中断,完成对 IDT 的最终初始 化过程。 (8)执行 init_timers(), softirq_init()和 time_init()函数, 分别初始系统的定时 器机制,软中断机制以及系统日期和时间。 (9)执行 mem_init()函数,初始化物理内存页面的 page 数据结构描述符, 完成对物理内存管理机制的创建。 (10)执行 kmem_cache_init(),完成对通用 slab 缓冲区管理机制的初始化工 作。 (11)执行 fork_init(), 计算出当前系统的物理内存容量能够允许创建的进程 (线程)数量。 (12)执行 proc_caches_init() , bufer_init(), unnamed_dev_init() ,vfs_cac hes_init(), signals_init()等函数对各种管理机制建立起专用的 slab 缓冲区 队列。 (13 )执行 proc_root_init()Wl 数,对虚拟文件系统/proc 进行初始化。 在 start_kenrel()的结尾, 内核通过 kenrel_thread()创建出第一个系统内核 线程(即 1 号进程),该线程执行的是内核中的 init()函数,负责的是下一阶
段的启动任务。最后调用 cpues_idle()函数:进入了系统主循环体口默认将 一直执行 default_idle()函数中的指令,即 CPU 的 halt 指令,直到就绪队 列中存在其他进程需要被调度时才会转向执行其他函数。此时,系统中唯 一存在就绪状态的进程就是由 kerne_hread()创建的 init 进程(内核线程), 所以内核并不进入 default_idle()函数,而是转向 init()函数继续启动过程。
启动第五步--用户层 启动第五步--用户层 init 依据 inittab 文件 -- 来设定运行等级
内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/initta b 文件,并依据此文件来进行初始化工作。 其实/etc/inittab 文件最主要的作用就是设定 Linux 的运行等级,其设定形 式是“:id:5:initdefault:”,这就表明 Linux 需要运行在等级 5 上。Linux 的 运行等级设定如下: 0:关机 1:单用户模式 2:无网络支持的多用户模式 3:有网络支持的多用户模式 4:保留,未使用 5:有网络支持有 X-Window 支持的多用户模式 6:重新引导系统,即重启
启动第六步-- 启动第六步--init 进程执行 rc.sysinit --
在设定了运行等级后,Linux 系统执行的第一个用户层文件就是/etc/rc.d/r c.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 启动第九步--执行 --执行
你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用 一目了然: # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don’t # want to do the full Sys V style init stuff. rc.local 就是在一切初始化工作后,Linux 留给用户进行个性化的地方。你 可以把你想设置和启动的东西放到这里。
启动第十步--执行/bin/login 程序, 程序, 启动第十步--执行 --执行 进入登 录状态
此时, 系统已经进入到了等待用户输入 username 和 password 的时候了, 你已经可以用自己的帐号登入系统了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值