天嵌 ARM开发社区

 找回密码
 注册
查看: 2633|回复: 2

关于ARM链接和执行机理的问题

[复制链接]
北上清云 发表于 2011-4-3 01:10:34 | 显示全部楼层 |阅读模式
问题:
注:所指芯片为s3c2440,烧写工具是SECURE CRT和DNW,重点是绿色部分的问题
RO base指指令的加载地址和运行地址(书上看的),加载地址是指映像文件烧写到flash上的的状态,也就是存放在flash上的位置,而运行域是指程序执行时的地址。
如果RO base设置成0x30000000,镜像文件烧写到NAND FLASH,问:
1、        镜像文件被烧录到NAND中,起始地址是什么,是0吗?根据加载域的定义(映像文件烧写到flash上的的状态)以及书上的解释(RO base 0x30000000就是加载地址和执行地址),既然映像文件时烧写到NAND中的,它的加载地址就应该是0啊,那岂不是矛盾了呢?
2、        在ADS环境中编译,如果镜像文件烧写到NAND中(用SECURE CRT和DNW烧写),那么烧写到NAND中的镜像文件的起始地址默认是什么,是0吗?可以指定吗?还有DNW种的地址指什么地址,为什么资料上指定为0x3000000?可以是其他地址吗?比如是0。
是不是不管连接地址(即RO base)设置成什么,复位后程序总是从地址0开始运行的呢?那么RO base设置的地址如果为0x3000000的话,那不是指代码从0x30000000开始执行吗?怎么又矛盾了?
3、        我在网上搜了一下,看到这样一段话:如果RO的值和你程序烧录起始地址的值不同,(如:你设置的RO=0x3000000,注意而你烧录的代码是在0地址处(问:这里的0地址是指烧写到NAND中的地址码)),这样就需要你烧录在0地址开始处的一小部分启动代码把程序从烧录地址搬运到RO设置的地址中去,但要注意,连接器为你连接的地址是以RO为基准的,这样你可能会有个疑问,为什么程序的运行域是以RO(0x30000000)为基准,但处于FLASH(0地址开始)里的一小部分启动代码还能运行呢,这就是因为程序中用了与地址无关的指令,使得一上电,能够顺利的执行0地址处的启动代码。
问:是不是只要RO base地址不是0,而镜像文件烧写到NAND中,都要在一开始有一小部分启动代码把程序从烧录地址搬运到RO设置的地址中去呢?否则就无法运行了呢?
4、        对于“为什么程序的运行域是以RO(0x30000000)为基准,但处于FLASH(0地址开始)里的一小部分启动代码还能运行呢,这就是因为程序中用了与地址无关的指令,使得一上电,能够顺利的执行0地址处的启动代码。”这段话,想问的是复位后是从0开始执行还是从0x3000000开始?
    为设么一定要是相对地址指令才能顺利执行0地址处的启动代码啊。
我的理解是这样的:复位后从0地址开始(nand中的代码会自动复制到偏上RAM,且地址为0),执行一些初始化,如存储控制器,中断,堆栈等(由于还没到复制NAND的代码到RO base指定的地址,所以这部分代码是在RAM中运行的,可是和相对地址没关系啊,即使不是也会执行啊),然后代码复制,跳到RO base指定的地址处执行。
对于相对地址指令总是似懂非懂。希望贵人能指教啊!!!!!
还有我看到网上说PC一上电的值是|Image$$RO$$Base|,也
就是RO base处的地址值,但是如果我的地址值是0X30000000,
那一上电PC就指向0X30000000,可是一开始这里没有指令可以执行啊,如果有,那又是什么时候复制过去的啊,不是烧写到NANDA中的吗?况且这是第一条指令啊。我知道是相对地址指令的缘故,可是我解释不同啊!!!!!而且对于以下指令网上说:不是跳转到RO处,而是跳到flash,我糊涂了,上电PC指向0X30000000,可是这里没有指令啊,何来跳转啊????
ENTRY
ResetEntry
    b ResetHandler           

5、        对于韦东山的《嵌入式linux应用开发》有这样一个例程:

IMPORT main
   AREA HEAD, CODE, READONLY
   ENTRY
   
    bl  disable_watch_dog               (1)
bl  memsetup                      (2)
bl  copy_steppingstone_to_sdram      (3)   
ld pc, =on_sdram
on_sdram:            
ldr sp, =0x34000000           
    bl  main
halt_loop
    b   halt_loop

disable_watch_dog
  
    mov r1,     #0x53000000
    mov r2,     #0x0
    str r2,     [r1]
    mov pc,     lr      
END
程序很简单,其中把main函数和disable_watch_dog   函数体给略去了,大家都知道怎么写
书上说:代码1、2、3指令的连接地址虽然都在0x30000000(sdram),但是由于他们都是位置无关的相对跳转指令,所以可以在Steppingstone中执行,我想问的是:这几条指令当然是在0开始出执行的么,如果不是相对跳转指令就不能执行了么?为什么?为什么我看反汇编第一条指令的地址是0x30000000?不是还没复制到sdram中吗?不是要到复制指令后才开始跳到sdram中么!到底是什么意思啊?
总结:是不是镜像文件烧写到NAND中时,即使地址是0x3000000,那么如果程序中没有复制的代码(把程序从烧录地址搬运到RO设置的地址中去),就还是从0开始执行呢,即在RAM中,只要不超出4kb。但是如果有复制的代码段,那又要重复红色字体部分问题了!!
这个问题已经困扰我好久,我也查了好多资料,就是绕不出来,只要这个问题通了,好多问题都能解决想通,请各位走过的路过的不要错过,都来说几句,谢谢了
天嵌_support1 发表于 2011-4-6 14:09:49 | 显示全部楼层
1# 北上清云


R0设置的是0x30000000,也就是SDRAM的起始地址,这个地址我理解就是告诉编译器,所以我们的程序只能在SDRAM里跑,而且地址是从 0x30000000开始,所以如果这么设置,bin可执行文件一定要拷贝到0x30000000,否则就会产生错误。当然RO的意思就是指令和常量存放的起始地址。
如果设置了0x30000000,那么假如代码里有一个标号label,这个标号对应的地址就会从0x30000000开始算起,当你通过这个 label 绝对跳转的时候,就是跳转到0x30000000以上的内存的位置,所以说如果设置了0x300000000,但你你把代码放到SRAM里执行(SRAM 的地址是0-4k),就会出错
 楼主| 北上清云 发表于 2011-4-9 14:03:28 | 显示全部楼层
2# embedsky_lxt


复位后大家都知道PC是指向0的,就是处理器从0地址处开始取指令(这句话不知道对不对)。书上说虚拟地址由编译器和连接器在定位程序时分配,请问:
虚拟地址是根据什么分配的,是ADS中的RO base吗?如果不是那是怎么分配的?
如果虚拟地址确实是按照链接地址分配的,即虚拟地址的首地址就是RO base的地址值,那么在没有使用MMU的情况下,使用平板存储方式,即虚拟地址就是等于物理地址,那么在执行程序的时候如果程序是烧写到NAND中的,复位后PC指向0地址处代码,处理器是从0地址处取指令,还是从虚拟地址开始处取指令?

如果复位后处理器是从0地址处开始取指令,且我把R0 base的地址设置成0x30000000,程序烧写到NAND中,那么我想问的是:除了跟PC有关的跳转指令外是不是其它所有指令都能够执行呢?因为我是烧写到NAND中的,且PC是从0地址处开始的,只要没有PC的跳转指令,就不会跳到0X30000000开始的某个地址处去执行指令。
我疑惑的是复位后处理器到底是从0地址处取指令运行,还是从RO base地址处取指令运行。
我已经验证过了,只要不是个PC 有关的跳转指令,都是从0地址以后的地址执行的,而不是跳到RO base地址开始后的某个地址处执行,所以我可以下结论:对于RO base的地址设置,如果要从此地址处开始执行,只能使用PC跳转指令跳到SDRAM中执行,对吗?验证过程如下:
原程序:

MEM_CTL_BASE   EQU    0x48000000
SDRAM_BASE     EQU    0x30000000

   IMPORT main
   AREA HEAD, CODE, READONLY
   ENTRY

bl  disable_watch_dog
bl memsetup
bl copy_steppingstone_to_sdram
ldr pc, =on_sdram                  
on_sdram
    ldr sp, =0x34000000               
    bl  main
halt_loop
    b   halt_loop

disable_watch_dog
   
    mov r1,     #0x53000000
    mov r2,     #0x0
    str r2,     [r1]
    mov pc,     lr
copy_steppingstone_to_sdram
  
    ldr r1, =SDRAM_BASE
    ldr r2, =SDRAM_BASE
    mov r3, #4*1024
    mov r0, #0
1  
    ldr r4, [r1],#4     
    str r4, [r2],#4
    add r0, r0, #4   
    cmp r0, r3         
    bne %B1            
    mov pc,     lr      

memsetup
   

    mov r1,     #MEM_CTL_BASE      
    adrl    r2, mem_cfg_val         
    add r3,     r1, #52           
1  
    ldr r4,     [r2], #4           
    str r4,     [r1], #4           
    cmp r1,     r3               
    bne %B1                        
    mov pc,     lr                 


    ALIGN 4
mem_cfg_val
   
   DCD    0x22011110      
   DCD    0x00000700      
   DCD    0x00000700     
   DCD    0x00000700     
   DCD    0x00000700   
   DCD    0x00000700      
   DCD    0x00000700     
   DCD    0x00018005      
   DCD    0x00018005      
   DCD    0x008C07A3      
   DCD    0x000000B1      
   DCD    0x00000030     
   DCD    0x00000030   
   END  
改动后的程序:即把bl memsetup直接用子程序代替。用红色字体显示






MEM_CTL_BASE   EQU    0x48000000
SDRAM_BASE     EQU    0x30000000

   IMPORT main
   AREA HEAD, CODE, READONLY
   ENTRY

bl  disable_watch_dog
mov r1,     #MEM_CTL_BASE      
    adrl    r2, mem_cfg_val         
    add r3,     r1, #52           
1  
    ldr r4,     [r2], #4           
    str r4,     [r1], #4           
    cmp r1,     r3               
    bne %B1                 
bl copy_steppingstone_to_sdram
ldr pc, =on_sdram                  
on_sdram
    ldr sp, =0x34000000               
    bl  main
halt_loop
    b   halt_loop

disable_watch_dog
   
    mov r1,     #0x53000000
    mov r2,     #0x0
    str r2,     [r1]
    mov pc,     lr
copy_steppingstone_to_sdram
  
    ldr r1, =SDRAM_BASE
    ldr r2, =SDRAM_BASE
    mov r3, #4*1024
    mov r0, #0
1  
    ldr r4, [r1],#4     
    str r4, [r2],#4
    add r0, r0, #4   
    cmp r0, r3         
    bne %B1            
    mov pc,     lr      

memsetup
   

    mov r1,     #MEM_CTL_BASE      
    adrl    r2, mem_cfg_val         
    add r3,     r1, #52           
1  
    ldr r4,     [r2], #4           
    str r4,     [r1], #4           
    cmp r1,     r3               
    bne %B1                        
    mov pc,     lr                 


    ALIGN 4
mem_cfg_val
   
   DCD    0x22011110      
   DCD    0x00000700      
   DCD    0x00000700     
   DCD    0x00000700     
   DCD    0x00000700   
   DCD    0x00000700      
   DCD    0x00000700     
   DCD    0x00018005      
   DCD    0x00018005      
   DCD    0x008C07A3      
   DCD    0x000000B1      
   DCD    0x00000030     
   DCD    0x00000030   
   END
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-4-27 16:54 , Processed in 1.062493 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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