本帖最后由 itelectron 于 2009-11-5 00:21 编辑
u-boot代码链接的问题
环境和配置:u-boot-1.1.2, arm-linux-gcc(v3.2), redhat linux9.0, cpu(s3c44b0), board(B2)
在/board/dave/B2/u-boot.lds有
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/s3c44b0/start.o (.text)
*(.text)
}
而/board/dave/B2/config.mk中有
TEXT_BASE = 0x0C100000
最后编译出来的代码反汇编得到
0c100000 <_start>:
c100000: ea00000a b c100030 <reset>
c100004: e28ff303 add pc, pc, #201326592 ; 0xc000000
c100008: e28ff303 add pc, pc, #201326592 ; 0xc000000
c10000c: e28ff303 add pc, pc, #201326592 ; 0xc000000
c100010: e28ff303 add pc, pc, #201326592 ; 0xc000000
c100014: e28ff303 add pc, pc, #201326592 ; 0xc000000
c100018: e28ff303 add pc, pc, #201326592 ; 0xc000000
c10001c: e28ff303 add pc, pc, #201326592 ; 0xc000000
0c100020 <_TEXT_BASE>:
c100020: 0c100000 ldceq 0, cr0, [r0]
0c100024 <_armboot_start>:
c100024: 0c100000 ldceq 0, cr0, [r0]
0c100028 <_bss_start>:
c100028: 0c115694 ldceq 6, cr5, [r1], -#592
0c10002c <_bss_end>:
c10002c: 0c1198a4 ldceq 8, cr9, [r1], -#656
0c100030 <reset>:
c100030: e10f0000 mrs r0, CPSR
链接得到的起始地址为什么是TEXT_BASE,而不是0呢,所以现在只能够下载到ram中运行,但是无法烧写道flash中跑,这是怎么回事呢?u-boot中应该是start.S中的这段代码在flash中运行吧,后面就把自身拷贝到ram中TEXT_BASE地址处,为什么在链接文件中指定的_start的起始地址为0x00000000呢?
blob中把整个代码分为两部分,所以有两个连接文件,前面1k在flash中运行,链接起始地址为0x0,ram中运行的,然后通过工具把两部分组合到一起,但是u-boot是怎么做的呢?
迷惑中,请帮忙解答,谢先!
Re: u-boot代码链接的问题
好象与这个地址没关系的
u-boot既可以在SDRAM中,
也可在Flash中运行
Re: u-boot代码链接的问题
兄弟,首先需要知道CPU的启动方式,一般来说有BOOTROM,SPI,FLASH这三种方式;一般来说也不会存在从SDRAM/DRAM上启动机器,因为它们不可能作为永久存储。
然后就是需要知道,外设地址映射关系,对于CPU来说总是有统一的IO地址映射,并且在不同的访问模式下,地址映射关系不一定相同。
还有,代码可以运行在不同的介质上,如:上述三种再包括RAM/ROM。
另外:还要知道代码段的链接地址,这个你应该是知道的。
最后,就可以考虑你的FLASH启动问题了。在Uboot里面的-text的参数,应该是真对某个硬件系统的配置,这个就是FLASH的高端地址或者低端地址。
一般来说,bootloader的代码的第一段总是运行在永久介质上,例如:FLASH,然后才将代码搬移到DRAM中,这个时候在dram中执行第二段BOOTLOADER的代码段,也就是你说下载到内存中的说法,实际上他都已经运行了一个阶段了。在内存中的运行入口地址,按照系统情况可以自行安排了。
因此,这个最开始的FLASH地址,肯定不是0,是什么看看你的单板的DATASHEET和编程参考
Re: u-boot代码链接的问题
谢谢,我的板子cpu是s3c44b0,不支持memory remap,flash为4M,从0x00000000到0x00400000,
sdram为8M,地址从0x0c000000到0x0c800000,我不清楚的问题时链接脚本中指定的_start的入口地址为0x00000000,为何编译出来的代码。链接地址是从0x0c100000开始的,即把TEXT_BASE作为_start的入口地址了,如果我把TEXT_BASE改为0x00000000,那么后面的rellocate代码还有意义吗?
Re: u-boot代码链接的问题
我猜测,问题可能有可能,我说的仅仅是may be:
和我前面说的一样,boot loader一般有两段代码段(独立的),在连接的时候也是分别连接,故此有两个代码连接文件,和编译过程共产生的两个MAP文件,可以查一下你看的连接文件和编译文件是不是对应的。
另外有两个建议:
1:这个也是疑惑,我看了你的问题后,作了这样的前提假设(个人的理解):在dram里的loader stage起始地址是定义在sdram的最低端。从这个假设出来,我觉得这个链接也是有问题的,因为一般来说sdram的最低端是做向量表、和模式栈顶区、参数区来用的,这个肯定有问题
2:分析这个问题,首先要确定你的编译过程,可以把编译过程定向到一个文件中仔细的分析,可以看到编译链接各个细节。不妨发给我一份hls780204cn@vip.sina.com
Re: u-boot代码链接的问题
TEXTADDR 是内核的虚拟起始地址,并且在arch/<target>/ 下的Makefile 中指定它的值。这个地址必须与引导装载程序使用的地址相匹配。 一旦引导装载程序将内核复制到闪存或DRAM 中,内核就被重新定位到TEXTADDR — 它通常在DRAM 中,然后,引导装载程序将控制转给这个地址,以便内核能开始执行。
Re: u-boot代码链接的问题
我已经理解了:
“链接得到的起始地址为什么是TEXT_BASE,而不是0呢,”
因为u_boot如果从flash运行的话,那么它会将自己的代码拷贝到RAM中,然后运行。u-boot开始部分代码与编译的入口没有关系,而主要的代码是在RAM中运行,因此编译的入口地址是TEXT_BASE.因此u-boot既可以flash运行,也可以ram运行。
“为什么在链接文件中指定的_start的起始地址为0x00000000呢?”
lds文件中的起始地址为0x00000000是不起作用的,由-TTEXT_BASE参数替代的。
刚开始比较疑惑的原因是对:
126 relocate: /* relocate U-Boot to RAM */
127 adr r0, _start /* r0 <- current position of code */
adr这条指令没有理解正确,因为把它想成mv r0,_start了,实际上adr这里的_start是相对的,如果从flash运行的话,r0就是0, 如果从ram运行的话,r0就是C100000。
我现在可以运行u-boot了,串口可以显示内容并且可以使用命令。但网卡驱动和flash驱动还有问题。慢慢搞就可以搞定,因为可以用printf调试的。
Re: u-boot代码链接的问题
楼上是不是说 因为adr指令是小范围地址读取指令,所以在不同的运行环境下,_start的值不同啊。
针对44box中的代码
adr r0, real_vectors
add r2, r0, #1024
ldr r1, =0x0c000000
add r1, r1, #0x08
vector_copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble vector_copy_loop
复制向量中断,为什么要复制1024个字节呢?
问得比较弱,见笑了。
Re: u-boot代码链接的问题
多一点是没有关系的
Re: u-boot代码链接的问题
在FLASH中以相对地址运行,然后一个绝对跳转完成从FLASH到RAM的切换,应该制定为UBOOT在RAM中的起始地址! |