uboot-start.S


 *  Startup Code for MIPS32 XBURST CPU-core
 *
 *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <config.h>
#include <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
#include <asm/arch/base.h>
#include "traps.h"


    .set noreorder
    .set mips32r2

    .globl _start
    .text
_start:
#if (defined(CONFIG_X2000_V12) || defined(CONFIG_M300))
#ifdef CONFIG_JZ_SECURE_SUPPORT
    .space 2048, 0

#endif
#endif
/*串口发送数据 0*/
#ifdef _DEBUG

    la      v0, 0xb0030000
    li    t0, '0'
    sw     t0, 0(v0)
loop0:
    lbu     v1, 0x14(v0)
    li    t1, 0x60
    andi    v1, v1, 0x60
    bne     v1, t1, loop0
    nop
    nop
#endif
    /* Initialize $gp */
    bal    1f
     nop
    .word    _gp
1:
    lw    gp, 0(ra)
/*串口发送数据 1*/
#ifdef _DEBUG


    la      v0, 0xb0030000
    li    t0, '1'
    sw     t0, 0(v0)
loop1:
    lbu     v1, 0x14(v0)
    andi    v1, v1, 0x60
    bne     v1, 0x60, loop1
    nop
    nop
#endif
    /* Set up temporary stack 4M*/
    li    sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
/*串口发送数据 2*/
#ifdef _DEBUG
    la      v0, 0xb0030000
    li    t0, '2'
    sw     t0, 0(v0)
loop2:
    lbu     v1, 0x14(v0)
    andi    v1, v1, 0x60
    bne     v1, 0x60, loop2
    nop
    nop
#endif
    la    t9, board_init_f

/*串口发送数据 4*/
#ifdef _DEBUG
    la      v0, 0xb0030000
    li    t0, '3'
    sw     t0, 0(v0)
loop3:
    lbu    v1, 0x14(v0)
    andi    v1, v1, 0x60
    bne     v1, 0x60, loop3
    nop
    nop
#endif
    jr    t9
     nop

/*重定向是把uboot代码从CONFIG_SYS_MONITOR_BASE=0X80100000地址搬运到addr_moni=0x87f5c000地址运行,搬运后,每个程序相对偏移一样,等于relocate_offset
 * void relocate_code (addr_sp, gd, addr_moni)
 *
 * This "function" does not return, instead it continues in RAM
 * after relocating the monitor code.
 *
 * a0 = addr_sp #0x86f1bf48
 * a1 = gd      #global_data
 * a2 = destination address #0x87f5c000
 */
    .globl    relocate_code
    .ent    relocate_code
relocate_code:
    move    sp, a0            # set new stack pointer sp=a0=0x86f1bf48

    li    t0, CONFIG_SYS_MONITOR_BASE = t0 = 0x80100000
    sub    t6, a2, t0        # t6 <-- relocation offset  = 0x87f5c000 - 0x80100000 = 0x7e5c000

    la    t3, in_ram   #加载in_ram标号地址
    lw    t2, -12(t3)  #in_ram向前偏移12个字节    # t2 <-- __image_copy_end
    move    t1, a2 #t1 = a2 = 0x87f5c000

    add    gp, t6    #gp = gp + 0x7e5c000        # adjust gp

    /*
     * t0 = source address = 0x80100000
     * t1 = target address = 0x87f5c000
     * t2 = source end address = __image_copy_end
     */
#搬运代码
1:
    lw    t3, 0(t0)
    sw    t3, 0(t1)
    addu    t0, 4
    blt    t0, t2, 1b
     addu    t1, 4

    /* If caches were enabled, we would have to flush them here. */

    /* flush d-cache */
    i    t0, KSEG0 #0x80000000
    or    t1, t0, CONFIG_SYS_DCACHE_SIZE #0x80008000
2:
    cache    INDEX_WRITEBACK_INV_D, 0(t0)
    bne    t0, t1, 2b
     addi    t0, CONFIG_SYS_CACHELINE_SIZE #32

    sync

    /* flush i-cache */
    li    t0, KSEG0
    or    t1, t0, CONFIG_SYS_ICACHE_SIZE
3:
    cache    INDEX_INVALIDATE_I, 0(t0)
    bne    t0, t1, 3b
     addi    t0, CONFIG_SYS_CACHELINE_SIZE

    /* Invalidate BTB */
    mfc0    t0, CP0_CONFIG, 7
    nop
    ori    t0, 2
    mtc0    t0, CP0_CONFIG, 7
    nop

    /* Jump to where we've relocated ourselves */
    addi    t0, a2, in_ram - _start #t0 =  a2 + (in_ram - _start)=0x87f5c00(重定向后的ram起始地址)  + (in_ram - _start)(此时的in_ram相对于_start=CONFIG_SYS_MONITOR_BASE的相对偏移)
                    #获取重定向后的in_ram
    jr    t0
     nop

    .word    __rel_dyn_end
    .word    __rel_dyn_start
    .word    __image_copy_end
    .word    _GLOBAL_OFFSET_TABLE_
    .word    num_got_entries

in_ram:
    /*
     * Now we want to update GOT.
     *
     * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
     * generated by GNU ld. Skip these reserved entries from relocation.
     */
    lw    t3, -4(t0)#800ffffc        # t3 <-- num_got_entries   #t0 = CONFIG_SYS_MONITOR_BASE 0x80100000
    lw    t4, -8(t0)#800ffff8        # t4 <-- _GLOBAL_OFFSET_TABLE_ #t4获取到旧的got地址
    add    t4, t6            # t4 now holds relocated _G_O_T_   #t6 = a2 - t0 = 0x87f5c000 - 0x80100000  t4+relocate_offset = 重定位之后的got表地址
    addi    t4, t4, 8        # skipping first two entries
    li    t2, 2
1:
    lw    t1, 0(t4)          #将got表中每一个entry存储的全局变量的地址 加载到 t1中
    beqz    t1, 2f           #如果entry中存储的地址为zero,跳转到label 2执行
    add    t1, t6           #分支延时槽: 将label中存储的全局变量的地址加上relocate_offset
    sw    t1, 0(t4)       #将计算后的全局变量的地址存放到got的entry项中
2:
    addi    t2, 1           #处理完一个got entry后t2计数加1
    blt    t2, t3, 1b       #比较当前处理过的got-entry数是不是已经到达got中总entry数num_got_entries,如果没有则跳转到label 1,重新处理下一个entry
     addi    t4, 4           #在分支延时槽中将got-pointer + 4,指向下一个entry地址

    /* Update dynamic relocations */
    lw    t1, -16(t0)        # t1 <-- __rel_dyn_start
    lw    t2, -20(t0)        # t2 <-- __rel_dyn_end

    b    2f            # skip first reserved entry
     addi    t1, 8
#rel.dyn段加上-pie就会自动出现,目的是告诉我们那些是位置无关代码需要重定位,每一个rel.dyn是8个字节,高四位是label低四位存储的是no-pic地址的地址

1:                    
    lw    t3, -4(t1)        # t3 <-- relocation info,获取高位label

    sub    t3, 3                   #如果高位label值等于3,就处理,否则,直接获下一个rel.dyn,
    bnez    t3, 2f            # skip non R_MIPS_REL32 entries
     nop

    lw    t3, -8(t1)        # t3 <-- location to fix up in FLASH 加载该rel.dyn存储着低四位的程序地址(重定位之前在flash中的地址)的地址

    lw    t4, 0(t3)        # t4 <-- original pointer从改地址中获取到程序的地址
    add    t4, t6            # t4 <-- adjusted pointer给程序地址加上relocate_offset,得到重定位后的程序运行地址(在ram中的地址)

    add    t3, t6            # t3 <-- location to fix up in RAM将存放程序地址的地址改为在ram中的地址
    sw    t4, 0(t3)               #保存重定向后程序地址

2:
    blt    t1, t2, 1b        #处理所有rel.dyn
     addi    t1, 8            # each rel.dyn entry is 8 bytes

    /*
     * Clear BSS #将bss全部写0
     *
     * GOT is now relocated. Thus __bss_start and __bss_end can be
     * accessed directly via $gp.
     */
    la    t1, __bss_start        # t1 <-- __bss_start
    la    t2, __bss_end        # t2 <-- __bss_end

1:
    sw    zero, 0(t1)
    blt    t1, t2, 1b
     addi    t1, 4
#board_init_r(gd,addr_moni)-->r(ram)
#board_init_r有两个参数,参数1:global_data  参数2:重定向后运行地址addr_moni = 0x87f5c000(根据x2000nand打印信息获取)
    move    a0, a1            # a0 <-- gd
    la    t9, board_init_r
    jr    t9
     move    a1, a2  #分支延时槽

    .end    relocate_code


#ifdef CONFIG_XBURST_TRAPS
// push context: at, v0-v1,a0-a3,t0-t9,s0-s7,fp,ra, & pc
    .macro  SAVE_ALL
    .set noat
    .set noreorder
        sw ra,PT_RA(sp)
        sw fp,PT_FP(sp)
        sw t9,PT_T9(sp)
        sw t8,PT_T8(sp)
        sw s7,PT_S7(sp)
        sw s6,PT_S6(sp)
        sw s5,PT_S5(sp)
        sw s4,PT_S4(sp)
        sw s3,PT_S3(sp)
        sw s2,PT_S2(sp)
        sw s1,PT_S1(sp)
        sw s0,PT_S0(sp)
        sw t7,PT_T7(sp)
        sw t6,PT_T6(sp)
        sw t5,PT_T5(sp)
        sw t4,PT_T4(sp)
        sw t3,PT_T3(sp)
        sw t2,PT_T2(sp)
        sw t1,PT_T1(sp)
        sw t0,PT_T0(sp)
        sw a3,PT_A3(sp)
        sw a2,PT_A2(sp)
        sw a1,PT_A1(sp)
        sw a0,PT_A0(sp)
        sw v1,PT_V1(sp)
        sw v0,PT_V0(sp)
        sw AT,PT_AT(sp)
        mfc0 k1,CP0_STATUS
        sw k1,PT_STATUS(sp)
        mfc0 k1, CP0_EPC
        sw k1,PT_EPC(sp)
        mflo k1
        sw k1,PT_LO(sp)
        mfhi k1
        sw k1,PT_HI(sp)
    nop
    la t1,0x80000004
    sw sp,0(t1)
    .endm

#define    NESTED(symbol, framesize, rpc)                  \
        .globl    symbol;                         \
        .align    2;                              \
        .type    symbol, @function;              \
        .ent    symbol, 0;                       \
symbol:        .frame    sp, framesize, rpc

/*
 * END - mark end of function
 */
#define    END(function)                                   \
        .end    function;                \
        .size    function, .-function


/*
 * General exception vector for all other CPUs.
 *
 * Be careful when changing this, it has to be at most 128 bytes
 * to fit into space reserved for the exception handler.
 */
NESTED(handle_exception, 0, sp)
    addi sp,sp,-PT_LEN
    SAVE_ALL
    la    t9,0x80000000
    lw    t9,0(t9)
    jr    t9
    nop
    nop
END(handle_exception)

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值