百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

Linux启动过程简述(linux系统启动过程简述)

sinye56 2024-11-03 15:02 16 浏览 0 评论

BIOS加载bootloader阶段

计算机接电之后第一个启动的是BIOS,因为BIOS是存储在主板上的一个小程序,空间有限代码量少因此功能受限。要经过一步步的控制权转移,最后转移给功能更加强大的操作系统。

BIOS对系统做一些简单的初始化工作,然后把控制权交给MBR。约定MBR(Main Boot Record)存在于整个硬盘最开始的扇区。每个扇区都是512字节,MBR引导扇区的内容是:

  • 446字节的引导程序及参数

  • 64字节的分区表(每个分区表项16字节,因此只能有4个主分区)

  • 2字节的结束标志0x55和0xaa

0x55和0xaa是MBR结束标志,0x7c00是MBR被加载在内存中的位置。

BIOS结束自己的工作以后,需要把控制权交给MBR,过程是:BIOS找到MBR并且把MBR加载在内存中,跳转到该位置。

为了方便BIOS寻找,约定好0盘0道1扇区(第一个扇区)用来存储MBR。MBR内容占510个字节,剩余两个字节用作结束标志。BIOS不用遍历这个扇区,只要检测到有这个标志就认为这个扇区有可以运行的MBR存在,否则BIOS会报错。这两个结束标志是0x55和0xaa。

关于0x7c00,这是一个历史遗留问题。MBR的名称是主引导记录,MBR主要工作是:建立分区表、引导其他更复杂的程序。8086cpu要求0~30k位置用来存储中断向量表,DOS1.0要求的最小内存是32k,因此MBR必须存储在钱32k中,中断向量表长度不一定,MBR希望自己有足够的空间运行(MBR也是程序,程序运行需要用到栈,MBR预估自己需要用到512字节的自身存储和512字节的堆栈空间),同时尽可能多的留给向量表足够的空间。综上,MBR存储在32k的最后1k空间,也就是从0x7c00开始。

MBR的主要工作是什么呢?

MBR加载bootloader

执行完了自己的工作,需要把控制权交出去。MBR遍历分区表中的4个分区,查找操作系统加载器,找到后把CPU交给加载器。MBR怎么知道加载器存在哪个分区呢?分区表项到 第一个字节就是活动分区标志,如果该分区存储了加载器,该标志被置为0x80,否则是0.MBR只需要遍历分区表就能找到下一棒选手应该是谁。这里为了方便MBR找到活动分区上的(因为程序跳转是需要指明跳转地址的),约定好加载器就存储在各分区的开始扇区,这个扇区被称为操作系统引导扇区也称为,这个OBR就是我们常见的x86平台上的grub或者arm平台上的uboot,这个程序负责的主要工作是加载kernel image 并解压缩。

bootloader加载kernel

CRUB会根据需求显示一个可用的内核列表(定义在/etc/grub.con,以及/etc/grub/menu.lst和/etc/grub.conf的软连接)。你可以选中一个内核,并且可以用附加的内核参数改进它。另外,你还能通过shell终端命令行的方式手动控制整个启动过程。

Bootloader完成CPU、RAM、网卡等信息的初始化,建立内存的映射关系。在外存上找到kernel image,启动IO读入内存。一般kernel image使用zlib压缩为zImage或者bzImage格式,读取了image以后,在内核镜像的头部,有一个小型的routine,做一些简单的硬件设置,解压缩至高端内存(输出解压缩提示信息:Decompressing Linux...),加载initrd(注意:这个在后面会作为临时根文件系统存在)进内存,执行kernel通过./arch/i386/boot/head

kernel初始化

Bootloader在把控制权交给kernel时候,会传递一些参数。这个参数可以是用户通过bootloader设置的(例如:grub的配置文件grub.conf),或者是bootloader自己检测到的硬件信息(例如:根设备标识、页面大小、内核需要的命令信息)。

内核先是设置系统的状态(此部分通过汇编程序head.S完成):查看CPU类型检查kernel是否支持此种类型,查找体系类型,初始化寄存器,创建页表,开启MMU,建立IDT、GDT、LDT,跳转到入口函数start_kernel(main.c中,是第一个C函数)处。

在main开始运行的时,PC处于一个实模式,CPU执行一些必要操作后跳转到保护模式。这里,有两个很重要的问题:中断和内存。在实模式下,处理器的中断向量表始终位于存储地址0(最开始的位置),而在保护模式下,中断向量表的位置存储在称为IDTR的CPU寄存器中。同是逻辑地址到线性地址转换实模式和保护模式是不一样的,保护模式需要一个称为GDTR的寄存器来加载内存的全局描述符表的地址。因此,go_to_protected_mode调用setup_idtsetup_gdt来安装临时中断描述符表和全局描述符表。

现在我们准备好了跳转到保护模式了,调用protected_mode_jump,这个函数设置CR0寄存器的PE位,打开A19地址线等等操作跳转到保护模式。注意此时分页还是被禁用的,因为暂时还不需要分页。现在,内存终于可以寻址到4GB,调用32位内核入口点startup_32

startup_32调用decompress_kernel解压缩真正的内核,并在显示器上打印信息Decompress Linux...。解压缩过的kernel此时会覆盖解压缩之前的内核镜像。解压缩结束以后,清楚BSS段设置最终的GDT和IDT,构建页表,打开分页初始化堆栈,最后跳转到start_kernel。 上面的过程如下所示:

start_kernel

执行各种初始化函数:初始化IRQ、时钟、CPU、内存、VFS、中断向量表、内核子系统等等。最后调用

rest_init

,这几乎是start_kernel的全部工作,

rest_init

创建一个内核线程,执行

kernel_init

rest_init

调用

schedule

启动任务调度,调用

cpu_idle

cpu_idle

永远运行,只有当进程就绪列表中有就绪进程时候,cpu_idle才会被从CPU上拉下来,当没有进程时候,这个空闲进程又被拉起来执行,这就是进程0。进程0漫长的工作终于结束了,从BIOS、MBR、Bootloader最后到kernel。虽然进程0从启动的舞台上退出了,这并没有意味着kernel启动完成了。

进程0刚刚创建了一个内核线程执行

kernel_init

,还记得吗?我们现在看看这个线程的运行。

kernel_init

负责初始化启动剩下的CPU,从启动分析到现在,我们只有一个CPU在运行注意到了吗?这个CPU我们成为引导CPU,剩下的应用CPU初始化依然需要从实模式开始。最后

kernel_init

调用

init_post

,这个函数尝试执行一下用户进程:

/sbin/init

/etc/init

/bin/init

/bin/sh

,如果全部失败,产生kernel panic。如果上述程序存在,创建进程1运行(这个进程是所有用户进程的父进程)。过程如下图所示:

init读取的第一个文件是

/etc/inittab

,从这里init决定了我们的Linux操作系统的运行级别。Linux系统有7个运行级别(runlevel):

level 0:系统停机状态

level 1:单用户工作状态

level 2:多用户状态

level 3:完全多用户状态

level 4:保留

level 5:X11

level 6:reboot

Init从/etc/fstab

文件中查找分区表信息,用真正的根文件系统替换initrd。Init然后启动默认运行级别的/etc/init.d目录中指定的所有服务或者脚本。这是所有服务由init逐个初始化的步骤。在这个过程中,一次一个服务由init启动,所有守护程序在后台运行,init继续管理它们。

至此,内核启动基本结束了。

相关推荐

程序员:JDK的安装与配置(完整版)_jdk的安装方法

对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...

Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置

一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...

麒麟系统安装JAVA JDK教程_麒麟系统配置jdk

检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...

学习笔记-Linux JDK - 安装&配置

前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

测试员必备:Linux下安装JDK 1.8你必须知道的那些事

1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...

Linux 下安装JDK17_linux 安装jdk1.8 yum

一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...

在Ubuntu系统中安装JDK 17并配置环境变量教程

在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...

如何在 Linux 上安装 Java_linux安装java的步骤

在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...

Windows和Linux环境下的JDK安装教程

JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...

linux安装jdk_linux安装jdk软连接

JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...

linux安装jdk,全局配置,不同用户不同jdk

jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...

运维大神教你在linux下安装jdk8_linux安装jdk1.7

1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...

window和linux安装JDK1.8_linux 安装jdk1.8.tar

Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...

最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?

默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...

取消回复欢迎 发表评论: