首页 >> 阀体

基于ARMll的精简BootLoader治具

时间:2022/07/14 16:28:52 编辑:

基于ARMll的精简BootLoader的设计

嵌入式系统的启动设备主要有三种,分别是NORFLASH,NAND FLASH以及SD卡,可通过配置引脚的不同状态确定启动设备。由于SD卡烧写方式不依赖JTAG和并行接口,以及其可插拔的特点,故其应用更加广泛和便捷,大大提高了调试的效率。本文研究基于S3C6410硬件平台,启动方式为SD卡启动。

1 开发环境介绍

本文基于SC36410硬件平台,S3C6410是三星公司推出的基于ARMl微处理器的一款高端开发板,专为多媒体消费类电了产品的开发而设计。S3C6410采用了64/32位内部总线架构,由AXl、AHB和APB总线组成,内置视频处理、音频处理、2D图形、3D图形等硬件加速器。本文软件开发环境基鼓励建立以优势企业为龙头于Linux操作系统Ubuntu一9.10,ARM嵌入式交叉工具链、scratchbox2、minicom、kermit等软件开发包。

2 ARM汇编程序编程要点

(1)位置无关性代码PIC(position-IndependentCode)

对于C、C++以及其他类似语言编写的程序,要经过编译、汇编、链接才成为可执行程序。在链接阶段编译器会给数据、函数等分配相应的内存地址。在有操作系统的系统环境中,编译阶段分配的地址和程序运行时候的物理地址通常是不一样的,这种情况并不会产生错误。因为现代CPU体系结构一般都有MMU模块,操作系统以保护模式的方式运行而非实地址模式,提供给CPU使用的地址需要经过MMU页表映射才能得到相应的物理地址。而Bootloader是为正确加载操作系统前初始化硬件的一段程序,一般情况下嵌入式的Bootloader是没有开启MMU的,所以要让Bootloader正确运行,在链接阶段产生的地址应该和运行时候的物理地址是一致的才行。

ARM体系架构的指令集采用的是RISC指令集,内存和CPU寄存器之间交换数据通过LDR/STR及其扩展指令来实现的,在链接阶段产生的地址和运行时候的物理地址不相同时,如果指令中地址值的编码计算方式是通过绝对值地址取得的时候就会产生不可预知的错误。在实际应用中,嵌入式Bootloader以及Linux启动代码采用汇编编写的程序中很多地方的链接阶段分配的地址和运行时候的物理地址不相同,但是程序却可以正确运行。这是因为这部分代码是位置无关件代码,其原理是指令所存放的内存地址是根据PC指令的偏移方式计算出来的,和链接阶段产生的地址无关。地址无关件代码用途很广,最常用的是程序的起始阶段通过地址无关件代码,实现代码的重定向功能。我们可根据ARM指令的编码方式,确定哪些是地址无关件的指令,编写出地址无关件的程序。

(2)AAPCS规范

AAPCS文档描述了基于ARM体系结构下的应用程序二进制接U的过程调用标准,该文档包含了第五次修订版的APCS和第三次修订版的TPCS规范的主要内容。同时支持Thumb和ARM指令,Thumb和ARM指令运行状态之间的切换,以及ARM体系结构高性能的执行效率是AACPS规范的目标。在编写程序时,要想生成一致件的机器代码,必须遵循AAPCS的一致性要求。本文在编写程序时,在ARM汇编中调用了C语言中的函数,属于混合编程。所以要使程序能够分别编译并且链接成功,以及正确运行,那么在对寄存器的使用,函数调用参数的传递和返叫,栈的保存等方面都必须按照AAPCS的规范来编程。

3 嵌入式引导加载程序的设计

引导加载程序是系统上电后,最先运行的一段初始化程序代码,其主要功能是初始化硬件设备并建立内存空间的映射图,为调用操作系统内核或应用程序建立止确的环境。引导加载程序一般分为两个阶段:第一个阶段主要是和CPU体系结构等硬件密切相关的代码,大部分用汇编语言完成;第二个阶段和板级配置相关的代码,主要用C语言编写。在嵌入式领域非常流行的一款开源软件是Bootloader,然而U-BOOT并不支持中断的功能,其最显著特点就是主机不能ping通目标机。要实现这个功能,一种方式是用轮询,另一种方式是采用中断。国内一款优秀的开源软件g-bios在S3C24X0、ATMEL926X实现了中断,S3C6410采用的是轮询的方式。本文设计了一种精简的嵌入式Bootloader,以最小的代码量来研究嵌入式的加载程序的实质。

(1)建立中断向量表

ARM体系结构提供了多种方法实现中断的功能,其中之一就是建立中断向量表。S3C6410上电后,映射地址从0xoc000000开始,而不是从0x地址开始的,这点和S3C24x0系列甲台有所不同。S3C6410设置中断向量表研究办法如下:

一种方法是开启MMU,建立页表,实现地址重定向功能。另外,在ARM V5以上架构的CPU,ARM的中断向量表不仅可以映射在Ox~0xC低地址,而且可以映射到OxFFFF0000~OxFFFF0001C。通否则将致使传感器精度偏差过大或致坏过设置协处理器CPl5寄存器1的第十三位的值便可设定中断向量表是映射在低地址卒间还是高地址空间。对于IRQ和FIQ模式,ARM架构还提供了在执行时定义这两个模式的地址映射的空间。通过设置协处理CPl5寄存器1的第二十四位的值可实现Bootloader中断功能。然而,无论是映射在低地址空间还是高地址空间,映射的内存范围都不包含SRAM或者SDRAM芯片挂载的内存空间。由于开启MMU过程入过复杂,而本文的目的是设计一个精简的boofloader,权衡考虑,放弃建立中断向量表。

(2)LED点亮控制

在裸机环境下,调试程序是一件很困难的事情;另一方面,本实验下台设有建立ARM的中断向量表,所以无法捕捉到程序出现了何种异常,加大了程序调试的难度。本文通过在程序的不同阶段对LED点亮进行控制,对程序的调试起到了一定的辅助作用。通过对相应的Gpi0管脚的电平写操作即可完成对LED的控制。

(3)看门狗和相关总线的时钟初始化

系统加载程序需要关闭看门狗,关闭看门狗的编程和LED的点亮控制一样简单。S3c6410的相关总线要比A3c24x0系列复杂,在编程实现的时候也相应的更复杂。如果不考虑功耗的因数,正确设置总线时钟的初始化值是很多的,一步一步按照Datasheet的要求实现即可。

(4)串口编程和kermit串口协议实现

串口控制器的初始化包括时钟初始化、波特率的设置、数据收发以及状态寄存器的编程等。在kermit串口协议的实现中,数据的读写是对串口控制器的数据收发寄存器以及状态寄存器的编程。

(5)SDRAM的初始化

本文采用的是SD启动方式,系统上电后,第一条指令运行在0xc000000地址上。S3c6410的0xc000000映射的是一块SRAM,SRAM不需要初始化设置,通过运行在SRAM上的程序完成必要的硬件初始化。如果本文的加载程序加载一段非常小的程序,可以将其直接加载到SRAM的地址空间,不需要对SDRAM进行编程。如果要加载比较大的程序则必须要对SDRAM进行初始化,将程序加载到SDRAM的地址空间。

(6)精简嵌入式Bootloader的实现

本文实现的嵌入式精简Bootloader由s3c6410.h、s3c6410.S、kermit.C、boot.1ds、Makefile组成。s3c6410.h包含了大量关于地址的宏定义,s3c6410.S和kermit.C是核心部分,为本文第三部分的设计的实现,其中kermit.C为kermit串口协议的实现,boot.1ds为链接脚本,Makefile为程序的自动编译脚本。

s:

(7)烧录和测试

用SD卡的烧写软件将编译出来的s3即ASTMF2913⑴1电脑式止滑实验机n烧录到SD卡,将SD插入开发板的SD卡插槽准备测试。在测试前需要编写一个程序作为串口下载的测试程序,本文用arm汇编编写了一个精简的hello world C程序,作为加载测试的文件。其中字符串输出所调用的函数是对串口读写操作来实现的,不能调用标准库下的printf函数来输出字符串。也可以用G-bios,U-boot等其他嵌入式加载程序作为这类状态1直延续到今天测试程序。

(8)加载和运行Linux内核

本文设计的加载程序没有实现卡驱动程序和tftp下载应用程序,只能通过串口下载内核image,由于串口下载速度比tftp下载速度慢很多,所以下载需要很长的时间。ARM体系架构要求在启动内核前,必须保证CPU处于SVC模式、IRQ和FIQ中断禁止,MMU关闭、数据cache关闭、r0寄存器值为0,rl为机器类型,r2为内核参数列表的物理地址,所以在嵌入式加载程序的设计中要特别注意这一点。

4 结语

本文基于ARMll平台提出了一种较简单的方法,设计和实现了这种精简的嵌入式加载程序,对于分析和理解嵌入式加载程序的实质有一定的作用,基于此工作的基础,扩展和丰富程序的功能是下一步要做的工作。

数据库应用程序开发
Django开发网站
Typescript React 全流程开发
相关资讯