Linux系统启动初始化
文章目录
Linux系统启动初始化的主要流程是:
1.上电BIOS自检
2.启动Boot Loader(GRUB)
3.加载内核
4.启动第一个进程
5.配置环境
一.BIOS 加载启动引导程序
BIOS(英文:Basic Input/Output System),即基本输入输出系统,亦称为ROM BIOS、System BIOS、PC BIOS,是在通电引导阶段运行硬件初始化,以及为操作系统提供运行时服务的固件。BIOS最早随着CP/M操作系统的推出在1975年出现。BIOS预安装在个人电脑的主板上,是个人电脑启动时加载的第一个软件。
现在,BIOS的作用是初始化和测试硬件组件,以及从大容量存储设备(如硬盘)加载引导程序,并由引导程序加载操作系统。BIOS还为DOS操作系统提供键盘、显示及其他I/O设备的硬件抽象层。
许多BIOS程序都只能在特定电脑型号或特定主板型号上运行。早年,BIOS存储于ROM芯片上;现在的BIOS多存储于闪存芯片上,这方便了BIOS的更新。
计算机上电之后,CPU就可以执行程序了,但是此时内存中并没有程序让CPU执行,因为内存是RAM掉电丢失。而且操作系统也没有装上,这个时候就要装系统了。ROM中就固化了一些计算机刚上电要执行的初始化程序,也就是BIOS(Basic Input and Output System,基本输入输出系统) 。简单地理解 BIOS,它就是固化在主板上一个 ROM(只读存储器)芯片上的程序,主要保存计算机的基本输入/输出信息、系统设置信息、开机自检程和系统自启动程序,用来为 计算机提供最底层和最直接的硬件设置与控制。
BIOS 的初始化主要完成以下 3 项工作:
- 第一次检查计算机硬件和外围设备(第二次自检由内核完后,后续会讲),例如 CPU、内存、风扇灯。当 BIOS 一启动,就会做一个自我检测的工作,整个自检过程也被称为 POST(Power On Self Test)自检。
- 如果自检没有问题,BIOS 开始对硬件进行初始化,并规定当前可启动设备的先后顺序,选择由那个设备来开机。
- 选择好开启设备后,就会从该设备的 MBR(主引导扇区)中读取 Boot Loader(启动引导程序)并执行。启动引导程序用于引导操作系统启动,Linux 系统中默认使用的启动引导程序是 GRUB。
BIOS从MBR中读取启动引导程序,加载至RAM中,就可以执行启动引导程序了。
二.MBR 主引导扇区
MBR是用来存储启动引导程序的!!!
MBR 也就是主引导扇区 ,位于硬盘的 0 磁道、0 柱面、1 扇区中,主要记录了启动引导程序和磁盘的分区表 ,如图是MBR的结构:

MBR大小是一个扇区512Byte, 其中 446 Byte 安装了启动引导程序,其后 64 Byte 描述分区表,最后的 2 Byte 是结束标记 。
BIOS从MBR中读取启动引导程序,将启动引导程序加载至RAM中,然后BIOS将控制权交给启动引导程序。
所以,虽然启动引导程序是在MBR中的,但是实际上是由BIOS从MBR中将启动引导程序加载至RAM中运行的!
注意:这里的446Byte中存放的只是启动引导程序的一个镜像文件,后面还要通过这个镜像文件来加载出完整的启动引导程序!
三.GRUB引导内核
Linux下是通过一个工具Grub2( Grand Unified Bootloader Version 2 ),这个工具就是专门引导系统启动的。
GNU GRUB(简称“GRUB”)是一个来自GNU项目的启动引导程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。
3.1运行 boot.img
BootLoader,是启动引导程序,启动引导程序的主要任务就是加载操作系统内核, 每种操作系统的文件格式不同,因此,每种操作系统的启动引导程序也不一样。不同的操作系统只有使用自己的启动引导程序才能加载自己的内核。这里使用GRUB2作为启动引导程序。
上面说BIOS将启动引导程序加载到RAM中执行,但是实际上启动引导程序的大小比512Byte要大,所以MBR中的只是一个镜像文件:boot.img。我们还得通过MBR中的boot.img找到完整的启动引导程序,从而正式启动内核。
所以,boot.img的任务并不是启动内核,而是加载其他镜像文件来完成内核的启动,也可以理解为只有446Byte大小的boot.img不足以启动内核,只能召唤出更加强大厉害的其他镜像文件来启动内核。
3.2加载 core.img
这个强大的后援就是:core.img, core.img 由 lzma_decompress.img、diskboot.img、kernel.img 和一系列的模块组成,功能比较丰富,能做很多事情。

boot.img 先加载的是 core.img 的第一个扇区。如果从硬盘启动的话,这个扇区里面是 diskboot.img,对应的代码是 diskboot.S。boot.img 将控制权交给 diskboot.img 后,diskboot.img 的任务就是将 core.img 的其他部分加载进来,先是解压缩程序 lzma_decompress.img,再往下是 kernel.img,最后是各个模块 module 对应的映像。这里需要注意,它不是 Linux 的内核,而是 grub 的内核。lzma_decompress.img 对应的代码是 startup_raw.S,本来 kernel.img 是压缩过的,现在执行的时候,需要解压缩。
在这之前,我们所有遇到过的程序都非常非常小,完全可以在实模式下运行,但是随着我们加载的东西越来越大,实模式这 1M 的地址空间实在放不下了,所以在真正的解压缩之前,lzma_decompress.img 做了一个重要的决定,就是调用 real_to_prot,切换到保护模式,这样就能在更大的寻址空间里面,加载更多的东西。
3.3切换到保护模式
切换到保护模式需要做以下几点:
- 启用分段,在内存中建立段描述符表(和中断向量表差不多),原来的段寄存器指向现在的段描述符
- 启动分页,现在内存大了,需要分页进行管理
- 打开Gate A20,使用第21根地址控制线
3.4kernel.img 引导内核
这里kernel.img不是Linux的内核,而是GRUB的内核。
kernel.img 对应的代码是 startup.S 以及一堆 c 文件,在 startup.S 中会调用 grub_main,这是 grub kernel 的主函数,主函数中 grub_load_config() 开始解析,我们上面写的那个 grub.conf 文件里的配置信息。
当启动了操作系统后,就要开始调用 grub_menu_execute_entry() ,开始解析并执行你选择的那一项。
例如里面的 linux16 命令,表示装载指定的内核文件,并传递内核启动参数。于是 grub_cmd_linux() 函数会被调用,它会首先读取 Linux 内核镜像头部的一些数据结构,放到内存中的数据结构来,进行检查。如果检查通过,则会读取整个 Linux 内核镜像到内存。

四.内核初始化
上面已经引导了操作系统,也就是引导了内核,接下来就是内核的初始化了。
内核启动的入口函数从start_kernel()开始, 在init/main.c 文件中,start_kernel 相当于内核的 main 函数。打开这个函数,你会发现,里面是各种各样初始化函数 XXXX_init .
内核初始化做了以下这些事:
- 创建0号进程, 这是唯一一个没有通过 fork 或者 kernel_thread 产生的进程,是进程列表的第一个。
- 初始化中断, 对应的函数是 trap_init() ,里面设置了很多中断门(Interrupt Gate),用于处理各种中断。其中有一个 set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32),这是系统调用的中断门。系统调用也是通过发送中断的方式进行的。
- 初始化内存管理模块, mm_init()
- 初始化调度模块, sched_init()
- 初始化基于内存的文件系统rootfs, vfs_caches_init()
- 初始化其他, rest_init()
- 创建用户态第一个进程:1号进程,用 kernel_thread(kernel_init, NULL, CLONE_FS) 创建1号进程
- 创建内核态第一个进程:2号进程, kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES)
这样看来,内核初始化靠的是start_kernel()函数,初始化主要做三件事:
1.创建样板进程(也就是0号进程),以及各个模块的初始化
2.创建用户态的进程
3.创建内核态的进程
用户态访问核心资源时,通过中断来请求,就是系统调用的统一中断,流程如下:

用户态和内核态进程执行的框图如下:

五.系统调用
从上面得知,一般程序运行在用户态,如果要想使用核心资源,就要进入内核态,就要通过系统调用。
此外,linux的一些驱动程序都是写在内核中的,当上层应用想要调用驱动的接口时,也要通过系统调用来实现。
但是,直接操作系统调用比较繁琐,所以一般使用glibc库对系统调用进行封装。
64位的系统调用如图所示:

Linux系统启动初始化的更多相关文章
- Linux学习之CentOS(二十一)--Linux系统启动详解
在这篇随笔里面将对Linux系统的启动进行一个详细的解释!我的实验机器是CentOS6.4,当然对于现有的Linux发行版本,其系统的启动基本上都是一样的! 首先我们来看下Linux系统启动的几个 ...
- Linux系统启动过程分析
[原创]Linux系统启动过程分析-wjlkoorey258-ChinaUnix博客http://blog.chinaunix.net/uid-23069658-id-3142047.html 经过对 ...
- 【转】Linux系统启动过程分析
[转]Linux系统启动过程分析 转自:http://blog.chinaunix.net/uid-23069658-id-3142047.html 经过对Linux系统有了一定了解和熟悉后,想对其更 ...
- 【转载】Linux系统启动流程
原文:Linux系统启动流程 POST(Power On Self Test/上电自检)-->BootLoader(MBR)-->Kernel(硬件探测.加载驱动.挂载根文件系统./sbi ...
- linux 系统启动流程
原著资料网址:http://wenku.baidu.com/view/414127fdf705cc1755270997.html (版权归原作者所有) Linux系统的启动分5个阶段,每个阶段都完成不 ...
- Linux系统启动流程及grub重建(1)
日志系统 Linux系统启动流程 PC: OS(Linux) POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel--& ...
- Linux系统启动过程介绍
Linux系统启动过程介绍 学习操作系统有必要了解一下系统的启动过程,这样在面对各种系统故障的时候能快速定位解决问题,下面以Centos来分析linux系统的启动过程. 1.BIOS自检:当开机的时候 ...
- 一起学Linux02之Linux系统启动过程
这个Linux系统启动过程啊,说实话,我认为,刚学习的时候看几遍,了解一下就好.现在的主要任务是用.熟练了之后再来深究这个不急. 下面我就简单地说说吧. Linux系统的启动主要分为下列步骤: 1 内 ...
- Linux系统启动那些事—基于Linux 3.10内核【转】
转自:https://blog.csdn.net/shichaog/article/details/40218763 Linux系统启动那些事—基于Linux 3.10内核 csdn 我的空间的下载地 ...
随机推荐
- QT从入门到入土(二)——对象模型(对象树)和窗口坐标体系
摘要 我们使用的标准 C++,其设计的对象模型虽然已经提供了非常高效的 RTTI 支持,但是在某些方面还是不够灵活.比如在 GUI 编程方面,既需要高效的运行效率也需要强大的灵活性,诸如删除某窗口时可 ...
- DNS域名解析四种配置实验 ---Linux DNS域名解析服务
DNS域名解析服务一.BIND域名服务基础1) DNS的定义2)域名结构3)DNS系统的作用① 正向解析:根据域名查找对应的IP地址② 反向解析:根据IP地址查找对应的域名③ DNS系统的分布式数据结 ...
- C语言:转义字符 ++a例子
#include <stdio.h> int main() { printf("a\bwhat\'s\tyour\tname\n"); int k; printf(&q ...
- iframe跨域访问出现的cookie问题,提供两种解决方案
最近在java项目对接时出现的一个问题.A系统嵌入B系统页面时,使用iframe去嵌入B系统页面丢失sessionid,导致B系统认为是未进行登录的请求,从而跳转到了B系统登录页. 解决方法查看此博客 ...
- Python3.7 lxml引入etree
用xml代替lxml,Python3.7中已经没有etree这个模块了 import xml.etree.ElementTree as etree from lxml import etree 这种方 ...
- Java基础00-基础语法3
1. 注释 1.1 注释概述 1.2 注释分类 1.3 示例 2. 关键字 2.1 关键字概述 2.2 关键字的特点 3. 常量 3.1 常量的概述 3.2 常量分类 以上常量除了空常量都是可以直接输 ...
- 【LeetCode】1248. 统计「优美子数组」
1248. 统计「优美子数组」 知识点:数组:前缀和: 题目描述 给你一个整数数组 nums 和一个整数 k. 如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」. ...
- 架构之:REST和HATEOAS
目录 简介 HATEOAS简介 HATEOAS的格式 HATEOAS的Spring支持 总结 简介 我们知道REST是一种架构方式,它只是指定了六种需要遵循的基本原则,但是它指定的原则都比较宽泛,我们 ...
- .net 5+ 知新:【1】 .Net 5 基本概念和开发环境搭建
最近一两年搞了很多其它事情,.net web方面的基本没做,之前做过几个小的项目零星的学习了些,从.net core 发布后其实都没正真的系统学习过. 就是上手做项目,平时也有关注和看些资料,所以项目 ...
- js之 foreach, map, every, some
js中array有四个方法 foreach, map, every, some,其使用各有倾向. 关注点一:foreach 和 map 无法跳出循环,每个元素均执行 foreach 和 map 无法跳 ...