S5PV210开发系列三

简易Bootloader的实现

象棋小子          1048272975

Bootloader是嵌入式系统上电后第一段运行的代码。对于功能简单的处理器,可能并没有Bootloader的概念,但对于应用处理器,有不同的启动方式。不同的存储设备(Nand flash、sd/mmc、DDR2、SRAM等)。不同的操作系统等,往往须要一个Bootloader先初始化CPU和相关的硬件,建立内存空间映射,把内核或应用程序载入到对应的内存运行位置。最后调用内核或应用程序,释放CPU控制权,完毕整个Bootloader的流程。

笔者此处就S5PV210的Bootloader实现作一个简单的介绍。

1. Bootloader流程

Bootloader是严重依赖于详细硬件实现的,同样CPU内核架构。不同厂商生产的处理器其Bootloader都是全然不一样的,即使对于同一CPU,板载不同的硬件配置。往往都是要针对性实现其Bootloader。因此。Bootloader的功能、流程等都没有特定的要求,仅仅要将系统的软硬件环境带到一个合适的状态。终于为操作系统内核或应用程序准备好正确的环境就可以。一般对于一个Bootloader应实现两种不同的操作模式:启动载入模式和下载模式。

启动载入模式就是Bootloader从设备系统的某个固态储存器中将操作系统或应用程序载入进RAM,整个过程无需用户的介入,这样的模式是设备成型后Bootloader的正常工作模式。下载模式是Bootloader能够通过串口、USB或网络等通信手段从主机下载文件,并终于写入到到设备系统的某个固态储存器中,这样的模式用在设备开发调试中,用于刷机升级。此处笔者从自己的角度简介Bootloader实现的一般流程。

与Bootloader相关的代码文件放在System文件夹文件夹中。文件夹架构例如以下:

  • s5pv210.s,启动代码文件,代码执行时的入口,控制了整个Bootloader的执行流程,终于建立起c执行环境后。进入到应用程序main入口。

  • LowLevelInit.s,板级初始化代码,包含CPU时钟的初始化、DDR2内存控制器初始化、代码载入实现(sd/mmc卡启动、Nand flash启动)。
  • Coprocessor.c,协处理器相关代码,主要是CP15协处理器L1 Cache、L2 Cache、MMU内存映射、中断向量基址等操作代码。

  • NandBoot.c,实现Nand flash启动相关Nand驱动代码。实现对应Nand代码下载、Nand代码启动的接口实现。
  • Download.c,实现代码下载调试功能,支持代码直接下载内存调试执行,支持代码下载进Nand flash,支持uboot的内存下载执行调试以及Nand下载固化。
  • Exception.c。异常处理相关代码。支持中断处理的完整架构。如中断嵌套处理、中断注冊、中断开启等接口实现。为系统应用架构实现。
  • Retarge.c,标准IO的底层重定向,支持c库中的标准IO函数,如标准输入、输出流重定向到串口、文件操作重定向到对应的文件系统接口实现等,为系统应用架构实现。
  • s5pv210.icf,IAR下链接文件,指定板载内存范围。代码以及RAM等布局。

这里笔者说明一下,在建立c执行环境之前的Bootloader代码均是地址无关的,CPU上电后会载入部分的Bootloader代码到内部RAM执行,不论什么RAM地址这部分Bootloader均应能正确执行。Bootloader中不要尝试调用c库函数。注意在Bootloader的c代码c执行环境也是不成立的。在Bootloader中应初始化最关键的硬件环境,其他不紧要的硬件初始化或功能代码能够放到c执行环境建立后处理。

1.1. 异常向量表

ARM核在异常发生时。会从异常向量表中取得对应的异常向量地址运行,发生IRQ中断则从异常向量表0x18偏移处取得IRQ异常向量地址。

异常向量表就是用来记录各个异常进入时的代码处理位置。除了Cortex-M处理器有嵌套向量中断控制器(NVIC),下面的异常向量处理对全部系列的ARM核均是成立的。

ARM

__iar_program_start

BLX Reset_Handler

LDR PC, Undef_Addr

LDR PC, SWI_Addr

LDR PC, PAbt_Addr

LDR PC, DAbt_Addr

LDR PC, Notuse_Addr

LDR PC, IRQ_Addr

LDR PC, FIQ_Addr

DCD 0x55aa55aa ; 0x20位置用来推断代码的执行区域

Undef_Addr

DCD Undef_Handler

SWI_Addr

DCD SWI_Handler

PAbt_Addr

DCD PAbt_Handler

DAbt_Addr

DCD DAbt_Handler

Notuse_Addr

DCD 0          ; Reserved Address

IRQ_Addr

DCD IRQ_SaveContext

FIQ_Addr

DCD FIQ_Handler

IRQ_SaveContext

; 保存中断上下文,支持中断嵌套

SUB LR, LR, #4 ; 计算返回地址

STMFD SP!,{R0-R12, LR} ;全部寄存器压栈保存

MRS R0, SPSR ; 保存中断前的CPSR(即如今的SPSR)

STMFD   SP!, {R0} ;

MSR CPSR_cxsf, #Mode_SYS+I_Bit ; 切换到系统模式

STMFD   SP!, {LR} ; 压栈系统模式LR

LDR R0, =IRQ_Handler ;系统模式下进行IRQ代码处理

BLX R0 ; 调用中断处理函数

LDMFD   SP!, {LR} ; 出栈系统模式LR

MSR CPSR_cxsf, #Mode_IRQ+I_Bit ; 切换到IRQ模式

LDMFD   SP!, {R0} ; 返回中断前的CPSR

MSR SPSR_cxsf, R0

LDMFD  SP!, {R0-R12, PC}^ ; ^表同一时候从spsr恢复给cpsr

PUBWEAK Undef_Handler

PUBWEAK SWI_Handler

PUBWEAK PAbt_Handler

PUBWEAK DAbt_Handler

PUBWEAK IRQ_Handler

PUBWEAK FIQ_Handler

Undef_Handler

SWI_Handler

PAbt_Handler

DAbt_Handler

IRQ_Handler

FIQ_Handler

B   .

1.2. 关看门狗

复位代码最先做的事应该是关看门狗,由于假设看门狗打开的话,在启动代码进行初始化过程中是无法喂狗的,可能造成处理器一直不停复位。

; 看门狗关闭

LDR R0, =WT_BASE

LDR R1, =0

STR R1, [R0]

1.3. 关闭全部中断

启动代码未完毕时。各个状态都还不是确定的。假设有中断打开并引起中断异常。可能造成代码跑飞。

; 关闭全部外设中断

LDR R1,=0xFFFFFFFF

LDR R0,=VIC0_BASE

STR R1,[R0, #INT_EN_CLR_OFS]

LDR R0,=VIC1_BASE

STR R1,[R0, #INT_EN_CLR_OFS]

LDR R0,=VIC2_BASE

STR R1,[R0, #INT_EN_CLR_OFS]

LDR R0,=VIC3_BASE

STR R1,[R0, #INT_EN_CLR_OFS]

1.4. 初始化协处理器

ARM核可最多支持16个协处理器,当中一般内置了CP14调试通信协处理器以及CP15系统控制协处理器。在Bootloader中须要对实际的寄存器物理地址进行初始化读写,因此应初始化CP15协处理器关闭Cache、关闭MMU、设置中断向量表基址等。

; 初始化协处理器

EXTERN Coprocessor_Init

BLX Coprocessor_Init

1.5. 初始化系统时钟

一般来说。处理器复位后都是执行在一个较低速的时钟下。为加快启动。通常尽可能快地设置处理器的各个时钟。

; 系统时钟设置

EXTERN      Clock_Init

BLX Clock_Init

1.6. 初始化外部内存

除了Nor flash能够直接运行代码外。其他的代码存储器如nand flash、sd/mmc都是不能直接运行代码的。

一般对于应用处理器。代码都是载入进RAM后运行。

; 外部内存控制设置

EXTERN  ERAM_Init

BLX ERAM_Init

LDR SP,=SFE(CSTACK) ; RAM初始化后调整栈指针到外部RAM

1.7. 下载模式

在调试开发阶段,能够通过直接下载代码到RAM调试运行,避免反复地烧写固态存储器,加快调试开发,在确定代码OK后,再把代码下载进固态存储器(Nandflash)就可以。

在开发完毕后,下载模式代码可凝视掉。

; 检查是否进入串口下载模式,开机时按住空格键进入串口下载模式

EXTWEAK DownloadCheck

BLX DownloadCheck

1.8. 代码载入

对于代码存储在Nand flash、sd/mmc等不能直接运行代码的存储器,Bootloader是一定须要把用户代码从这些设备读入到特定的内存中运行的。

而对于Nor flash可直接运行代码的存储器。通常为了提高性能,也是会把代码从Nor flash读出,在内存中运行的。

; 拷贝用户代码到RAM

EXTERN      CopyCodeToRAM

BLX CopyCodeToRAM

1.9. MMU内存映射

为了提高CPU的处理性能。MMU必须开启,在开启之前。需先建立对应的内存空间映射表,设置对应的内存区域訪问权限等。开启MMU后。也必须同一时候开启L1 I/D Cache、L2 Cache、硬件分支预測功能。不然CPU的性能将极其低下。有几十倍的性能差异。

; MMU初始化

EXTERN      MMU_Init

BLX MMU_Init

1.10. 初始化栈

ARM核有多种工作模式。每种模式的栈是一定要分配及初始化的。这样才干在对应模式下正确地运行代码。

; 堆栈初始化

;  Enter Undefined Instruction Mode and set itsStack Pointer

LDR R0,=SFE(UND_STACK)

LDR R1,=Mode_UND+I_Bit+F_Bit

MSR CPSR_c,R1

MOV SP,R0

;  Enter Abort Mode and set its Stack Pointer

LDR R0,=SFE(ABT_STACK)

LDR R1,=Mode_ABT+I_Bit+F_Bit

MSR CPSR_c,R1

MOV SP,R0

;  Enter FIQ Mode and set its Stack Pointer

LDR R0,=SFE(FIQ_STACK)

LDR R1,=Mode_FIQ+I_Bit+F_Bit

MSR CPSR_c,R1

MOV SP,R0

;  Enter IRQ Mode and set its Stack Pointer

LDR R0,=SFE(IRQ_STACK)

LDR R1,=Mode_IRQ+I_Bit+F_Bit

MSR CPSR_c,R1

MOV SP,R0

;  Enter Supervisor Mode and set its StackPointer

LDR R0,=SFE(SVC_STACK)

LDR R1,=Mode_SVC+I_Bit+F_Bit

MSR CPSR_c,R1

MOV SP,R0

;  Enter System Mode and set its Stack Pointer

LDR R0,=SFE(CSTACK)

LDR R1,=Mode_SYS

MSR CPSR_c,R1

MOV SP,R0

1.11. 初始化c执行环境

进入c入口之前是须要初始化c环境的,如清0全局变量、静态变量区等。此处直接利用编译器的库函数__cmain来完毕c环境的初始化,最后才是真正的应用程序入口main函数。用绝对地址跳转到c入口__cmain,Bootloader释放CPU控制权,完毕整个流程。

; Initialize VFP (ifneeded).

EXTERN __iar_init_vfp

LDR R0,=__iar_init_vfp

BLX R0

; Continue to ?

mainfor C-level initialization.

EXTERN  __cmain

LDR R0,=__cmain

BX  R0

2. 代码烧写

代码能够存储在Nand flash或sd/mmc卡中。一般先把代码烧写进sd/mmc卡中,这样无需复杂的操作以及昂贵的烧录器等。

sd/mmc卡启动后通过里面的Bootloader下载功能把主机上的对应代码下载进设备的Nand flash上,之后无需再用sd/mmc卡,设置Nand flash启动。代码更新也通过Nandflash上的Bootloader下载更新就可以。

sd/mmc卡启动须要专用的烧录软件SdBoot。SdBoot.exe为笔者在windows下针对三星S3C2416和S5PV210这两个平台开发的sd/mmc启动烧录工具。sd/mmc启动须要对应的代码格式以及需烧录进sd/mmc卡指定的位置。SdBoot.exe工具集代码格式转换以及sd/mmc卡烧录于一体,能够烧录S3C2416和S5PV210这两个平台下笔者编写的裸机bootloader,wince bootloader,uboot,工具简单易用。

图2-1 SdBoot.exe工具

3. Bootloader下载功能

Bootloader通过串口实现主机代码文件的下载,主机端代码下载须要三星专用的工具dnw.exe工具,连接好串口后。按住空格键后,目标板上电会进入Bootloader的下载模式。

图3-1 Bootloader下载模式

当中选项1能够基于笔者Bootloader开发的应用。下载进RAM,并直接调试执行。下载进RAM的代码均是编译器直接编译出来的代码。未经过SdBoot工具格式转换。

选项2用于uboot的调试开发。能够直接把编译好的uboot二进制代码下载进RAM,并直接调试执行。

选项3用于代码烧录进Nand flash,把通过SdBoot工具格式转换后的基于笔者Bootloader应用代码、uboot代码下载进Nand flash,之后设置Nand flash启动就可以。

4. Bootloader功能

笔者的S5PV210的Bootloader设置最高的CPU主频1GHZ。MMU进行1:1内存空间线性映射,并开启L1 I/D Cache、L2 Cache、硬件分支预測功能。使CPU能达到最大的吞吐量性能。初始化内存,可以识别sd/mmc启动和Nand flash启动,自己主动载入应用代码到RAM位置。统一的中断管理架构、重定向底层IO操作,可以更加专注于应用的开发。

5. 附录

Bootloader.rar,Bootloader下IAR測试project以及SdBoot工具。

http://pan.baidu.com/s/18pFhs

S5PV210开发系列三_简易Bootloader的实现的更多相关文章

  1. S5PV210开发系列四_uCGUI的移植

    S5PV210开发系列四 uCGUI的移植 象棋小子          1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...

  2. BizTalk开发系列(三十三)BizTalk之Excel终极解决方案

    Excel作为优秀的客户端数据处理程序得到了广泛的应用. 由于其简单又强大的功能在很多公司或个人的数据处理中占用非常重要的位置. 而BizTalk作为微软的SOA主打产品虽然免费提供了很多Adapte ...

  3. Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息

    前面我们介绍了枚举系统中的U盘盘符(见<Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>).以及获取USB设备的信息(见<Windows下USB磁盘开发系列二:枚举系统中 ...

  4. 【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计

    这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3. ...

  5. leaflet-webpack 入门开发系列三地图分屏对比(附源码下载)

    前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...

  6. BizTalk开发系列(三十八)微软BizTalk Server定价和许可[解读]

    做BizTalk的项目一段时间了,但是对BizTalk的价格和许可还不是很了解.给客户设计解决方案时大部分产品都是直接按照企业版的功能来设计,很 少考虑到价格和许可方面的因素,以为这个不是我们的事情或 ...

  7. BizTalk开发系列(三十二)浅谈BizTalk主机性能优化

    很多BizTalk的项目都要考虑到性能优化的问题,虽然BizTalk采用多线程处理消息的,大大提高了程序效率.但默认情况下 BizTalk的主机有很多阻止参数会控制BizTalk对服务器的资源使用率, ...

  8. BizTalk 开发系列(三十九) BizTalk Server 2009技术概览

    BizTalk Server 2009已经发布一段时间了,之前Beta版发布的时候也写过一篇文章<BizTalk Server 2009 Beta初体验>, 当时比较了2006 R2与20 ...

  9. BizTalk开发系列(三十七) 性能监视器在BizTalk性能测试中的使用

    BizTalk应用程序的性能测试和分析是一个非常重要的过程,因为BizTalk的应用程序在Run-time时受部署结构.消息请求数量和消息大小等 的影响很大,因此无论是简单还是复杂的的应用都需要在部署 ...

随机推荐

  1. QT学习笔记7:C++函数默认参数

    C++中允许为函数提供默认参数,又名缺省参数. 使用默认参数时的注意事项: ① 有函数声明(原型)时,默认参数可以放在函数声明或者定义中,但只能放在二者之一.建议放在函数声明中. double sqr ...

  2. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  3. BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)

    题目链接 线性基可以\(O(log^2)\)暴力合并.又是树上路径问题,考虑点分治. 对于每个点i求解 LCA(u,v)==i 时的询问(u,v),只需求出这个点到其它点的线性基后,暴力合并. LCA ...

  4. HTTP 499 状态码 nginx下 499错误[转]

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

  5. PAT甲级1131. Subway Map

    PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...

  6. AbstractAction

    package cn.tz.action.abs; import java.io.File; import java.io.IOException; import java.text.SimpleDa ...

  7. 怎么样退出vi/vim编辑器

    怎么样退出vi/vim编辑器 先按   ESC   然后输入  w  q  :wq 就退出来了

  8. Perforce-Server迁移

    Author: JinDate: 20140827System: Windows 2008 R2 从Windows 2008 R2迁移到Windows 2008 R2 linux版本迁移官方文档htt ...

  9. 详解Linux中CentOS6.8下解压安装mysql-5.7.14

    原文:http://blog.csdn.net/yangle4695/article/details/52185859 mysql下载地址:http://dev.mysql.com/downloads ...

  10. wrap ConcurrentDictionary in BlockingCollection

    ConcurrentDictionary<int, BlockingCollection<string>> mailBoxes = new ConcurrentDictiona ...