bootloader启动流程分析

bootloader启动流程分析

 

1Bootloader的概念和作用

      Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序。在完成对系统的初始化任务之后,它会将Flash中的Linux内核拷贝到 RAM 中去,跳转到内核的第一条指令处继续执行,从而启动 Linux 内核。由此可见,bootloader和 Linux内核密不可分,要想了解 Linux内核的启动过程,我们必须先得了解 bootloader的执行过程,这样才能对嵌入式系统的整个启过程有清晰的掌握。

 

2、常见的Bootloader

X86:LILO和GRUB

ARM: 每一种芯片都会有自己的Bootloader

PowerPC:ppcboot

MIPS:YAMON

U-BOOT支持以上所有平台,是bootloader介公认的老大,因此接下来要深入学习U-BOOT。

 

3Bootloader启动流程分析

      Bootloader启动的两个阶段: stage1 和 stage2两大部分。 stage1 主要是一些依赖于 CPU 体系结构的代码。这一阶段的代码主要是通过汇编来实现的。 stage1 为位置无关代码,通常在Flash 中运行。所以有的指令为相对寻址,可以在任何位置运行。stage2 则是通常用 C 语言来实现,这样可以实现更复杂的功能,而且代码 会具有更好的可读性和可移植性。

stage1负责的主要任务有:
   ① 硬件设备初始化包括:关闭Watchdog、关闭中断、设置 CPU 的速度和时钟频率、配置SDRAM 存储控制器及 IO、关闭处理器内部指令/数据 Cache 等;
   ② 为加载Bootloader 的 stage2 代码准备 RAM ;
   ③ 复制 Bootloader的 stage2 代码到 RAM 中;
   ④ 设置堆栈;
   ⑤ 跳转到 stage2的 C 函数入口点。

stage2 负责的主要任务有:
    ① 硬件设备的初始化(如串口、Flash和网卡等);
    ② 系统的内存映射检测;

    ③将内核映像从 Flash 读到 RAM 中;
    ④ 设置内核启动参数;
    ⑤ 调用内核。

Bootloader 调用内核的方法就是直接跳转到内核的第一条指令处。在调用内核之前下列的条件必须要满足:

(1) CPU 寄存器的设置

    ① R0 为 0;
    ② R1 为机器码;
    ③ R2 为启动参数,标记列表在RAM 中的起始基地址。

(2)CPU 工作模式
    ① 必须禁止中断( IRQ 和 FIQ);
    ② CPU 必须设置为 SVC 模式。

(3)Cache 和 MMU 的设置
    ① MMU 必须关闭;
    ② 指令 Cache 可以打开或关闭;
    ③ 数据 Cache 必须关闭。

 

4uboot简介

    U-Boot,全称Universal Boot Loader,遵循GPL 条款。为什么我们要选用U-Boot 作为Bootloader 呢?

    ①开放源码;
    ②对多种嵌入式操作系统内核的支持,如Linux、QNX等;
    ③对多个处理器系列的支持,如X86、PowerPC 、ARM等;
    ④较好的稳定性和可靠性;

    ⑤功能的设置较为灵活,适合U-Boot 调试、操作系统不同引导要求、产品发布等;
    ⑥丰富的设备驱动源码,如串口、以太网等。

 

5U-BOOT代码结构分析

U-BOOT目录下有多个子目录,分别存放管理不同的源程序。这些目录下所要存放的文件有其规则,可以分成三类:

第一类目录与处理器体系结构或者开发板硬件直接相关;

第二类目录是一些通用的函数或者驱动程序;

第三类目录是 U-BOOT 的应用程序、工具或者文档。

U-BOOT目录结构

board

本目录存放与已有开发板相关的文件。每种开发板有一个子目录,子目录仅存放与开发板相关的c文件和配置文件,不包含开发板CPU架构通用的实现文件。

common

实现基本命令,一条命令一个文件

CPU

与CPU 架构相关的目录,每款CPU或架构在一个子目录下。其中的子目录都是以 U-BOOT 所支持的 CPU 为名,比如有子目录 mips、 mpc8260等,每个子目录中都包括Makefile、config.mk、interrupt.c、cpu.c和serials.c和 start.S。

disk

对磁盘的支持

doc

文档目录

drivers

存放设备驱动程序的目录,mmc、串口等

examples

一些独立运行的应用程序的例子。

fs

支持的文件系统。如ext2、yaffs2、jffs2等文件系统

include

需要的头文件都在该目录下,和各种平台所支持的汇编文件,系统配置文件和对文件系统所支持的文件,其configs 子目录下与目标 板相关的配置头文件是移植过程中经常要修改的文件。

net

与网络协议栈相关的代码。BOOTP 协议、 TFTP 协议 RARP协议和 NFS 文件系统的实现。

lib

库文件

post

上电自检。

tools

生成U-BOOT的工具,例如mkimage等

 

后面分析uboot时的一些参考手册:

(1)ARM Architecture Reference Manual.pdf

(2)S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf

(3)S5PV210_UM_REV1.1.pdf


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

赢在中国 - 史玉柱经典语录

1.要重视建立销售手册2.凡是先做试点,风险才低。3.找到自己的细分市场。4.不要总想着同竞争对手对立,而是要想办法让自己弥补竞争对手的不足。5. 如果没有价格上的优势与技术上的绝对优势,千万不要进入红海市场,否则你会必输无疑&…

Utility.cpp的函数

C 对文件夹的安全权限操作 https://blog.csdn.net/zipper9527/article/details/6256459 https://blog.csdn.net/sz76211822/article/details/73199181 ZeroMemory https://baike.baidu.com/item/ZeroMemory/961326?fraladdin GetComputerName https://baike.baidu.com/item/G…

类中调用界面ActiveX控件报错当前线程不在单线程单元中因此无法实例化 ActiveX 控件的解决办法...

解决办法是Form类中定义一个静态的ActiveX对象,在formload中将界面上的ActiveX对象赋值给新定义的对象,类中访问该静态对象即可. public static AxClientDriver_NTLib.AxClientDriverCtrl com new AxClientDriver_NTLib.AxClientDriverCtrl(); private void Form1_Load(object…

我最近在学微信小程序开发,一起吗?

从当初的一夜成名,到今天火爆的市场占有率,微信小程序已走过 4 个年头。据今年 1 月阿拉丁发布的报告显示,微信小程序 2020 年 DAU 已破 4 亿,其总数超 380 万。最近有读者问我说,发哥,之前自己一直是个人…

回数

回数是指从左到右读和从右到左读都是一样的数,请利用filter()滤掉非回数(打印出1000内所有回数) def is_palindrome(n): return str(n)str(n)[::-1] # str(n)[::-1]代表字符串从后往前读,也代表字符串的翻转 output filter(is_palindrome,range(1,10…

初始化COM库

初始化COM库 CoCreateInstance //在本机中只创建一个对象 https://baike.baidu.com/item/CoCreateInstance QueryInterface 客户可以通过此函数来查询某个组件是否支持某个特定的接口 https://baike.baidu.com/item/QueryInterface SetNotifyWindow //注册一个窗口来处理事件通…

WebService大讲堂之Axis2(2):复合类型数据的传递

在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。数组与类(接口)是比较常用的复合类型。在Axis2中可以直接使用将WebService方法的参数或返…

Linux虚拟摄像头vivid配置

总述最近在看摄像头驱动,需要配置虚拟摄像头的驱动,但是教程里面是linux2.6内核的,实际电脑的是Ubuntu16,内核是linux4.15版本,从2.6到4.15内核好多文件发生了变化,所以我们该怎么操作呢?下面就…

第一次工作报告

要求 1. 对源文件(*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等)统计字符数、单词数、行数、词频,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。 2. 使用性能…

TQ210——S5PV210 uboot顶层mkconfig分析

################################################################################################# # SHELL常用内部参数:   # $# —— 传递给程序的总的参数数目 # $? —— 上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0&am…

音频系统底层API

IAudioEndpointVolume IAudioEndpointVolume接口表示进出音频端点设备的音频流的音量控制。 客户端通过调用参数iid设置为REFIID IID_IAudioEndpointVolume的IMMDevice :: Activate方法获取对端点设备的IAudioEndpointVolume接口的引用。 IAudioEndpointVolume编程调节Win7/Wi…

早睡早起

这两天考虑着以前工作的一些问题。有一点非常需要改正。就是作息时间不规律。经常睡的很晚。把前两年锻炼身体的老本吃的差不多了。该是“存钱”的时候了。新的工作依旧很繁忙,事情很多,但是身体调整绝对不能放松的。所以还是决定从明天开始早起&#xf…

树莓派Pico的一些有趣的基本实验

▲ 实验电路板Raspberry PI Pico小型MCU模块,以其价格低廉,功能丰富,开发方便为很多非电子类专业的同学进行创意项目原型设计提供了方便的平台。下面的一些实验给CDIE课程设计同学们制作的一些基本演示实验。▌01 PI Pico实验板在 RASPBERRY …

Gabor变换

gabor变换分析非平稳信号有弊端主要是时频窗宽度固定 小波wavelet a小窗窄a大窗宽 窗口或短时傅氏变换在时域上和频域上的局部化程度主要由窗函数g(x)的有效时宽Δt 和有效带宽Δf 决定。Δt 和Δf 越小, 表明局部性越好。但Heisenberg 测不准原理指出[ 6] :Δt 和Δf 不可能任…

30块钱的树莓派跑unix系统,源码全部开源,香

▌ 1、前言之前做活动抽奖送的几个树莓派,但是因为好几个人都没有填写地址,所以就只能把东西寄回来给我,然后手痒自己玩了下,觉得这个东西确实很香,比一般的Linux开发板都好。PICO这个开发板可以玩很多东西1 、运行pic…

CoInitialize\CoCreateGuid\CoCreateInstance

CoInitialize是Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。 https://baike.baidu.com/item/CoInitialize/4114580?fraladdin CoCreateGui…

产品设计体会(8001)产品经理工作手册

产品经理的工作是最具挑战性的工作之一。产品经理职责描述产品经理的全部责任在于通过了解不断变化的市场需求和优化产品推向目标市场的全过程,将企业的不同组成部分凝聚成一个战略上一致集中的整体,同时将一项产品的价值最大化。产品经理的全部职责在于…

Oracle11gR2_ADG管理之恢复主库的truncate表实战

备库开启flashback database #关闭备库的同步 SQL> alter database recover managed standby database cancel;Database altered.SQL> select flashback_on from v$database;FLASHBACK_ON ------------------ NOSQL> alter database flashback on;Database altered.SQ…

为什么大家都只谈薪资,却不谈梦想?

说个薪资的问题,最近在帮一个朋友物色工作,当然,除了我那个朋友以外,也有挺多同学向我咨询offer薪资的问题。先说我那个朋友。高中毕业后去当兵,服兵役结束后去4s店修车,我车子的很多问题也会向他咨询&…

获取指定地址的值

C语言 —— 获取指定地址的值 int b *((volatile unsigned int *)0x0028FF1C);// 0x0028FF1C就是内存中的地址&#xff0c;根据自己需要指定 #include <stdio.h> #include <stdlib.h>int main() {int b *((volatile unsigned int *)0x0028FF1C);printf("b…