uboot(一)

BootLoader指系统启动后,在操作系统内核运行之前运行的一段小程序。通过BootLoader,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的 BootLoader 几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。

BootLoader的操作模式一般分为自启动模式和交互模式。

自启动模式:BootLoaderd从目标机上的某个固态设备上将操作系统加载到RAM中运行,整个过程没有用户的介入;

交互模式:目标机上的BootLoader将通过串口或网络等通信手段从开发板上下载内核映像和根文件系统映像等到RAM中,可以写到目标机上的固态存储介质中,或者直接进行系统的引导。也可以通过串口接收用户的命令。

BootLoader基本功能:

初始化相关硬件;

把BootLoader自搬移到内存中;

执行用户的命令(访问环境变量;通过网络/串口通信;读写RAM/Flash);

加载并执行内核。

 一个嵌入式Linux系统从软件的角度看通常可以分为四个部分:BootLoader、Linux内核、跟文件系统及用户的应用程序。BootLoader处于系统的最底层,运行于系统启动的最初阶段。

系统加电或复位后,所有CPU都会从某个地址开始执行,这是由处理器设计决定的。比如,X86的复位向量在高地址端,ARM处理器在复位时从地址0x00000000取第一条指令。嵌入式系统的开发板都要把板上ROM或Flash映射到这个地址。因此,必须把Bootloader程序存储在相应的Flash位置。系统加电后,CPU将首先执行它。

 BootLoader的启动过程可以是单阶段的,也可以是多阶段的。多阶段一般比单阶段的提供更为复杂的功能,以及更好的可移植性。从固态存储设备上启动的bootloader大多数是二阶段的启动过程。

  BootLoader 的实现依赖于CPU的体系结构,因此大多数 BootLoader 都分为stage1 和stage2 两大部分。依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在 stage1中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而stage2 则通常用C 语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。

  BootLoader 的 stage1 通常包括以下步骤:

  ·硬件设备初始化;//屏蔽所有的中断、关闭处理器内部指令/数据Cache等

  ·为加载BootLoader的stage2准备RAM空间;

  ·拷贝BootLoader的stage2 到RAM空间中;

  ·设置好堆栈并将bss段清零;

  ·跳转到 stage2 的 C 入口点。

  Boot Loader的stage2通常包括以下步骤:

  ·初始化本阶段要使用到的硬件设备;

  ·检测系统内存映射(memory map);

  ·将内核映像和根文件系统映像从flash上读到 RAM 空间中;

  ·为内核设置启动参数;

  ·调用内核。

为什么bootloader的初始部分要用汇编?一种解释是有些操作必须用汇编实现,如协处理器寄存器的操作。更重要的问题在于,c程序需要一个具体的运行环境,如代码段,初始化的数据段,BSS段,栈,堆等。尤其是栈,它承担着C函数调用参数传递,局部变量的存储等工作。再者,启动时仅有Nand Flash的前4K内容在stepping stone中运行,这如何能保证C程序的完整性呢?因此,通常的做法是将第一阶段的汇编代码在单独的模块实现,并链接到程序的开始处。然后有它将完整的bootloader程序映像文件从Nand Flash中搬运至SDRAM中,并设置好上面谈到的各个段。这么以来,第二阶段的代码就会在SDRAM中运行。

第一阶段汇编代码的入口处,一般首先放置的是cpu异常的跳转代码,如IRQ,FIQ,SWI,Undef等。中断源将中断请求送至cpu的中断控制器,通过中断控制器仲裁,决定被响应与否或响应的顺序。例如IRQ异常,cpu会跳转到IRQ异常跳转指令处,该指令修改pc地址使其指向IRQ异常处理例程。在处理历程中,程序通过判断中断源的偏移量,确定该IRQ异常的具体类型,计算出这种IRQ异常的中断响应函数,这个过程是通过查阅IRQ中断向量表来实现的。IRQ中断向量表中定义了具体IRQ中断响应函数的地址,这些地址可以在第二阶段根据需要而设置,例如Timer的中断响应函数等等。

第二阶段首先做的是设置时钟。复位后,cpu使用外部时钟源,而非MPLL。通过设置MPLL,从而初始化HCLK,FCLK和PCLK,后者给cpu和外设提供稳定的时钟。接着可以对中断控制器和串口进行初始化,这样就可以通过串口向PC终端输出一些交互信息了。

接着打开MMU,指令缓存和数据缓存。这里可以设置协处理器CP15的Register 13(ProcID)为0,并建立从虚地址到物理地址的直接映射关系。

以上工作完成后,将存放于Nand Flash中的kernel和启动参数搬运到内存中的特定区域,重新设置好时钟(与内核中的保持一致),关闭MMU,指令缓存和数据缓存,跳转到内核的起始地址就可以运行了。

转载于:https://www.cnblogs.com/wangchaoguo-li/archive/2012/12/09/2810494.html

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

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

相关文章

linux+默认监听+目录,C# 时时监听目录文件改动

C# 时时监听目录文件改动:public static class DirectoryListen{public static string CountListXmlPath CountCore.CountListXmlPath;public static string DirectoryListenPath CountCore.ListenerAssemblyDirectory;[PermissionSetAttribute(SecurityAction.Demand, Name …

计算机简介

一、计算机简介: 1、计算机系统组成:软件和硬件,二者紧密相关,缺一不可 1.1硬件:计算机系统的物质基础,软件的载体 1.1.1硬件系统:主机(中央处理器(CPU,一般CPU由计算器和…

前端学习(612):js的三种书写位置

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><!--外部js写法--><…

linux内核 task cmd,linux内核

标签&#xff1a;1. 常见内核参数内核参数一般在/proc/sys 目录中临时改变某个系统参数的值&#xff0c;可以用两种方法来实现,如1) echo 1 > /proc/sys/net/ipv4/ip_forward2) sysctl -w net.ipv4.ip_forward1以上两种方法都可能立即开启路由转发功能&#xff0c;但如果系统…

分布式文件系统虚拟目录及命名空间的实现方法

分布式文件系统虚拟目录及命名空间的实现方法 http://www.doc88.com/p-717876372220.html 可以读一下&#xff0c;讲得还算清楚 转载于:https://www.cnblogs.com/hengli/archive/2012/12/12/2814342.html

Linux编译dhcpd,linux中搭建dhcpd服务器

这一次咱们来共同看一看如何在linux中搭建dhcp服务器&#xff1a;首先呢dhcp服务分为客户端IP地址动态分配服务和dhcp中继服务&#xff0c;小编在这里用linux系统搭建一个为客户端动态分配IP地址的dhcp服务器&#xff0c;dhcp中继就在路由器上做了(小编用了一台华为路由器R2621…

一张图说明我们为什么要关注 HTML5

转载于:https://www.cnblogs.com/h5rocks/archive/2012/12/12/2814692.html

linux自动读取麦克风,检测用户向麦克吹气

如果几年前你告诉我人们可以通过晃动手机或向麦克吹气使手机有所动作&#xff0c;我一定会大笑不止。但现在这已经是事实了。检查晃动动作是很直接的&#xff0c;所有这些在3.0“motion event”(动作事件)中都有介绍。检测向麦克吹气困难一点。本教程将建立一个简单的单视图程序…

动态绑定 datagridview

//绑定该邮箱到datagridviewint index this.dataGridViewSendEmail.Rows.Add();DataGridViewRow row this.dataGridViewSendEmail.Rows[index];row.Cells[1].Value emailAddr;row.Cells[2].Value "正常";row.Cells[3].Value DateTime.Now.ToString("yyyy-M…

linux中端口的欺骗,Linux中的端口占用问题

本文将会阐述两种解决端口占用的方法。本文会用到的服务器端的程序如下&#xff1a;1 #include "unp.h"2 #include 34 int main(int argc, char **argv)5 {6 intlistenfd, connfd;7 socklen_t len;8 structsockaddr_in servaddr, cliaddr;9 charbuff[MAXLINE];10 tim…

oracle维护常用SQL语句(查看系统表和视图)

转:http://www.360doc.com/content/11/1230/15/7489308_176090474.shtml oracle维护常用SQL语句(查看系统表和视图) 1.查看表空间的名称及大小 select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size   from dba_tablespaces t, dba_data_files d   wher…

Asp.net 调用mysql存储过程参数传中文乱码!

<add name"xxx" connectionString"server10.10.xx.xx;User Idxxx;passwordxxxx;databasexxxx;Port3306;character setutf8;"/> 在web.config中进行编码设置&#xff1a;character setutf8; 调用存储过程方法&#xff1a;MySqlCommand cmd new MySql…

手机内存卡转化linux,Android 往手机内存卡上存储用户名与密码的操作

当大家 用Android 应用 操作时&#xff0c;会发现有很多应用要登陆名和密码&#xff0c;而且&#xff0c;它们都能记住密码&#xff0c;当你退出 &#xff0c;再次登陆时&#xff0c;你们帐号密码会自动添加上去。例&#xff1a;布局文件 相信都能做出来 就不一一介绍 了。下面…

Mplayer 音频解码分析

一.序 还是按部就班的来&#xff0c;这次主要分析一下Mplayer中音频解码流程&#xff0c;特别说明一下&#xff0c;这里 的音频解码包括后面会说的视频解码统统不涉及到具体的格式和解码算法&#xff0c;如果大伙对具 体文件格式和解码感兴趣可以在网上找相关资料看看~也可以留…

Linux格式化sd卡博客,linux设备驱动那点事儿之SD卡驱动理论篇

一.SD/MMC卡介绍1.1.什么是MMC卡MMC&#xff1a;MMC就是MultiMediaCard的缩写&#xff0c;即多媒体卡。它是一种非易失性存储器件&#xff0c;体积小巧(24mm*32mm*1.4mm)&#xff0c;容量大,耗电量低,传输速度快&#xff0c;广泛应用于消费类电子产品中。1.2.什么是SD卡SD&…

SQL Server 2008 数据库同步的两种方式 (发布、订阅)

通过SQL JOB的方式对数据库的同步&#xff0c;这一节作为上一节的延续介绍通过发布订阅的方式实现数据库之间的同步操作。发布订阅份为两个步骤&#xff1a;1、发布。2、订阅。首先在数据源数据库服务器上对需要同步的数据进行发布&#xff0c;然后在目标数据库服务器上对上述发…

前端学习(619):变量的小案例二

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><script>//请输入姓名…