免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5682 | 回复: 17
打印 上一主题 下一主题

2440的u-boot的start.s文件里的一些看不懂的代码,请高手帮忙解释下。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-01 20:32 |只看该作者 |倒序浏览
start.rar (3.39 KB, 下载次数: 45)

附件是arm920t的start.s文件的压缩包,我在第relocate这个标号开始的这段拷贝代码有点看不懂,问题在于如下这几句话:
relocate:                               
        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         */

copy_loop:
        ldmia        r0!, {r3-r10}                /* copy from source address [r0]    */
        stmia        r1!, {r3-r10}                /* copy to   target address [r1]    */
        cmp        r0, r2                        /* until source end addreee [r2]    */
        ble        copy_loop

问题1. 上面代码中r0 r1各自都存的是上面值?我个人感觉r0中存的就是start的第一句代码,即b  start_code,而r1中存的应该是_TEXT_BASE这个变量,这2者怎么可能会出现相等这种情况呢?也就是说beq stack_setup何时会执行?
问题2.  上面代码中一个sub 和一个add执行完后,进入loop之前,r2是个什么值?为什么要把sub得到的armboot长度加到r0上来,这算什么意思?这里所谓的armboot是不是就是第一个c程序_armboot_start?
问题3. 该带代码要把armboot具体复制到哪里?是复制到存放中断向量表的bootsram还是赋值到SDRAM?我的开发板显示bootsram是0x0开始的4KB,SDRAM是从0x30000000开始的。

非常感谢高手能帮我解答,如果有想一起讨论的,可以加Q:215587754 ,加的时候注明u-boot。

论坛徽章:
0
2 [报告]
发表于 2010-04-01 21:51 |只看该作者
_start 和 _TEXT_BASE 都是地址,放到r0 r1中

论坛徽章:
0
3 [报告]
发表于 2010-04-01 22:33 |只看该作者
_start 和 _TEXT_BASE 都是地址,放到r0 r1中
bitmilong 发表于 2010-04-01 21:51



    他们的值一样吗?我觉得_start始终要比_TEXT_BASE小啊,因为代码是先写_start,后写_TEXT_BASE的啊。怎么会出现一样的情况?它所说的从ram启动,应该是指比如休眠或者挂起以后再次启动。

论坛徽章:
0
4 [报告]
发表于 2010-04-02 00:13 |只看该作者
我的看法:
第一个问题:
adr指令取的是_start的运行时地址,即第一条指令的地址。_TEXT_BASE是程序在内存的起始运行地址。如果两者不相等说明程序是在flash里运行。这就需要将程序拷贝到内存里。也就是copy_loop的任务。如果两者相等,则说明加载地址和运行地址一样。而beq stack_setup这句不重要。重要的是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         */
这四段代码是为了计算整个程序的结束地址。我的看法:_armboot_start就是第一个C语言的入口地址。_bss_start是整个C程序的结束地址。两者相减后就是整个C程序的字节大小,即整个C程序的空间大小(C_Byte)。r0里存放的是_start,即第一条指令的地址。r0+C_Byte就是整个程序的结束地址。

第三个问题:
这个当然是要复制到内存(SDRAM)里。

以上回答都是个人愚见,有高手的话还请指点。

评分

参与人数 1可用积分 +18 收起 理由
bitmilong + 18 鼓励下

查看全部评分

论坛徽章:
0
5 [报告]
发表于 2010-04-02 09:04 |只看该作者
我的看法:
第一个问题:
adr指令取的是_start的运行时地址,即第一条指令的地址。_TEXT_BASE是程序在内存 ...
lanlovehua 发表于 2010-04-02 00:13



    TEXT_BASE是运行地址?焕然大悟。。。。。

论坛徽章:
0
6 [报告]
发表于 2010-04-02 09:10 |只看该作者
我的看法:
第一个问题:
adr指令取的是_start的运行时地址,即第一条指令的地址。_TEXT_BASE是程序在内存 ...
lanlovehua 发表于 2010-04-02 00:13



    你解释的第二个问题,最后一句话我还是不太清楚,如果相减后得到的是C程序的长度,也就是待拷贝进入SDRAM的长度,而_start是0x0,那么相加怎么就成了整个程序的结束地址?整个程序的结束地址不就是_bss的值吗?
我觉得这个_start地址是0x0,加和不加应该都没效果才对啊?岂不是多此一举?

论坛徽章:
0
7 [报告]
发表于 2010-04-02 12:14 |只看该作者
1. r0中存放的是代码运行时地址,r1中则是加载地址,如果不相等则进行数据拷贝,因为大部分代码(主要是C代码)是位置相关的,只有把代码放到加载地址处,程序才能正确执行,另外,运行时地址和加载时地址是有肯能相等的;
2. sub        r2, r3, r2                /* r2 <- size of armboot            */
r2中存放代码段到堆栈段的size,这里包括代码段,数据段,只读数据段等;
add        r2, r0, r2                /* r2 <- source end address         */
r0是代码段的运行起始地址
r0+r2则是堆栈段的运行时起始地址,即要拷贝数据的结束地址
_armboot_start的值可以在本文件中查找,找不到的话就肯定在链接文件中定义的,不过它到底在哪里定义不重要,它应该也是代表代码的起始地址,和TEXT_BASE的值应该相等
3. 这个很明显是复制到_TEXT_BASE指定的地址处

好久没开这块的代码了,不知道解释清楚没有,反正大概原理就是这样吧

评分

参与人数 1可用积分 +30 收起 理由
bitmilong + 30 鼓励

查看全部评分

论坛徽章:
0
8 [报告]
发表于 2010-04-06 10:48 |只看该作者
1. r0中存放的是代码运行时地址,r1中则是加载地址,如果不相等则进行数据拷贝,因为大部分代码(主要是C代码 ...
chengxuetao 发表于 2010-04-02 12:14



    谢谢你的回复,我明白了

论坛徽章:
0
9 [报告]
发表于 2010-04-06 20:37 |只看该作者
我也在看这段代码,也有个问题:

.globl _start
_start:        b       start_code               
        ldr        pc, _undefined_instruction
        ldr        pc, _software_interrupt
        ldr        pc, _prefetch_abort
        ldr        pc, _data_abort
        ldr        pc, _not_used
        ldr        pc, _irq
        ldr        pc, _fiq

_undefined_instruction:        .word undefined_instruction
_software_interrupt:        .word software_interrupt
_prefetch_abort:        .word prefetch_abort
_data_abort:                .word data_abort
_not_used:                .word not_used
_irq:                        .word irq
_fiq:                        .word fiq

这里
start_code时用的是b,也就是相对跳转
而其他的中断用的是ldr,绝对跳转
请问:这和代码的重定址有关系吗?

论坛徽章:
0
10 [报告]
发表于 2010-04-06 21:26 |只看该作者
回复 9# OLAY玉兰油



跟寻址空间有关系吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP