主题 : 2440test中的代码复制部分的一个小问题,只有这个问题没有想通啦 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 1852
精华: 0
发帖: 21
金钱: 195 两
威望: 183 点
综合积分: 42 分
注册时间: 2008-10-06
最后登录: 2012-12-02
楼主  发表于: 2009-07-10 00:35

 2440test中的代码复制部分的一个小问题,只有这个问题没有想通啦

2440test中的2440init.s中的代码复制部分,有判断从nandflash启动还是norflash启动分别复制执行代码的功能。

norflash启动基本上清楚了,就是如果是norflash启动再判断运行域和加载域是不是都在同一个空间,如果是就跳过可执行代码的复制部分(可执行代码已经在运行域也就是内存中间),但是此时内存中的程序的RW段还是按默认的方式紧跟着RO段的,所以接下来的动作就只是根据ads的baseofbss来重定向在sdram中的RW段。如果运行域和加载域不是同一个空间,就把在加载域norflash中的代码拷贝到sdram中在重定向RW段,最后ldr pc,=F2来实现绝对地址的跳转到sdram中运行。

但是如果从nandflash来启动,程序复制代码到绝对地址中(ldr r9, =ResetEntry程序放到r9中地址为基地址的内存中)。复制过程中并判断nandflash是否有坏块,是好块的话直接复制到sdram中,并且是nandflash的完全复制,此时的sdram中有一个nandflash的镜像。接下来程序会顺行执行上面说的norflash启动的程序。按理来说应该这个时候sdram中已经有了可执行代码部分,就只要重定位RW段就可以了,但是在读程序
copy_proc_beg
    adr    r0, ResetEntry
    ldr    r2, BaseOfROM
会发现,copy_proc_beg还是会直接拷贝RO段的,adr r0, ResetEntry这个时候r0是0地址,照我想的话这里应该在nandflash部分程序执行完后
r0要是0x30000000才会直接重定位RW段的,
我这个逻辑到底对不对,版主帮我忙吧!
    谢谢!
级别: 新手上路
UID: 1852
精华: 0
发帖: 21
金钱: 195 两
威望: 183 点
综合积分: 42 分
注册时间: 2008-10-06
最后登录: 2012-12-02
1楼  发表于: 2009-07-10 01:35
晕死  
copy_proc_beg
    adr    r0, ResetEntry    
    ldr    r2, BaseOfROM
经过我测试发现执行了adr    r0, ResetEntry这句r0的内容果然是0x30000000,为什么程序执行完nand_boot_beg段后会这样哦

nand_boot_beg
    ;adr    r0,ResetEntry
    ;ldr    r1,=Entry    
    ;str    r0,[r1]
    mov    r5, #NFCONF
    ;set timing value
    ldr    r0,    =(7<<12)|(7<<8)|(7<<4)
    str    r0,    [r5]
    ;enable control
    ldr    r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
    str    r0, [r5, #4]
    
    bl    ReadNandID
    mov    r6, #0
    ldr    r0, =0xec73
    cmp    r5,    r0
    beq    %F1
    ldr    r0, =0xec75
    cmp    r5, r0
    beq    %F1
    mov    r6, #1
1    
    bl    ReadNandStatus
    
    mov    r8, #0      ldr    r9, =ResetEntry;    
2    ands    r0, r8, #0x1f
    bne        %F3
    mov        r0, r8
    bl        CheckBadBlk
    cmp        r0, #0
    addne    r8, r8, #32
    bne        %F4
3    
    mov    r0, r8
    mov    r1, r9
    bl    ReadNandPage
    add    r9, r9, #512
    add    r8, r8, #1
4    
    cmp    r8, #5120
    bcc    %B2
    
    mov    r5, #NFCONF            ;DsNandFlash
    ldr    r0, [r5, #4]
    bic r0, r0, #1
    str    r0, [r5, #4]
    ldr    pc, =copy_proc_beg
;===========================================================
copy_proc_beg
    adr    r0, ResetEntry
0    cmp r0,#0x30000000     ;这两行是测试用r0的值用的
    beq %B0    ;这两行是测试用r0的值用的
    ldr    r2, BaseOfROM
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2009-07-10 09:15
要搞清楚这个问题,先去搞懂adr和ldr指令的区别
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 1852
精华: 0
发帖: 21
金钱: 195 两
威望: 183 点
综合积分: 42 分
注册时间: 2008-10-06
最后登录: 2012-12-02
3楼  发表于: 2009-07-10 10:56
ldr r0,=loop 这个伪指令,最后的的loop地址是连接后的绝对地址,是程序相对偏移加0x30000000(ads设置RO地址)
为什么程序运行了nand_boot_beg程序之后adr    r0, ResetEntry   r0的值也是0x30000000
级别: 新手上路
UID: 1852
精华: 0
发帖: 21
金钱: 195 两
威望: 183 点
综合积分: 42 分
注册时间: 2008-10-06
最后登录: 2012-12-02
4楼  发表于: 2009-07-10 13:56
至于相通了  豁然开朗啦  就是爽
原来nand_boot_beg程序的最后一句是 ldr    pc, =copy_proc_beg是跳到了运行域的copy_proc_beg当然在copy_proc_beg程序的第一句adr    r0, ResetEntry  r0的内容是运行域中ResetEntry的地址也就是0x30000000,就是这样的
copy_proc_beg
    adr    r0, ResetEntry
求真知!去浮躁!
级别: 侠客
UID: 6514
精华: 0
发帖: 86
金钱: 770 两
威望: 642 点
综合积分: 172 分
注册时间: 2009-06-04
最后登录: 2019-08-08
5楼  发表于: 2009-07-10 16:24
支持这种专研精神!
尊严不是别人给的,是自己争取来的!!!
级别: 新手上路
UID: 15797
精华: 0
发帖: 6
金钱: 30 两
威望: 6 点
综合积分: 12 分
注册时间: 2010-03-09
最后登录: 2010-05-04
6楼  发表于: 2010-03-27 15:24
非常经典………………