找回密码
 注册
搜索
查看: 907|回复: 10

[讨论] 44B0_bootloader的疑惑,请教高手!!

[复制链接]
发表于 2008-3-23 10:26:06 | 显示全部楼层 |阅读模式
这些天在看44B0的bootloader,对其把程序拷贝到RAM中运行的程序段(是不是叫伪地址重映射呢?)非常迷惑,希望各位高手解答一下,非常感谢!!!

adr        r0, ResetEntry[/COLOR];获取加载到的程序的起始地址
        ldr        r1,        BaseOfROM               
        cmp        r0,        r1                ;若程序加载起始地址与运行时RO底部相同则直接初始化RAM
        ldreq        r0, TopOfROM
        beq        InitRamData
       
        ldr        r2,        =CopyProcBeg[/COLOR];获取CopyProcBeg在RAM中运行的地址
        sub        r1, r2, r1[/COLOR]
        add        r0, r0, r1[/COLOR] ;(CopyProcBeg)RAM-Ro_Base+(ResetEntry)ROM,,计算CopyProcBeg在Flash的地址。
        ldr        r3,        =CopyProcEnd       
0       
        ldmia        r0!, {r4-r7}
        stmia        r2!, {r4-r7}
        cmp        r2, r3
        bcc        %B0                                ;先把CopyProcBeg程序段拷到RAM中。
       
        ldr        r3, TopOfROM               
        ldr        pc, =CopyProcBeg                ;再跳转到RAM运行CopyProcBeg        拷贝其他程序到RAM
       
;*********************************************** **************************
CopyProcBeg       
0       
        ldmia        r0!, {r4-r11}
        stmia        r2!, {r4-r11}
        cmp        r2, r3
        bcc        %B0       
CopyProcEnd
       
        sub        r1, r2, r3
        sub        r0, r0, r1
按照这个说法,假设程序是烧进Flash中正常运行的话,那么程序的上半段就是在Flash中运行的。那么,在红色部分,ldr        r2,        =CopyProcBeg和ldr        r3,        =CopyProcEnd加到寄存器的是什么值呢?我总认为应该是这两个标号在Flash中加载的地址值吧? 但是它却用sub        r1, r2, r1  和add        r0, r0, r1两条指令计算CopyProcBeg程序在Flash中的绝对地址,可见上面两条指令加到寄存器的值应该是两个地址标号在RAM中运行的地址,然而此时程序是在Flash中运行的,怎么可能得到在RAM中运行的地址呢?
第二个问题就是程序开始用adr        r0, ResetEntry得到加载时程序起始地址,类似的,能不能用adr        r0, CopyProcBeg之类的同样获得CopyProcBeg在Flash中的地址呢?还是没有理解adr到底怎么使用的。
发表于 2008-3-25 10:33:24 | 显示全部楼层
加载时地址和运行时地址的概念不同。
两个问题可以一起回答:
标号copyprocbeg等是运行时地址,运行时地址是在链接时指定的,比如resetentry为flash地址,作为初时入口点其运行时地址和加载时地址必须相同,copyprocbeg为ram中地址,加载时地址和运行时地址是不同的。这些个标号代表的地址和程序在flash还是ram中运行没有关系,连接时就决定了。flash地址的计算是按照ro+rw等默认加载规则计算的。
点评回复

使用道具 举报

 楼主| 发表于 2008-3-27 17:38:00 | 显示全部楼层
可以理解标号是在连接时确定其值,与在哪里运行无关,但是,为什么说入口点的运行时地址和加载时地址必须要相同呢?
假设我设置ro-base为0xc000000,那么我把程序烧进flash的状态(也就是加载时域)是从flash的0x0地址开始顺次排满程序代码。开始执行时,从0x0地址取指,adr r0, ResetEntry获得r0的值为0x0, ldr r1, BaseOfROM  获得r1的值为0xc000000,所以执行搬迁,各个地址标号值是相对于这个值在连接时确定的,为什么adr r0, ResetEntry不是得到ResetEntry运行时的值呢?
点评回复

使用道具 举报

发表于 2008-3-28 12:00:46 | 显示全部楼层
不相同的话,显然你的程序就运行不了了。
在链接时,ResetEntry必须放在0x0地址处,因此adr r0, ResetEntry 获得r0为0x0,即加载时地址和运行时地址相同。

引用:
为什么adr r0, ResetEntry不是得到ResetEntry运行时的值呢?ResetEntry的运行时值就是0x0,所有标号指的地址值都是指运行时地址!

ro-base为0xc000000,它在运行时是从ram中的。其保存在flash中的位置(加载时地址)和resetEntry(加载时位置)显然是不同的。
点评回复

使用道具 举报

 楼主| 发表于 2008-3-29 16:33:41 | 显示全部楼层
有点明白,是否place at beginning of image那里设置的入口段就是指这个ResetEntry呢?先谢谢你的回答,再慢慢咀嚼一下[em02],谢谢谢谢
点评回复

使用道具 举报

发表于 2008-3-31 09:20:43 | 显示全部楼层
那就要看具体是如何链接的了,入口段一般会标识有+first属性。
点评回复

使用道具 举报

发表于 2008-4-1 12:55:32 | 显示全部楼层
好好学习,
点评回复

使用道具 举报

发表于 2008-5-9 10:59:05 | 显示全部楼层
在我2,3年前做的44B0中我记得TOPOFROM 和RAMBASE 是相等的,如果是这样的话问题就很好理解了.
当上电的时候RESETENTRY=BASEOFROM,所以把LDR R0 ,TOPOFROM,相当于把BASEOFRAM也就是RAM的固定地址给R0.  所以要在R0上加上和应用程序的地址之间的长度就是应用程序在SDRAM中运行的入口.而SDRAM的初始地址和应用程序入口之间的长度和BASEOFROM和应用程序搬运之前放在FLASH中的间隔是一样的.

所以所有的问题都可以在LDREQ  R0,TOPOFROM 这条语句(如果相等,R0等于TOPOFROM)得到解决.因为TOPOFROM和BASEOFRAM是连续着的. 你应该仔细的去看一下BOOTLOADER 里的相关一些参数.
点评回复

使用道具 举报

发表于 2008-5-9 11:02:43 | 显示全部楼层
弄错了不好意思
点评回复

使用道具 举报

发表于 2008-5-9 11:09:01 | 显示全部楼层
最好把整个BOOTLOADER 公开.
点评回复

使用道具 举报

 楼主| 发表于 2008-5-17 18:22:53 | 显示全部楼层
现在来看就比较清楚了,专门试了一下adr跟ldr两个指令,书上对这两个指令的用法说得很笼统,其实发现用adr时,得到的是相对地址,而用ldr时是得到连接时地址标号的值。
按照上面的,如果程序在ROM中运行时,adr计算出基于0x0的地址,为0,在RAM中运行时得到基于0xc000000,为0xc000000
而ldr则不会受这个影响,不管在哪里执行程序,它都得到标号在连接时就已经确定的值,这里会是基于0xc000000,显然就是在RAM中运行的值。
谢谢各位的回答[em14]
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-11-25 16:41 , Processed in 0.049361 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表