U-BOOT全线移植分析系列之一 ――BOO…

本文详细介绍了bootloader的基本概念、移植必要性、烧录存储、操作模式、与主机通信方式以及通用执行流程。重点阐述了bootloader如何在特定硬件平台上正确调用内核,以及其在嵌入式设备中的作用。
U-BOOT全线移植分析系列之一

――――BOOTLOADER介绍



【摘要】本节介绍了bootloader的基本概念。首先分析了为什么要针对特定的CPU和开发板移植bootloader的必要性。然后介绍了两种如何在裸板中烧写bootloader的方法以及如何确定烧写地址。其次介绍了产品发布的启动加载模式和开发使用的下载模式(更新内核文件系统及 bootloader自身)。最后介绍了bootloader的两个通用启动阶段的流程及代码特性和运行位置。

【关键词】bootloader,烧写,复位地址,固化loader,启动加载,stage1,位置无关

一 bootloader介绍

1.1 Bootloader移植的必要性
Bootloader是与系统硬件环境高度相关的初始化软件,它担负着初始化硬件和引导操作系统的双重责任。一些ARM平台可以共用同一种Bootloader,但是总的说来,每一个特定系统的Bootloader都会有所不同。 Bootloader广泛用于有操作系统的手持终端设备、智能家电及机顶盒等嵌入式设备上,它负责完成硬件初始化、操作系统引导和系统配制等。 Bootloader移植是在特定硬件平台上操作系统移植至关重要的一步。



1.2 BootLoader所支持的CPU和嵌入式系统板
每种不同的CPU体系结构都有不同的BootLoader。有些 BootLoader也支持多种体系结构的CPU,比如U-BOOT就同时支持ARM、MIPS、POWERPC等体系结构。除了依赖于CPU的体系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行在一块板子上的BootLoader程序也能运行在另一块板子上,通常也都需要修改BootLoader的源程序。



1.3. Boot Loader的烧录和存储
系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。比如,at91rm9200的CPU在复位时通常都从地址0x00000000取它的第一条指令。而MPC8260高端启动则时从0xfff00000开始取指。这个地址依据特定的CPU而定。通常片外启动时,基于CPU构建的嵌入式系统通常都有某种类型的固态存储设备(EEPROM或FLASH 等,at91rm9200是0x10000000)被映射到这个预先安排的地址上。因此在系统加电后,CPU将首先执行Boot Loader程序。



那么bootloader最初是怎么烧写到flash中的呢?对于一个裸板怎么让它跑起来呢?有两种方式:

?????? 通过片内固化的loader加载bootloader:通常某些CPU内部ROM中固化了一段程序可以用于最初的程序下载,如AT91RM9200。这时下载的程序是在内部RAM中运行的,大小有一定限制,然后由这段程序继续交互下载真正要烧写到flash中的程序,将其保存在外部RAM中,最终烧写到 flash中。

?????? 通过JTAG或者仿真器下载:通常这些烧录工具可以直接操作flash,对其进行编程烧录。需要专门的工具。这种情况多用于那些没有固化loader的CPU,如三星系列。




上图是一个同时装有Boot Loader、内核的启动参数、内核映像和根文件系统映像的固态存储设备的典型空间分配结构图。上述顺序是可变的,但bootloader首地址一定要在CPU复位取指的地址上。



1.4 Boot Loader的操作模式(Operation Mode)
主机和目标机之间一般通过串口建立连接,BootLoader软件在执行时通常会通过串口来进行数据传输,如输出打印信息到串口,从串口读取用户控制字符。



大多数Boot Loader都包含两种不同的操作模式:启动加载模式和下载模式,这种区别仅对于开发人员才有意义。从最终用户的角度看,BootLoader的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。

?????? 启动加载(Boot loading)模式:这种模式也称为自主模式bootstrap。也即Boot Loader将存储在目标板Flash中的内核和文件系统的镜像装载到SDRAM中,整个过程无需用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时候,BootLoader显然必须工作在这种模式下。

?????? 下载Downloading模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从宿主机Host下载文件,比如下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的 FLASH类固态存储设备中。BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新(bootloader自身也可以这样更新)也会使用Boot Loader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一些简单的命令行接口。



像U-BOOT等这样功能强大的BootLoader通常同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。比如,U-BOOT 在启动时处于正常的启动加载模式,但是它会延时几秒(在配置文件中可以设定)等待终端用户按下任意键而将其切换到下载模式(相当于bios下按del键可进入系统配置界面一样,设置从光盘启动可进行重装),如果在给定时间内没有用户按键,则U-BOOT继续启动,进行正常的启动加载。



1.5 Bootloader与主机之间进行文件传输所用的通信设备及协议
最常见的情况就是,目标机上的BootLoader通过串口与主机之间进行文件传输,传输协议通常是kermit / xmodem / ymodem协议中的一种。但是,串口传输的速度是有限的,因此如果该Bootloader对目标板的网卡支持良好,还可以通过以太网连接并借助TFTP (Trivial File Transfer Protocol)协议来下载文件是个更好的选择。此时,主机方所用的软件也要考虑,比如,在通过以太网连接和TFTP协议来下载文件时,主机方必须有一个软件用来提供TFTP服务,如Windows平台上的tftpd.exe等或Linux下面的tftp服务器。



1.6 Bootloader的通用执行流程

从操作系统的角度看,Bootloader的总目标就是正确地调用内核来执行。另外,由于Bootloader的实现依赖于 CPU的体系结构,因此大多数Bootloader都分为stagel和stage2两大部分。依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在stagel中,而且通常都用汇编语言来实现,以达到短小精悍和高效的目的。而stage2则通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。



Bootloader的stagel为位置无关代码,通常在FLASH中运行。所有的指令为相对寻址,可以在任何位置运行。通常包括以下步骤(以执行的先后顺序):

??????? 硬件设备初始化(配置SDRAM存储控制器及IO),中断初始化;

??????? 为加载Bootloader的stage2准备RAM空间(这个地址由链接脚本指定,为运行域地址,通常为RAM的高端地址),测试内存空间是否有效;

??????? 拷贝Bootloader的stage2到RAM空间中;

??????? 设置好堆栈;

??????? 跳转到stage2的C入口点。



Bootloader的stage2通常被拷贝到RAM中运行,这样可以提高运行速度。通常包括以下步骤(以执行的先后顺序):

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

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

??????? 没有用户干预时将kernel映像和根文件系统映像从flash读到RAM空间中;

??????? 为内核设置启动参数;

??????? 调用内核。
下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
源码来自:https://pan.quark.cn/s/a4b39357ea24 在VC++开发过程中,对话框(CDialog)作为典型的用户界面组件,承担着与用户进行信息交互的重要角色。 在VS2008SP1的开发环境中,常常需要满足为对话框配置个性化背景图片的需求,以此来优化用户的操作体验。 本案例将系统性地阐述在CDialog框架下如何达成这一功能。 首先,需要在资源设计工具中构建一个新的对话框资源。 具体操作是在Visual Studio平台中,进入资源视图(Resource View)界面,定位到对话框(Dialog)分支,通过右键选择“插入对话框”(Insert Dialog)选项。 完成对话框内控件的布局设计后,对对话框资源进行保存。 随后,将着手进行背景图片的载入工作。 通常有两种主要的技术路径:1. **运用位图控件(CStatic)**:在对话框界面中嵌入一个CStatic控件,并将其属性设置为BST_OWNERDRAW,从而具备自主控制绘制过程的权限。 在对话框的类定义中,需要重写OnPaint()函数,负责调用图片资源并借助CDC对象将其渲染到对话框表面。 此外,必须合理处理WM_CTLCOLORSTATIC消息,确保背景图片的展示不会受到其他界面元素的干扰。 ```cppvoid CMyDialog::OnPaint(){ CPaintDC dc(this); // 生成设备上下文对象 CBitmap bitmap; bitmap.LoadBitmap(IDC_BITMAP_BACKGROUND); // 获取背景图片资源 CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap* pOldBitmap = m...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值