ARM的启动代码(1):介绍

2020-01-16来源: eefocus关键字:ARM  启动代码  bootloader

很多朋友搞嵌入式,写起代码来一点问题没有,到最后上板子调试的时候,挂了。究其原因,还是对芯片的启动地址、启动方式、bootloader和操作系统的衔接出了问题。今天就闲聊一下这个问题。

对于一个新处理器,我们最关心的是什么呢?并不是它支持不支持C编译器,有没有良好的开发环境。从程序员的角度说,要把一个新处理器吃透,必须明白两样东西:a)新处理器的内存模型;b)新处理器的中断方式、中断源等等。以ARM的AT91SAM9260为例。

一个ARM芯片可能有N种不同的启动方式,支持从SPI flash启动、Norfalsh、nandflash、片内rom 等等。一些操作系统,如vxworks、ecos也支持这些五花八门的启动方式,如果不理解内存模型,会认为这些方式是完全不同的。但从有经验的嵌入式软件工程师眼里,这些方式其实都是一种方式扩展出来的。所有的ARM一上电以后,都是进入SVC模式、中断关闭、ARM指令,从0x0处执行代码。


我们来考察一个问题,SP flash和Nandflash是用什么总线的呢?SPI 和 8Bit or 16bit, 在代码中可以通过简单的赋值和地址方式来访问spi flash和nandflash中的内容吗?是不可以的,读取spi flash/nandflash,写入spi flash/nandflash首先要写入命令,然后准备缓冲区,刷新数据。所有这些不可能简简单单的通过一条LDR、STR指令完成对存储单元的访问。专业的话来说,SPIflash/nandflash并不是和系统统一编址的。一上电以后,ARM从0x0处执行,是无法通过复杂的方式获取0x0处的数据,只能通过简单的总线动作完成。也就是,想直接用spiflash/nandflash启动ARM那是天方夜谭……为什么有的ARM可以用spiflash/nandflash启动系统呢?AT91SAM9260 就是一个这样的芯片。


我们来看看AT91SAM9260的芯片存储结构:0x0~0x0FFF FFFF是internal memories,就是芯片内部的存储器。0x0~ 0x0F FFFF 是boot memory, 0x10 0000 到 0x10 7FFF是ROM。0x20 0000~0x20 0FFF是 SRAM0,0x30 0000 ~ 0x30 0FFF 是 SRAM1。boot memory是什么?boot memory是一个空闲的地址。可将SRAM0、ROM映射到该地址来,也就是用控制寄存器,选择ROM、SRAM0映射到boot memory位置。如果访问boot memory的地址,也就是访问被映射到该位置的ROM或SRAM0地址内容。例如,如果boot memory映射了SRAM0,访问0x10 的位置与0x20 0010位置是等价的。芯片一上电后,默认的映射是ROM,ROM是什么?原来是ATMEL为9260定义的一段启动代码,出厂就固化在里面。它会寻找Dataflash(ATMEL的一种flash),从flash中加载bootloader,或寻找nandflash、norflash,加载bootloader。

ARM上电从内存0x0开始执行,9260将rom映射到boot memory的位置,即执行的rom中的代码。从外设中加载bootloader。这个过程就顺利成章了,boot memory在arm7中是经常可见的,用以解决ARM的启动和异常向量的问题。是个非常完美的解决方案。

到这里,我们就明白了,其实从nandflash/spi flash/uart/网络等方式加载应用程序,实际上,ARM裸机是做不到的,必须要告诉ARM方法。也就是说,我们必须写个程序告诉ARM,从什么口,什么方法可以把正确的代码载入内存。明白了这一点,就需要弄清楚地址了,就是将什么东西加载到什么位置。其实这个问题并不复杂,关键就是把一些概念分清楚就好了。

  1. 我们的代码加载到芯片统一编址的什么位置,这个地址整个芯片内部都是通行可见的。


  2. 我们的代码存储在spi flash/nandflash这样非统一编制的器件上,代码在这些器件上的地址从哪里开始?其实这个地址对ARM来说已经不是统一编制的地址了,只需要编程人员明了,写好驱动,从指定位置加载就好。如果厂家已经写好驱动,这个地址已经固定了,对于编程人员来说,将代码写入nandflash/spi flash不能再随心所欲了,因为无法改变驱动中的起始地址了。


  3. 被加载代码的格式。如果是原始二进制格式,参考1)就可以了。但如果是elf文件,那就稍微麻烦了:elf文件中含有每一块数据加载到芯片的什么位置,但不管怎么说,思路都是一样的,将合适的代码加载到芯片特定的位置。


修改这些地址的位置也是不同的,Bootloader可以配置将目标加载到的位置、获取目标代码的位置和获取目标代码的方法;工具链的链接脚本可以修改每个段(数据段、代码段)的位置。硬件的片选信号也决定着器件统一编址的位置。所以,在设计ARM启动代码的时候,不能孤立的去看芯片资料,需要统一从全局考虑。

关键字:ARM  启动代码  bootloader 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic485859.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:ARM在进入main函数之前会做什么
下一篇:ARM启动代码的分析

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

ARM嵌入式学习--OK6410裸板程序--1.GPIO控制LED
;  mov pc, lrMakefile: 1 led.bin: start.o 2         arm-linux-ld -Ttext 0x50008000 -o led.elf $^ 3         arm-linux-objcopy -O binary led.elf led.bin 4         arm-linux-objdump -D led.elf > led_elf.dis 5 %.o
发表于 2020-01-09
ARM嵌入式学习--OK6410裸板程序--1.GPIO控制LED
移植mysql到arm平台
最近需要将一个程序移植到arm平台上,程序调用了MySQL数据库,所以就牵扯到将MySQL数据库移植到ARM平台上面,所以在网上大量查阅资料。在baidu文库发现了一篇文档,是wlzxlc上传的文档名称为:《编译ARM平台的QtEmbedded的MySQL插件和移植MySQL》。下面说明里面介绍到:ARM平台下的QtEmbedded所需mysql插件,及MySQL的移植。我的整个移植过程参考了这篇文档,但是遇到了很多的问题,所以又上网搜寻其它资料。现在我已经移植成功,回头看这篇文档,就发现里面有很多疏漏甚至是错误。这些东西如果不详细注明出来,更多的新手绝对还会重蹈我的覆辙,所以在这里将mysql 的arm+linux移植
发表于 2020-01-09
ARM Linux.2.6.34内核移植
ARM-LINUX-GCC版本4.3.2.以安装在/usr/local/arm/4.3.2下.第一步:修改linux-2.6.34/Makefile文件,在makefile中找到以下两条信息并做修改ARCH ? =arm  CROSS_COMPILE ?=/usr/local/arm/4.3.2/bin/arm-linux-第二步:修改平台输入时钟修改平台的时钟频率,修改内核源码“arch/arm/mach-s3c2440/mach-smdk2440.c”把时钟初始化中(S3C24XX_init_clocks(16934400 ))的16934400 改为12000000,因为我们的开发板上为12M第三步:修改
发表于 2020-01-09
编译基于ARM LINUX的驱动模块的Makefile
KERNELDIR = /home/wenhao/platform/linux-2.6.34PWD := $(shell pwd)CROSS_COMPILE = /usr/local/arm/4.3.2/bin/arm-linux-CC    = $(CROSS_COMPILE)gccobj-m := key.o modules:    $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
发表于 2020-01-09
GNU ARM汇编快速入门
以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。ARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。 目前常用的ARM编译环境有2种:ARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定;GNU ARM ASM:GNU工具的ARM版本
发表于 2020-01-09
交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别
自己之前一直没搞清楚这两个交叉编译器到底有什么问题,特意google一番,总结如下,希望能帮到道上和我有同样困惑的兄弟…..一. 什么是ABI和EABI1) ABI: 二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口.ABI涵盖了各种细节,如:数据类型的大小、布局和对齐;调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最
发表于 2020-01-08
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved