地址0x30000000处于什么行政区域地址库

yao3gang 的BLOG
用户名:yao3gang
文章数:33
访问量:84130
注册日期:
阅读量:3962
阅读量:2422
阅读量:2659
[匿名]51cto游客:
51CTO推荐博文
都知道U-BOOT分为两个阶段,第一阶段是(~/cpu/arm920t/start.S中)在FLASH上运行(一般情况下),完成对硬件的初始化,包括看门狗,中断缓存等,并且负责把代码搬移到SDRAM中(在搬移的时候检查自身代码是否在SDRAM中),然后完成C程序运行所需要环境的建立,包括堆栈的初始化等,最后执行一句跳转指令:
&&&&&&& ldr pc, _start_armboot
&&&&&&& _start_armboot: .word start_armboot,
进入到/lib_arm/board.c中的函数void start_armboot (void),从此就进入了第二阶段。这是在很多资料上都有讲述的,所以勿需多言了。
&&& 现在对于第一阶段有几个问题,以前我一直是没有搞明白的,既然在FLASH中的代码是把自己拷贝到SDRAM中,那么在S3C2410的内存地址空间,就有两份的启动代码,第一份就是在FLASH中,第二份就是在SDRAM中。根据链接脚本文件(~/board/smdk2410/u-boot.lds)
OUTPUT_FORMAT(&elf32-littlearm&, &elf32-littlearm&, &elf32-littlearm&)
/*OUTPUT_FORMAT(&elf32-arm&, &elf32-arm&, &elf32-arm&)*/
OUTPUT_ARCH(arm)
ENTRY(_start)
&. = 0x;&&& /* 后记:这个链接起始地址实际上被-Ttest $(TEST_BASE)更新了*/
&. = ALIGN(4);
&.text&&&&& :
&& cpu/arm920t/start.o (.text)
&& *(.text)
&. = ALIGN(4);
&.rodata : { *(.rodata) }
&. = ALIGN(4);
&.data : { *(.data) }
&. = ALIGN(4);
&.got : { *(.got) }
&__u_boot_cmd_start = .;
&.u_boot_cmd : { *(.u_boot_cmd) }
&__u_boot_cmd_end = .;
&. = ALIGN(4);
&__bss_start = .;
&.bss : { *(.bss) }
&_end = .;
&&& 其中的链接命令 . = 0x;表示地址计数器从0地址开始计数,而且_start 是程序代码段的入口,那么*.text中的所有地址标号(cpu/arm920t/start.S中定义的)就应该从0地址开始计数,那么标号start_armboot(就是void start_armboot (void)函数的入口地址)应该在FLASH中才对啊,所以按照上边的分析,
&&&&&&& ldr pc, _start_armboot
&&&&&&& _start_armboot: .word start_armboot
此条语句后,并没有跳转到SDRAM中的void start_armboot (void),而是跳转到了FLASH中的void start_armboot (void)中。
所以就出现了这样的矛盾,在FLASH中有一段代码把自己拷贝到SDRAM中,产生了两份UBOOT可执行的指令流,但是最后却没有跳转到SDRAM中去运行以提高指令执行的速度。
产生以上的认识是基于以下几个认识(肯定是错误的):
1.*.text中的所有地址标号(在链接时确定)是从0地址开始生成的。
&&&&& 实际上在arm-linux-ld 执行时,原来定义的0x0地址被更新为TEXT_BASE定义的地址。
2.relocate:&&& /* relocate U-Boot to RAM&&&& */
&& adr r0, _start& /* r0 &- current position of code&& */
&& ldr r1, _TEXT_BASE& /* test if we run from flash or RAM */
&& cmp&&&& r0, r1&&&&&&&&&&&&&&&&& /* don't reloc during debug&&&&&&&& */
&& beq&&&& stack_setup
&& ldr r2, _armboot_start
&& ldr r3, _bss_start
&& sub r2, r3, r2& /* r2 &- size of armboot&&&&&&&&&&& */
&& add r2, r0, r2& /* r2 &- source end address&&&&&&&& */
如果不是出于调试阶段,这段搬移代码中的r0和r1肯定不相等的,r0=#0,r1=#TEXT_BASE: 0x33F80000(在./board/smdk2410/config.mk中),所以执行代码的自身拷贝与搬移。
注意:在GNU中:adr r0, _start 作用是获得 _start 的实际运行所在的地址值,而ldr r1, _TEXT_BASE 为获得地址_TEXT_BASE中所存放的数据,其中adr r0, _start翻译成 add r0,(PC+#offset),offset 就是 adr r0, _start 指令到_start 的偏移量,在链接时确定,这个偏移量是地址无关的。而 ldr r1, _TEXT_BASE 指令表示以程序相对偏移的方式加载数据,是索引偏移加载的另外一种形式,等同于ldr r1,[PC+#offset],offset 是 ldr r1, _TEXT_BASE 到 _TEXT_BASE 的偏移量。注意这种用法并不是伪指令,伪指令的特征是 ldr r1, =expr/lable_expr。对于LDR伪指令,ADS的情况有些不一样(细微差别),在ADS中的情况可以参考杜春雷&ARM体系结构与编程&144页。
比较一下:
add r0,(PC+#offset):(PC+#offset)是相对地址,表示把本指令上溯或下溯offset处的地址加载到 r0;
ldr r1,[PC+#offset]:[PC+#offset]也是相对地址,表示把偏移offset处的地址上的数据加载到 r1;
&&& 刚才分析所得到的矛盾,肯定是在认识上存在的偏差,经过把U-BOOT进行make后,从所生成的两个.map文件来看(~/u-boot.map和Systen.map),所有的地址标号都是从0x33f80000开始的,就是从SDRAM的高地址开始,等于TEXT_BASE的值,也就是说,链接器是从0x33F80000开始来链接所编译生成的目标文件的,而不是从0地址开始,经过查看,start_armboot=0x33f80d9c,就是说void start_armboot (void)函数的入口地址在SDRAM中(链接器决定),所以执行
&&&&&&& ldr pc, _start_armboot
&&&&&&& _start_armboot: .word start_armboot,
PC指针肯定就指向了SDRAM中,换句话就是说进入到SDRAM中了,对于ldr pc, _start_armboot,其仍然是GNU中使用程序相对偏移的方式加载数据,翻译一下就是ldr pc, [pc+pc到_start_armboot的偏移值],结果就把_start_armboot地址中的数start_armboot放入pc中完成了跳转,而 start_armboot 的值(函数地址)是在链接时就确定了,是相对于 TEXT_BASE 的。因为在整个UBOOT的阶段1中所有的寻址都是相对位置的寻址(虽然链接器认为是阶段1的代码是从地址0x3ff80000中开始链接的),把阶段1的代码放在0地址开始的FLASH中也是可以正确的运行的,如果ARM的复位向量是在0x(假设),那么把代码烧写到从0x处开始的地方,上电时也可以正确的运行(假设ARM的复位向量是在0x成立),当然ARM的复位向量不在这里,只是以此假设来说明以上的对于阶段1的分析。
&&& 现在最后一个矛盾就是链接脚本(~/board/smdk2410/u-boot.lds)所描述的链接地址与实际的链接地址不相同的问题,因为根据链接脚本,所有的地址标号应该从0地址开始计数的,然而不是。经过查找Makefile文件,在顶层的Makefile文件中,在166行中链接是的链接命令:
$(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \,
其中的LDFLAGS在定义在顶层的config.mk中的145行:LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS),
最关键的就是 -Ttext $(TEXT_BASE)命令了,他的含义就是说,起始地址在TEXT_BASE,而TEXT_BASE在~/board/smdk2410/config.mk中TEXT_BASE = 0x3FF80000;
到此就弄清楚为什么链接从0x3ff80000开始的了,至于链接脚本,其主要作用是用来指明各个*.o文件的顺序,如入口地址标号(_start)等,以及使两个地址标号得到当前的地址
&&& __u_boot_cmd_start = .;&&& *.u_boot_cmd段的起始地址
&&& .u_boot_cmd : { *(.u_boot_cmd) }
&&& __u_boot_cmd_end = .;&&&&&& *.u_boot_cmd段的结束地址
以供C程序使用。 __u_boot_cmd_start和__u_boot_cmd_end可以作为全局的一个常数使用。
&&& 因为-Ttext $(TEXT_BASE)命令的使用,链接器把UBOOT从地址0x3ff80000开始连接,在第一阶段中,所有使用的目标地址寻址都是使用当前PC值加减偏移量的方法,所以把UBOOT烧写到0地址开始的FLASH中,不影响第一阶段的正确执行。
了这篇文章
类别:未分类┆阅读(0)┆评论(0)
09:13:07 20:59:56UsartGPU使用手册文档更新日期更新内容C编程...
本教程为 李华明 编著的iOS-Cocos2d游戏开发系列教程:教程涵盖关于i......
专题主要学习DirectX的初级编程入门学习,对Directx11的入门及初学者有......
&面向对象的JavaScript&这一说法多少有些冗余,因为JavaScript 语言本......
Windows7系统专题 无论是升级操作系统、资料备份、加强资料的安全及管......如何利用JLINK烧写U-boot到NAND Flash中_百度知道
如何利用JLINK烧写U-boot到NAND Flash中
我有更好的答案
很多同学使用笔记本作为自己的ARM开发和学习的平台,绝大多数笔记本都没有并口,也就是无法使用JTag调试和烧写程序到Nand Flash中,幸好我们还有JLINK,用JLINK烧写U-boot到Nor Flash中很简单,大部分NOR Flash都已经被JLink的软件SEGGER所支持,而新手在学习的时候经常会实验各种各样的命令,最悲剧的莫过于将NAND Flash中原有的bootloader给删除了,这时候开发板上电后由于没有bootloader,硬件没有被初始化,在NAND Flash中的操作系统也就无法被加载,开发板成“砖”了,这时候笔记本又无法利用JTag烧写程序进Nand Flash。起始这些可以利用JLink通过两种方法解决:
一、方法一,利用NOR Flash。
这种方法是利用JLink能够烧写程序到NOR Flash来完成的,首先利用J-FLASH ARM将u-boot.bin烧写进NOR Flash(记...
其他类似问题
为您推荐:
jlink的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁S3C2410A复位后执行的第一条指令存放首地址是什么?_百度知道
S3C2410A复位后执行的第一条指令存放首地址是什么?
提问者采纳
下面是我个人的一点认知,希望对你有帮助。1、从nor flash启动则存在地址0x,也就是说要用FLASH做程序启动,FLASH必须放BANK0,且地址从0x0开始,你可以直接在nor flash 中运行程序,也可把程序用自己写在启动代码拷入SDRAM运行。2、若从NAND FLASH启动,则存放在NAND FLASH的开始区域,上电后系统会硬拷贝到内部的4KBRAM运行。下面是我写的一个直接从nor启动的程序代码:只有init.s与led.c两个文件,我调试过,运行正常ADS环境参数设置中把:RO-BASE设为0x,RW-BASE设为0x(根据具体硬件来定)image entry point 设为:0x,设置好的合令为:-info totals -entry 0x -ro-base 0x -map -symbols -rw-base 0x -first init.o(Init) -xrefinit.s文件内容: AREA
Init,CODE,READONLY该伪指令定义了一个代码段,段名为Init,属性只读 ENTRY程序的入口点标识ResetEntry
ldr sp,=0x
;定义堆栈指针(根据具体硬件来定)
IMPORT Main
;声明主函数Main BL Main ;调用主函数
END程序结束符 led.C代码:/*led.c*/
/*用GPB5~GPB8控制四个发光二极管闪烁*/#define GPBCON
(*(volatile unsigned *)0x) //Port B control#define GPBDAT
(*(volatile unsigned *)0x) //Port B data#define GPBUP
(*(volatile unsigned *)0x) //Pull-up control B void Main(void)
GPBCON &= ~((0x3&&10) | (0x3&&12) | (0x3&&14) | (0x3&&16
GPBCON |= (0x1&&10) | (0x1&&12) | (0x1&&14) | (0x1&&16);
//GPBCON=0x; while (1) {
GPBDAT=0x061F;
for(i=0;i&10000;i++);
GPBDAT=0x07FF;
for(i=0;i&10000;i++); }}
提问者评价
谢谢关注哦
其他类似问题
为您推荐:
其他1条回答
Nucleus PLUS是美国ATI公司为实时性要求较高的嵌入式系统应用设计的操作系统内核。约95%的Nucleus PLUS代码用ANSI C语言编写,因此,非常便于移植并能够支持大多数类型的微处理器,如X86、68K、PowerPC、MIPS、ARM等。
  经过截减编译后,Nucleus PLus核心代码区一般不超过20KB大小。同时提供TCP/IP网络、图形界面Grafix、文件系统File等模块。还有一个特点就是免费提供源代码,有利于节省开发费用。
  S3c2410A是三星公司推出的基于ARM920T内核高性能低功耗16/32位RISC微控制器,内部集成了丰富的系统外围控制器。配合Nucleus PLUS操作系统可方便地开发出适于手持设备和各种低功耗产品的应用程序,加快新产品的上市时间。 NUcleus PLUS启动过程
  嵌入式实时操作系统内核Nucleus PLus的启动...
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 excel 返回区域地址 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信