uboot start.S文件分析

U-boot 第一个开始文件arch\arm\cpu\arm1176\start.S

start.S文件分析:

/*

 *  armboot - Startup Code for ARM1176 CPU-core

 *

 * Copyright (c) 2007 Samsung Electronics

 *

 * Copyright (C) 2008

 * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>

 *

 * 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

 *

 * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)

 * 2007-09-21 - Added MoviNAND and OneNAND boot codes by

 * jsgood (jsgood.yang@samsung.com)

 * Base codes by scsuh (sc.suh)

 */

 

#include <config.h>

#include <version.h>

#ifdef CONFIG_ENABLE_MMU

#include <asm/proc/domain.h>

#endif

 

#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)

#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE

#endif

 

/*

 *************************************************************************

 *

 * Jump vector table as in table 3.1 in [1]

 *

 *************************************************************************

 */

 

.globl _start

_start: b reset

/*异常向量表,为中断异常作准备*/

/* 当异常发生pc会跳到.wrod后面的地址处处理异常*/

#ifndef CONFIG_NAND_SPL

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

/*未定义指令异常,程序从地址0x4处开始执行*/

_undefined_instruction:

.word undefined_instruction

/*软件中断处理指令,,0x8处开始执行*/

_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

_pad:

.word 0x12345678 /* now 16*4=64 */

#else

. = _start + 64

#endif

 

.global _end_vect

_end_vect:

.balignl 16,0xdeadbeef

/*

 *************************************************************************

 *

 * Startup Code (reset vector)

 *

 * do important init only if we don't start from memory!

 * setup Memory and board specific bits prior to relocation.

 * relocate armboot to ram

 * setup stack

 *

 *************************************************************************

 */

/*uboot代码的运行地址*/

_TEXT_BASE:

/*uboot程序的运行地址为0xc7e00000

  即代码放到我们的sdram*/

.word TEXT_BASE

 

/*

 * Below variable is very important because we use MMU in U-Boot.

 * Without it, we cannot run code correctly before MMU is ON.

 * by scsuh.

 */

/*uboot会开启mmu, 以下是开启mmuuboot存放的真实物理地址

_TEXT_PHY_BASE:

.word CONFIG_SYS_PHY_UBOOT_BASE

 

/*_start标号和编译时运行的地址有关系,

  text_base参数通知编译器程序运行在0xc7e00000

  那么标号也是此值

*/

.globl _armboot_start

_armboot_start:

.word _start

 

/*

 * These are defined in the board-specific linker script.

 */

/*u-boot.lds中指定*/

.globl _bss_start

_bss_start:

.word __bss_start

 

.globl _bss_end

_bss_end:

.word _end

 

/*

 * the actual reset code

 */

reset:

/*

 * set the cpu to SVC32 mode

 */

    /*使cpu的模式为管理模式.即保证cpsr低五位的值为10011*/

mrs r0, cpsr /*r0=cpsr*/

bic r0, r0, #0x3f  /*后后6位清零*/

orr r0, r0, #0xd3  /*11010011*/

msr cpsr, r0

 

/*

 *************************************************************************

 *

 * CPU_init_critical registers

 *

 * setup important registers

 * setup memory timing

 *

 *************************************************************************

 */

/*

 * we do sys-critical inits only at reboot,

 * not when booting from ram!

 */

cpu_init_crit:

/*

 * When booting from NAND - it has definitely been a reset, so, no need

 * to flush caches and disable the MMU

 */

#ifndef CONFIG_NAND_SPL

/*

 * flush v4 I/D caches

 */

mov r0, #0

mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */

mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

 

/*

 * disable MMU stuff and caches

 */

mrc p15, 0, r0, c1, c0, 0

bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)

bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) /*0为小端,1为大端*/

orr r0, r0, #0x00000002 @ set bit 2 (A) Align /*打开地址对齐检察*/

orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache /*打开指令缓存*/

 

/* Prepare to disable the MMU */

adr r2, mmu_disable_phys

sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE)

b mmu_disable

 

.align 5

/* Run in a single cache-line */

mmu_disable:

mcr p15, 0, r0, c1, c0, 0

nop

nop

mov pc, r2

mmu_disable_phys:

 

#ifdef CONFIG_DISABLE_TCM

/*

 * Disable the TCMs

 */

mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */

cmp r0, #0

beq skip_tcmdisable

mov r1, #0

mov r2, #1

tst r0, r2

mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/

tst r0, r2, LSL #16

mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/

skip_tcmdisable:

#endif

#endif

 

#ifdef CONFIG_PERIPORT_REMAP

/* Peri port setup */

ldr r0, =CONFIG_PERIPORT_BASE

orr r0, r0, #CONFIG_PERIPORT_SIZE

mcr p15,0,r0,c15,c2,4

#endif

 

/*

 * Go setup Memory and board specific bits prior to relocation.

 */

/*初始化工作:关看门狗、关闭中断、初始化时钟、

              nand flash初始化、内存控制器初始化、

                 */

bl lowlevel_init /* go setup pll,mux,memory */

 

#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 */

 

#ifdef CONFIG_ENABLE_MMU

enable_mmu:

/* enable domain access */

ldr r5, =0x0000ffff

mcr p15, 0, r5, c3, c0, 0 /* load domain access register */

 

/* Set the TTB register */

ldr r0, _mmu_table_base

ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE

ldr r2, =0xfff00000

bic r0, r0, r2

orr r1, r0, r1

mcr p15, 0, r1, c2, c0, 0

 

/* Enable the MMU */

mrc p15, 0, r0, c1, c0, 0

orr r0, r0, #1 /* Set CR_M to enable MMU */

 

/* Prepare to enable the MMU */

adr r1, skip_hw_init

and r1, r1, #0x3fc

ldr r2, _TEXT_BASE

ldr r3, =0xfff00000

and r2, r2, r3

orr r2, r2, r1

b mmu_enable

 

.align 5

/* Run in a single cache-line */

mmu_enable:

 

mcr p15, 0, r0, c1, c0, 0

nop

nop

mov pc, r2

skip_hw_init:

#endif

 

/* Set up the stack     */

stack_setup:

ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM     */

sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area                      */

sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */

sub sp, r0, #12 /* leave 3 words for abort-stack    */

bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

 

/*bss段内容*/

clear_bss:

ldr r0, _bss_start /* find start of bss segment        */

ldr r1, _bss_end /* stop here                        */

mov  r2, #0 /* clear                            */

 

clbss_l:

str r2, [r0] /* clear loop...                    */

add r0, r0, #4

cmp r0, r1

ble clbss_l

 

#ifndef CONFIG_NAND_SPL

ldr pc, _start_armboot

 

_start_armboot:

.word start_armboot

#else

 

/*check boot status */

#define MEM_CFG_STAT 0x7E00F12C

 

ldr r1, =MEM_CFG_STAT /* address of reg  MEM_CFG_STAT*/

ldr r0, [r1]

mov  r1, #0x60

and r1, r0, r1 /*r1 = MEM_CFG_STAT & CFG_BOOT_LOC */

 

cmp r1, #0x60 /*Internal ROM*/

beq boot_from_irom

cmp r1, #0x00 /*Stepping Stone area in NFCON*/

beq nand_boot

b reset

/* .word nand_boot*/

boot_from_irom:

b mmc_boot_copy /*MINI6410 boot from Internal ROM-->MMC boot*/

#endif

 

#ifdef CONFIG_ENABLE_MMU

_mmu_table_base:

.word mmu_table

#endif

 

#ifndef CONFIG_NAND_SPL

/*

 * we assume that cache operation is done before. (eg. cleanup_before_linux())

 * actually, we don't need to do anything about cache if not use d-cache in

 * U-Boot. So, in this function we clean only MMU. by scsuh

 *

 * void theLastJump(void *kernel, int arch_num, uint boot_params);

 */

#ifdef CONFIG_ENABLE_MMU

.globl theLastJump

theLastJump:

mov r9, r0

ldr r3, =0xfff00000

ldr r4, _TEXT_PHY_BASE

adr r5, phy_last_jump

bic r5, r5, r3

orr r5, r5, r4

mov pc, r5

phy_last_jump:

/*

 * disable MMU stuff

 */

mrc p15, 0, r0, c1, c0, 0

bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */

bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */

orr r0, r0, #0x00000002 /* set bit 2 (A) Align */

orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */

mcr p15, 0, r0, c1, c0, 0

 

mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

 

mov r0, #0

mov pc, r9

#endif

 

 

/*

 *************************************************************************

 *

 * Interrupt handling

 *

 *************************************************************************

 */

@

@ IRQ stack frame.

@

#define S_FRAME_SIZE 72

 

#define S_OLD_R0 68

#define S_PSR 64

#define S_PC 60

#define S_LR 56

#define S_SP 52

 

#define S_IP 48

#define S_FP 44

#define S_R10 40

#define S_R9 36

#define S_R8 32

#define S_R7 28

#define S_R6 24

#define S_R5 20

#define S_R4 16

#define S_R3 12

#define S_R2 8

#define S_R1 4

#define S_R0 0

 

#define MODE_SVC 0x13

#define I_BIT  0x80

 

/*

 * use bad_save_user_regs for abort/prefetch/undef/swi ...

 */

 

.macro bad_save_user_regs

/* carve out a frame on current user stack */

sub sp, sp, #S_FRAME_SIZE

/* Save user registers (now in svc mode) r0-r12 */

stmia sp, {r0 - r12}

 

ldr r2, _armboot_start

sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)

/* set base 2 words into abort stack */

sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)

/* get values for "aborted" pc and cpsr (into parm regs) */

ldmia r2, {r2 - r3}

/* grab pointer to old stack */

add r0, sp, #S_FRAME_SIZE

 

add r5, sp, #S_SP

mov r1, lr

/* save sp_SVC, lr_SVC, pc, cpsr */

stmia r5, {r0 - r3}

/* save current stack into r0 (param register) */

mov r0, sp

.endm

 

.macro get_bad_stack

/* setup our mode stack (enter in banked mode) */

ldr r13, _armboot_start

/* move past malloc pool */

sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)

/* move to reserved a couple spots for abort stack */

sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)

 

/* save caller lr in position 0 of saved stack */

str lr, [r13]

/* get the spsr */

mrs lr, spsr

/* save spsr in position 1 of saved stack */

str lr, [r13, #4]

 

/* prepare SVC-Mode */

mov r13, #MODE_SVC

@ msr spsr_c, r13

/* switch modes, make sure moves will execute */

msr spsr, r13

/* capture return pc */

mov lr, pc

/* jump to next instruction & switch modes. */

movs pc, lr

.endm

 

.macro get_bad_stack_swi

/* space on current stack for scratch reg. */

sub r13, r13, #4

/* save R0's value. */

str r0, [r13]

/* get data regions start */

ldr r0, _armboot_start

/* move past malloc pool */

sub r0, r0, #(CONFIG_SYS_MALLOC_LEN)

/* move past gbl and a couple spots for abort stack */

sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)

/* save caller lr in position 0 of saved stack */

str lr, [r0]

/* get the spsr */

mrs r0, spsr

/* save spsr in position 1 of saved stack */

str lr, [r0, #4]

/* restore r0 */

ldr r0, [r13]

/* pop stack entry */

add r13, r13, #4

.endm

 

/*

 * exception handlers

 */

.align 5

undefined_instruction:

get_bad_stack

bad_save_user_regs

bl do_undefined_instruction

 

.align 5

software_interrupt:

get_bad_stack_swi

bad_save_user_regs

bl do_software_interrupt

 

.align 5

prefetch_abort:

get_bad_stack

bad_save_user_regs

bl do_prefetch_abort

 

.align 5

data_abort:

get_bad_stack

bad_save_user_regs

bl do_data_abort

 

.align 5

not_used:

get_bad_stack

bad_save_user_regs

bl do_not_used

 

.align 5

irq:

get_bad_stack

bad_save_user_regs

bl do_irq

 

.align 5

fiq:

get_bad_stack

bad_save_user_regs

bl do_fiq

#endif /* CONFIG_NAND_SPL */

 

链接地址:\board\samsung\mini6410\u-boot-nand.lds

 

程序的一般步骤:

初始化:关看门狗 

          初始化时钟

          初始化sdram

把程序从nand flash拷贝到sdram

设置sp 

posted @ 2013-06-03 22:18  retacn_yue  阅读(439)  评论(0编辑  收藏  举报