U-boot-2009.03移植之六:对一些关键标号的理解以及start.s中代码重定向原理

 

由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改

连接器脚本来完成。
1. board/samsung/mini2440/uboot.lds: ENTRY(_start) ==> cpu/arm920t/start.o (.text)
以下附上board/samsung/mini2440/uboot.lds源码
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
 . = 0x00000000;

 . = ALIGN(4);
 .text      :
 {
   cpu/arm920t/start.o (.text)
         board/samsung/mini2440/lowlevel_init.o  (.text)
   board/samsung/mini2440/nand_read.o  (.text)
   *(.text)
 }

 . = ALIGN(4);
 .rodata : { *(.rodata) }

 . = ALIGN(4);
 .data : { *(.data) }

 . = ALIGN(4);
 .got : { *(.got) }

 . = .;
 __u_boot_cmd_start = .;
 .u_boot_cmd : { *(.u_boot_cmd) }
 __u_boot_cmd_end = .;

 . = ALIGN(4);
 __bss_start = .;
 .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
 _end = .;
}
2. uboot在ram的代码区(TEXT_BASE = 0x33F80000)定义在board/samsung/mini2440/config.mk
以下附上源码
# SMDK2410 has 1 bank of 64 MB DRAM
#
# 3000'0000 to 3400'0000
#
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F8'0000
#
# download area is 3300'0000
#


TEXT_BASE = 0x33f80000
从上面的源码可以看出,RAM对应的地址范围是3000'0000 to 3400'0000(针对64MRAM)
内核将被定位在30008000,这就是为什么后来我们使用UBOOT下载内核要指定这个地址的原因
UBOOT在RAM中被重定向在33F8'0000

这里可以很好的理解start.s中判断UBOOT是在flash中运行还是在ram中运行的原理,实际上是通过对比_start和TEXT_BASE
_start是个相对地址,它的值取决于start.o的第一句代码此时在哪个地址,如果是在flash中运行,则等于0x000000,如果是在ram中运行,则等于TEXT_BASE


start.s中把u-boot.lds定义的text段,rodata段,data段,got段,__u_boot_cmd_start段搬移到ram区的代码如下:
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:    /* relocate U-Boot to RAM     */
 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
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */


放在flash中最前面地址的,是一个中断向量表,当发生异常或者中断的时候,程序讲跳转到相应的中断向量表中,而这些表中,存放的是一些地址,程序会继而跑到相应地址执行

相应处理程序。其中,最特别的,就是重启,可以认为,重启也是一个中断,当发生重启时,程序将跳转到向量表中的第一个,也就是,地址0,如果此时是在flash中运行,则是

0x00000000,如果是在ram中运行,则是0x33f80000,而这个地址中的内容则是跳转到_start_code:(老版本的标号是reset)
start.S最前面的代码为:
.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

跳转到start_code之后,首先执行设置ARM进入管理员模式,就是svc32模式,然后开始整个启动过程。
1:CPU进入管理模式;
2:关看门狗和中断;
3:CPU的初始化
4:堆栈设置
5:时钟的初始化
6:代码搬运到内存中

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值