APP下载
报价宝  ›  科技  › 

Linux 的启动流程

报价宝 来源:baojiabao.com 发布时间:2019-11-20 16:59:00 11月12日更新
报价宝综合消息Linux 的启动流程

本篇的重点是讲解装置和驱动的启动流程,装置和驱动的流程是整个核心启动的核心,也是工作中最常面对的问题。出于知识点的系统性考虑,在进入主题之前我们先看下整个 Linux 在 ARM 中的启动流程如何。

Uboot 的启动流程ARM Linux 的启动流程大致为:Uboot → Kernel → Root filesystem。Uboot 在上电的时候就拿到 CPU 的控制权,实现了硬件的初始化。具体是怎么实现的呢?一起来看一下,CPU 的内部集成了小容量的 Sram,而 PC 指标一上电就指向 Sram 的起始地址 0x00000000,所以一上电 Uboot 程式码就得到了执行。

Uboot 拿到 CPU 使用权就开始做初始化工作,比如关闭看门狗、设定 CPU 执行模式、设定堆叠、初始化内存、网络卡、nand flash 等,最后把 Linux 核心载入到内存中。

初始化 RAM

因为核心要在 RAM 中执行,所以在呼叫核心之前必须初始化和设定 RAM,为呼叫核心做好准备。

初始化串列埠

核心在启动过程中可以将资讯通过串列埠输出,这样就可以清楚的知道核心启动资讯。虽然串列埠不是 Uboot 必须要完成的工作,但是通过串列埠可以方便除错 Uboot 和核心的各种资讯。

检测处理器型别

Uboot 在呼叫核心前需要检测系统的处理器型别,并将其储存在某个变数中提供给核心,核心在启动过程中会根据该处理器的型别呼叫相应的初始化程式。

设定核心启动引数

核心在启动过程中会根据该启动引数进行相应的初始化工作。

呼叫核心映象

值得注意的是储存 Uboot 的储存器不同,Uboot 的执行过程也并不相同,一般来讲 Flash 分为 nor Flash 和 nand Flash 两种:nor Flash 支援芯片内执行(XIP,eXecute In Place),这样程式码可以在 Flash 上直接执行而不必复制到 RAM 中去执行。

但是 nand Flash 并不支援 XIP,所以要想执行 nand Flash 上的程式码,必须先将其复制到 RAM 中去,然后跳到 RAM 中去执行。如果核心存放在 nor Flash 中,那么可直接跳转到核心中去执行。但通常由于在 nor Flash 中执行程式码会有种种限制,而且速度也远不及 RAM 快,所以一般的嵌入式系统都是将核心复制到 RAM 中,然后跳转到 RAM 中去执行。不论哪种情况,在跳到核心执行之前 CPU 的暂存器必须满足以下条件:r0 = 0,r1 = 处理器型别,r2 = 标记列表在 RAM 中的地址。

Linux 核心的启动流程(装置和驱动的载入)关于 Uboot 的启动本课程不做详细介绍,因为本课程的主要内容是核心。在讲述核心启动之前让我们先了解下核心的组成结构:

其中,

(1)vmlinusx 是 ELF 格式的 Object 档案,这种档案只是各个源代码经过连线以后得到的档案,并不能在 ARM 平台上执行。

(2)经过 objcopy 这个工具转换以后,得到了二进位制格式档案 Image,Image 档案相比于 vmlinusx 档案,除了格式不同以外,还被去除了许多注释和除错的资讯。

(3)Image 档案经过压缩以后得到了 piggy.gz,这个档案仅仅是 Image 的压缩版,并无其他不同。

(4)接着编译生成另外几个模组档案 misc.o、big_endian.o、head.o、head-xscale.o,这几个档案组成一个叫 Bootstrap Loader 的元件,又叫载入程式,编译生成 piggy.o 档案。

(5)最后 piggy.o 档案和 Bootstrap Loader 组成一个 Bootable Kernel Image 档案(可启动档案)。

经过上面的分析不难知道 piggy.o 就是核心映象,而剩下的几个档案就组成了载入程式。知道了核心的组成结构,Uboot 就是按照核心的组成结构一层一层剥开然后引导核心的:

可以说 start_kernel之前的所有工作都是为了将环境准备好,满足start_kernel的要求,然后由start_kernel开始进行核心的载入:

关于 start_kernl函式的内容太多,可以通过红色回拨函式看出,start_kernel函式基本是在回拨很多对应的注册函式。为了本系列课程的结构性这里就不展开所有知识点讲解,本篇内容接着前一篇装置树的内容重点讲解下装置和驱动的匹配过程。

还记得上一篇讲到的装置树三大作用吗?

平台标识;

执行时配置;

装置资讯集合。

接下来我们就看看核心在启动的时候是如何寻找装置,驱动又如何和装置系结的。

首先在平台目录下可以看到有很多平台描述的档案,如图:

有那么多的平台,我们到底要执行哪个平台是首先要考虑的事情。这也是装置三大功能的第一个功能——平台标识。

装置树里有对装置根节点的 Compatible 描述,平台档案里有对 __initconst的描述,如果两个字段一致则找到了对应的板级档案,这样就通过装置树把要用的装置平台与其他平台区分开来了,如图:

找到平台后就可以根据回拨函式的指标呼叫该平台的注册函式。这里以飞思卡尔 imx.6dl 平台为例,回拨的时候会呼叫 imx6q_init_machine函式,如下:

这里补充一个知识点,细心的读者也许发现了在 Compatible 字段里用逗号分隔了两个字串。板级匹配的时候用的是哪个字串,另外一个字串又是做什么用?首先后面的字段 "fsl,imx6dl" 是抽象共用平台描述符,前面的字段 "fsl,imx6dl-sabresd" 是通用平台下的具体平台描述符,可以理解为母板和子板的区别。在具体的子板档案中我们可以通过前面的字段进行装置资讯的获取,如图:

接着是执行时配置,让核心在启动的时候根据引数设定进行不同的处理。有经验的读者清楚在 Uboot 里也有对 Bootargs 的配置,这里为什么多此一举呢,是为了在 Uboot 中更灵活的对核心启动进行配置。

最后的作用就是装置资讯集合,这是装置和驱动匹配的核心,也是工作中面对最多的情况。出于这一作用的内容是工作中经常遇到的重点也是难点,我们专门用一篇内容来详细讲解各级装置是如何展开的,并且手把手教你如何定制一套自己的开发板全新案例。

轻轻一扫 欢迎关注~

文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 报价宝 汽车价格 电视机价格 华为手机价格 降噪耳机价格