共2条
1/1 1 跳转至页
ARM,0x00000000,CODE ARM是从0x00000000地址开始执行CODE
问
那么是不是FLASH的空间一定要位于0地址开始的位置呢? 如果是的话,为什么我拿到一个ARM核的芯片的DATASHEET里写到"After reset the ARM7 cpu is booting from address 0x00000000 which is remapped to 0xff000000 (paraller boot) or 0x9f000000(serial boot) (Chip select 0 (SBCS0))" 这个REMAP怎么理解? 我刚接触ARM,还请知道的告诉一声,谢谢!
答 1:
我也好想知!!
答 2:
可能这个有用
看来我们遇到了同样的问题了.
看看这篇文章也许有用,这里真心感谢文章的作者.
http://www.21icsearch.com/buzi/upimage/upfile/20053101735010.pdf 答 3: remap就是把一个地址指到另一个地方去了,由硬件自动完成例如,将地址0映射到地址100,那么你访问地址0的时候,实际上访问的是地址100。当然,你访问地址100时,还是100…………
在你看到那个芯片中,你只要将启动代码从0xff000000开始存放,然后将地址0映射到0xff000000,那么硬件就会自动将地址0指向0xff000000。
读地址0的值,就会得到地址0xff000000中的值。 答 4: 对computer00的解答还有疑问(本人还没理解,太菜了)computer00大哥说
1,“remap由硬件自动完成”
2,“你只要将启动代码从0xff000000开始存放,然后将地址0映射到0xff000000”
以上这两个过程是不是只要把编译器linker项R0 base=0xff000000 就OK了吗?
在启动代码中是否还要把flash从地址0x00000000开始的内容copy到0xff000000开始的sram?
在我的启动程序中有以下一段:可以帮我解释下是如何实现的吗?
;****************************************************
;拷贝并粘贴 RW data/zero initialized data *
;****************************************************
adr r0, ResetEntry
ldr r1, BaseOfROM
cmp r0, r1
ldreq r0, TopOfROM
beq InitRamData
;****************************************************
;计算拷贝程序在flash中的实际位置 *
;****************************************************
ldr r2, =CopyProcBeg
sub r1, r2, r1
add r0, r0, r1
ldr r3, =CopyProcEnd
;****************************************************
;将拷贝程序复制到ram中 *
;****************************************************
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
;********************************************************
;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中 *
;********************************************************
ldr r3, TopOfROM
ldr pc, =CopyProcBeg
;********************************************************
;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置 *
;只拷贝CopyProcEnd以后的代码 *
;********************************************************
CopyProcBeg
0
ldmia r0!, {r4-r11}
stmia r2!, {r4-r11}
cmp r2, r3
bcc %B0
CopyProcEnd
sub r1, r2, r3
sub r0, r0, r1
InitRamData
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
[ :LNOT:THUMBCODE
BL Main ;从汇编进入C语言代码空间,不要使用main()
B .
]
[ THUMBCODE ;for start-up code for Thumb mode
orr lr,pc,#1
bx lr
CODE16
bl Main ;从汇编进入C语言代码空间,不要使用main()
b .
CODE32
]
LTORG
答 5: 我只想说明一下remap是什么意思,至于你的代码,我看了眩晕~~从你看到的那个芯片来看,在复位后,地址0被映射到了0xFF000000或者0x9F000000处,你应该在这里安置启动代码。
这两个地址应该就没有SRAM了,是给FLASH用的,不然上电后就无法引导了。
如果还可以remap到SRAM区的话,那么在启动后,你可以给remap做相关设置,使其映射到SRAM区,并将异常处理代码安置到那里。
这样当异常发生时,就会取到那里的指令来运行。 答 6: 的确,我的 答 7: 的确,我的ic是44B0……我的ARM是44B0,0xFF000000或者0x9F000000处的确不可能是sdram,或者sram,我只是引用你之前的例子而已,其实我的ro被设置为0x0c008000,
就以R0 base=0x0c008000来说,
我如何才能在复位后,把地址0映射到了0x0c008000处,我应该如何安置启动代码?
要做些什么设置?只要把编译器linker项R0 base设置0x0c008000 就OK了吗? 答 8: 不能将启动代码放在地址0x0c00800处吧?如果是并行的FLASH,启动代码应该放在地址0xFF000000处。
我对44B0不了解,不知道是否可以让在它复位后,将地址0影射到0x0C008000处?如果可以的话,你放在那也是可以的。 答 9: 是可以的,(别人的代码)但是为什么能?硬件上flash起始地址为0x00000000,sdram起始地址为0x0c000000 ,
当用AXD仿真时,跳入仿真,PC的值就等于0x0c008000,(我的理解为什么pc不是0x0000000,最起码也要应该从flash启动吧?)
即准备执行以下代码的:( b ResetHandler ;for debug)
AREA Init,CODE,READONLY
ENTRY
ResetEntry
b ResetHandler ;for debug
b HandlerUndef ;handlerUndef
b HandlerSWI ;SWI interrupt handler
b HandlerPabort ;handlerPAbort
b HandlerDabort ;handlerDAbort
b . ;handlerReserved
b HandlerIRQ
b HandlerFIQ
这样说明已经完成了remap吗?
如果已完成了remap,那么是怎么一个过程,怎么用AXD仿真时,在代码中没有体现出来,pc值一下子就是0x0c008000呢? 答 10: 你开始仿真后,再点复位试试?“PC的值就等于0x0c008000”这个不叫remap,这个叫做跳转。
程序启动是从地址0开始的。如果remap之后,地址0里面的内容将不再是地址0里面的内容,但PC是从0开始的,这个是不会变的。 答 11: 我基本上明白computer00的意思,但是……但是我没有真正的仿真器,只是代理仿真AXD的那种,所以不能做“开始仿真后,再点复位”的操作,没办法进一步验证我的理解;
疑问:
1,"如果remap之后,地址0里面的内容将不再是地址0里面的内容" 如果那样那么地址0的内容会是什么?
2,“PC是从0开始的,这个是不会变的”,pc为0时应该还没有完成remap吧!那么什么时候进行什么操作才能完成remap呢?
我这个牛皮灯笼点不明,圈圈请不要见怪啊!!真诚的谢谢圈圈!!
答 12: re:eqtwo您不要总想着remap功能,44box没有硬件的remap功能。
当复位后pc从0x0地址开始运行,如果你把RO base设成了0x0c008000,在0x0地址开始的代码必须将0x0(flash)开始的所有代码都复制到0x0c008000(sdram)开始的地址处,然后跳到该地址处去执行 答 13: 有点晕了……1.地址0里面的内容不是地址0里面的内容,而是remap之后指向的那个内容了…………
例如,地址0里面的内容为a,地址222里面的内容为b。如果将地址0,remap到地址222,你在取读地址0里面的内容,发现它返回的值是b…………
启动时,是从地址0开始运行的。但如果在启动时,地址0被remap到了地址222,那么它将运行的是222地址中的b这条指令……
2.不管如何,中断入口的地址是不会变的。例如,地址4是中断1入口地址,不管你如何remap法,中断发生时,
始终是到地址4去取指令。但是如果地址4被remap到其它地方去了,读的将不再是物理上的地址4,读回的值,
将是被remap到的那个地方的值了!也就是说,虽然是取的地址4,但是被硬件做了手脚,不指向4了,而指到了另一个地址…………
不知道这回你明白了没…………
如果你有keil for ARM就好了,可以用它来仿真。直接查看地址0的内容,然后,修改remap,
再查看地址0的内容,你会发现,地址0里的内容变了……而且跟它remap到的地方那个地址单元的值一样…… 答 14: 再次谢谢圈圈和啊南!感激之至,有点开窍了,琢磨下应该没问题! 答 15: 同意阿南观点
rt 答 16: REeqtwo:不知道您悟懂了没有,现在我还是有你的那个疑问!
阿南的帖子这样回复:
//====================================================================
您不要总想着remap功能,44box没有硬件的remap功能。
当复位后pc从0x0地址开始运行,如果你把RO base设成了0x0c008000,在0x0地址开始的代码必须将0x0(flash)开始的所有代码都复制到0x0c008000(sdram)开始的地址处,然后跳到该地址处去执行
//====================================================================那么如果硬件有remapg功能的芯片是在什么时候完成的这个remap操作呢?
系统在上电复位位后PC的值应该是0 那么在最初上电的时候程序应该是从0地址处开始取指令,这个时候如果ARM的硬件没有进行所谓的remap操作的话,那么,ARM应该是由地址0处开始取指令并执行,这时候,执行的肯定是FLASH里的指令,因为 REM里面在最初上电的时候是没有代码的,那么在中断向量和FLASH部分代码都拷贝完之后,程序为什么会自动跳到RAM中去执行?在程序中只有这么一条指令“ bl Main ”就跳到主程序去了,为什么会这样?
归根结底,就是remap操作是在什么时候完成的?需要执行哪条指令来完成REMAP或是需要对编译器进行什么设置来完成?
希望“电脑圈圈” “阿南”及论坛里的各位高手能再指点一下!真诚的感谢你们! 答 17: remap是设置一个寄存器来完成的 答 18: 再问!哪个寄存器? 我在启动代码里面找了,没找到,见笑了! 答 19: 你用的是什么型号的MPU?我现在在用LPC2138,它里面就有一个MEMMAP的寄存器。设置不同的值,就会把中断入口地址remap到不同的位置。
如果没有remap功能的MCU,其中断处理只能放在一个地方了。
看来我们遇到了同样的问题了.
看看这篇文章也许有用,这里真心感谢文章的作者.
http://www.21icsearch.com/buzi/upimage/upfile/20053101735010.pdf 答 3: remap就是把一个地址指到另一个地方去了,由硬件自动完成例如,将地址0映射到地址100,那么你访问地址0的时候,实际上访问的是地址100。当然,你访问地址100时,还是100…………
在你看到那个芯片中,你只要将启动代码从0xff000000开始存放,然后将地址0映射到0xff000000,那么硬件就会自动将地址0指向0xff000000。
读地址0的值,就会得到地址0xff000000中的值。 答 4: 对computer00的解答还有疑问(本人还没理解,太菜了)computer00大哥说
1,“remap由硬件自动完成”
2,“你只要将启动代码从0xff000000开始存放,然后将地址0映射到0xff000000”
以上这两个过程是不是只要把编译器linker项R0 base=0xff000000 就OK了吗?
在启动代码中是否还要把flash从地址0x00000000开始的内容copy到0xff000000开始的sram?
在我的启动程序中有以下一段:可以帮我解释下是如何实现的吗?
;****************************************************
;拷贝并粘贴 RW data/zero initialized data *
;****************************************************
adr r0, ResetEntry
ldr r1, BaseOfROM
cmp r0, r1
ldreq r0, TopOfROM
beq InitRamData
;****************************************************
;计算拷贝程序在flash中的实际位置 *
;****************************************************
ldr r2, =CopyProcBeg
sub r1, r2, r1
add r0, r0, r1
ldr r3, =CopyProcEnd
;****************************************************
;将拷贝程序复制到ram中 *
;****************************************************
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
;********************************************************
;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中 *
;********************************************************
ldr r3, TopOfROM
ldr pc, =CopyProcBeg
;********************************************************
;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置 *
;只拷贝CopyProcEnd以后的代码 *
;********************************************************
CopyProcBeg
0
ldmia r0!, {r4-r11}
stmia r2!, {r4-r11}
cmp r2, r3
bcc %B0
CopyProcEnd
sub r1, r2, r3
sub r0, r0, r1
InitRamData
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
[ :LNOT:THUMBCODE
BL Main ;从汇编进入C语言代码空间,不要使用main()
B .
]
[ THUMBCODE ;for start-up code for Thumb mode
orr lr,pc,#1
bx lr
CODE16
bl Main ;从汇编进入C语言代码空间,不要使用main()
b .
CODE32
]
LTORG
答 5: 我只想说明一下remap是什么意思,至于你的代码,我看了眩晕~~从你看到的那个芯片来看,在复位后,地址0被映射到了0xFF000000或者0x9F000000处,你应该在这里安置启动代码。
这两个地址应该就没有SRAM了,是给FLASH用的,不然上电后就无法引导了。
如果还可以remap到SRAM区的话,那么在启动后,你可以给remap做相关设置,使其映射到SRAM区,并将异常处理代码安置到那里。
这样当异常发生时,就会取到那里的指令来运行。 答 6: 的确,我的 答 7: 的确,我的ic是44B0……我的ARM是44B0,0xFF000000或者0x9F000000处的确不可能是sdram,或者sram,我只是引用你之前的例子而已,其实我的ro被设置为0x0c008000,
就以R0 base=0x0c008000来说,
我如何才能在复位后,把地址0映射到了0x0c008000处,我应该如何安置启动代码?
要做些什么设置?只要把编译器linker项R0 base设置0x0c008000 就OK了吗? 答 8: 不能将启动代码放在地址0x0c00800处吧?如果是并行的FLASH,启动代码应该放在地址0xFF000000处。
我对44B0不了解,不知道是否可以让在它复位后,将地址0影射到0x0C008000处?如果可以的话,你放在那也是可以的。 答 9: 是可以的,(别人的代码)但是为什么能?硬件上flash起始地址为0x00000000,sdram起始地址为0x0c000000 ,
当用AXD仿真时,跳入仿真,PC的值就等于0x0c008000,(我的理解为什么pc不是0x0000000,最起码也要应该从flash启动吧?)
即准备执行以下代码的:( b ResetHandler ;for debug)
AREA Init,CODE,READONLY
ENTRY
ResetEntry
b ResetHandler ;for debug
b HandlerUndef ;handlerUndef
b HandlerSWI ;SWI interrupt handler
b HandlerPabort ;handlerPAbort
b HandlerDabort ;handlerDAbort
b . ;handlerReserved
b HandlerIRQ
b HandlerFIQ
这样说明已经完成了remap吗?
如果已完成了remap,那么是怎么一个过程,怎么用AXD仿真时,在代码中没有体现出来,pc值一下子就是0x0c008000呢? 答 10: 你开始仿真后,再点复位试试?“PC的值就等于0x0c008000”这个不叫remap,这个叫做跳转。
程序启动是从地址0开始的。如果remap之后,地址0里面的内容将不再是地址0里面的内容,但PC是从0开始的,这个是不会变的。 答 11: 我基本上明白computer00的意思,但是……但是我没有真正的仿真器,只是代理仿真AXD的那种,所以不能做“开始仿真后,再点复位”的操作,没办法进一步验证我的理解;
疑问:
1,"如果remap之后,地址0里面的内容将不再是地址0里面的内容" 如果那样那么地址0的内容会是什么?
2,“PC是从0开始的,这个是不会变的”,pc为0时应该还没有完成remap吧!那么什么时候进行什么操作才能完成remap呢?
我这个牛皮灯笼点不明,圈圈请不要见怪啊!!真诚的谢谢圈圈!!
答 12: re:eqtwo您不要总想着remap功能,44box没有硬件的remap功能。
当复位后pc从0x0地址开始运行,如果你把RO base设成了0x0c008000,在0x0地址开始的代码必须将0x0(flash)开始的所有代码都复制到0x0c008000(sdram)开始的地址处,然后跳到该地址处去执行 答 13: 有点晕了……1.地址0里面的内容不是地址0里面的内容,而是remap之后指向的那个内容了…………
例如,地址0里面的内容为a,地址222里面的内容为b。如果将地址0,remap到地址222,你在取读地址0里面的内容,发现它返回的值是b…………
启动时,是从地址0开始运行的。但如果在启动时,地址0被remap到了地址222,那么它将运行的是222地址中的b这条指令……
2.不管如何,中断入口的地址是不会变的。例如,地址4是中断1入口地址,不管你如何remap法,中断发生时,
始终是到地址4去取指令。但是如果地址4被remap到其它地方去了,读的将不再是物理上的地址4,读回的值,
将是被remap到的那个地方的值了!也就是说,虽然是取的地址4,但是被硬件做了手脚,不指向4了,而指到了另一个地址…………
不知道这回你明白了没…………
如果你有keil for ARM就好了,可以用它来仿真。直接查看地址0的内容,然后,修改remap,
再查看地址0的内容,你会发现,地址0里的内容变了……而且跟它remap到的地方那个地址单元的值一样…… 答 14: 再次谢谢圈圈和啊南!感激之至,有点开窍了,琢磨下应该没问题! 答 15: 同意阿南观点
rt 答 16: REeqtwo:不知道您悟懂了没有,现在我还是有你的那个疑问!
阿南的帖子这样回复:
//====================================================================
您不要总想着remap功能,44box没有硬件的remap功能。
当复位后pc从0x0地址开始运行,如果你把RO base设成了0x0c008000,在0x0地址开始的代码必须将0x0(flash)开始的所有代码都复制到0x0c008000(sdram)开始的地址处,然后跳到该地址处去执行
//====================================================================那么如果硬件有remapg功能的芯片是在什么时候完成的这个remap操作呢?
系统在上电复位位后PC的值应该是0 那么在最初上电的时候程序应该是从0地址处开始取指令,这个时候如果ARM的硬件没有进行所谓的remap操作的话,那么,ARM应该是由地址0处开始取指令并执行,这时候,执行的肯定是FLASH里的指令,因为 REM里面在最初上电的时候是没有代码的,那么在中断向量和FLASH部分代码都拷贝完之后,程序为什么会自动跳到RAM中去执行?在程序中只有这么一条指令“ bl Main ”就跳到主程序去了,为什么会这样?
归根结底,就是remap操作是在什么时候完成的?需要执行哪条指令来完成REMAP或是需要对编译器进行什么设置来完成?
希望“电脑圈圈” “阿南”及论坛里的各位高手能再指点一下!真诚的感谢你们! 答 17: remap是设置一个寄存器来完成的 答 18: 再问!哪个寄存器? 我在启动代码里面找了,没找到,见笑了! 答 19: 你用的是什么型号的MPU?我现在在用LPC2138,它里面就有一个MEMMAP的寄存器。设置不同的值,就会把中断入口地址remap到不同的位置。
如果没有remap功能的MCU,其中断处理只能放在一个地方了。
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |