嵌入式 hi3518c默认看门狗没有开启,uboot汇编start.s解析
来源:互联网 发布:大数据产业测度 编辑:程序博客网 时间:2024/06/05 21:54
/*====================================Hi3518c start.S Begin 2014-04-20=============================================*/
/*
* armboot - Startup Code for ARM926EJS CPU-core
*
* Copyright (c) 2003 Texas Instruments
*
* ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
*
* Copyright (c) 2001 Marius Gr?ger <mag@sysgo.de>
* Copyright (c) 2002 Alex Z?pke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
* Copyright (c) 2003 Kshitij <kshitij@ti.com>
*
* 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>
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start //汇编程序都要提供一个_start符号并且用.globl声明
_start: b reset //B或BL指令引起处理器转移到“子程序名”处开始执行 复位
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
_pad: .word 0x12345678 /* now 16*4=64 */
/*.fill
语法:.fill repeat, size, value
含义是反复拷贝 size个字节,重复 repeat 次,
其中 size 和 value 是可选的,默认值分别为 1 和 0.
*/
__blank_zone_start:
.fill 1024*4,1,0 //给某个具体的寄存器里填数
__blank_zone_end:
.globl _blank_zone_start
_blank_zone_start:
.word __blank_zone_start
.globl _blank_zone_end
_blank_zone_end:
.word __blank_zone_end
.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
*
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
_clr_remap_spi_entry:
.word SF_TEXT_ADRS + do_clr_remap - TEXT_BASE
_clr_remap_nand_entry:
.word NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr //将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0
bic r0,r0,#0x1f //位清除指令 将R0最低5位清零,其余位不变 工作模式位清零
orr r0,r0,#0xd3 //工作模式位设置为“10011”(管理模式),并将中断禁止位和快中断禁止位置1 "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中
msr cpsr,r0 //将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
/*
* flush v4 I/D caches
*/
mov r0, #0 //置零ro通用寄存器
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ //向c7写入0将使ICache与DCache无效 "0"表示省略opcode_2 MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ //MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2
/*
* 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) */
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
mcr p15, 0, r0, c1, c0, 0 //保存r0到控制寄存器
mov r0, pc, lsr#24 //LSL、LSR、ASR、ROR 寄存器移位
cmp r0, #0x0
bne do_clr_remap //检测是否需要跳转,PC的高八位如果不为0(已经在ram中运行了)则跳转 不等于则调转
check_start_mode:
ldr r0, =REG_BASE_SCTL
ldr r0, [r0, #REG_SYSSTAT]
mov r6, r0, lsr#5
and r6, #0x1
/* reg[0x2005008c:5]:
* 0: start from spi
* 1: start from nand
*/
cmp r6, #BOOT_FROM_SPI
ldreq pc, _clr_remap_spi_entry
ldr pc, _clr_remap_nand_entry
@b . /* bug here */
/*
LDR和STR用来存取内存,关于"索引偏移",你是不是指pre-indexed addressing和post-indexed addressingpre-indexed addressing是指地址经过运算不写回基址寄存器post-indexed addressing则回写到基址寄存器比如pre-indexed addressing:mov r1,#0STR r0, [r1, #0x10] ;r1+0x10这个是所用的实际地址值,但是不回写入r1,在此句之后,r1=0post-indexed addressing:STR r0, [r1], #0x10 ;r1+0x10这个是所用的实际地址值,这个值回写入r1,此句之后,r1=0x10
*/
do_clr_remap:
ldr r4, =REG_BASE_SCTL //用来从存储器(确切地说是地址空间)中装载数据到通用寄存器 系统控制器寄存器 0x20050000 写地址
ldr r0, [r4, #REG_SC_CTRL] //加载32位的立即数或一个地址值到指定寄存器 不回写 其实是r4+#0x0是实际地址值
/* reg[0x20050000:8]:
* 0: keep remap
* 1: clear remap 重映射
*/
@Set clear remap bit.
orr r0, #(1<<8) //第八位置1
str r0, [r4, #REG_SC_CTRL] //不回写 @表示注释
@Setup TCM (ENABLED, 2KB) // TCM时钟门控使能
ldr r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)
mcr p15, 0, r0, c9, c1, 1
@enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
@Check if I'm running in ddr //代码内存运行测试
mov r0, pc, lsr#28
cmp r0, #8
bleq relocate //小于等于跳转
ldr r0, _blank_zone_start
ldr r1, _TEXT_BASE //代码段
sub r0, r0, r1 //减法 sub a,b (a-b)
adrl r1, _start //将相对于程序或相对于寄存器的地址载入寄存器中 adrl宽
add r0, r0, r1 //加法
mov r1, #0 /* flags: 0->normal 1->pm */
bl init_registers //初始化寄存器
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:
@copy arm exception table in 0 address
adrl r0, _start
mov r1, #0
mov r2, #0x100 /* copy arm Exception table to 0 addr */
add r2, r0, r2
copy_exception_table:
ldmia r0!, {r3 - r10}
stmia r1!, {r3 - r10}
cmp r0, r2
ble copy_exception_table
@relocate U-Boot to RAM
adrl 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 */
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
bic sp, sp, #7 /*8-byte alignment for ABI compliance*/
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot
_start_armboot:
.word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* 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) */
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
/*
* Go setup Memory and board specific bits prior to relocation.
*/
mov ip, lr /* perserve link reg across call */
@bl lowlevel_init /* go setup pll,mux,memory */
mov lr, ip /* restore link */
mov pc, lr /* back to my caller */
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
#ifndef CONFIG_PRELOADER
/*
*************************************************************************
*
* 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 ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
@ carve out a frame on current user stack
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
ldr r2, _armboot_start
sub r2, r2, #(CONFIG_STACKSIZE+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}
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp @ save current stack into r0 (param register)
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack
sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
@ reserved a couple spots in abort stack
sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8)
str lr, [r13] @ save caller lr in position 0 of saved stack
mrs lr, spsr @ get the spsr
str lr, [r13, #4] @ save spsr in position 1 of saved stack
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13 @ switch modes, make sure moves will execute
mov lr, pc @ capture return pc
movs pc, lr @ jump to next instruction & switch modes.
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
#endif /* CONFIG_PRELOADER */
/*
* exception handlers
*/
#ifdef CONFIG_PRELOADER
.align 5 //加上.align汇编语句后,指令就对齐
do_hang:
ldr sp, _TEXT_BASE /* switch to abort stack */
1:
bl 1b /* hang and never return */
#else /* !CONFIG_PRELOADER */
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
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
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.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
#endif /* CONFIG_PRELOADER */
#include "lowlevel_init.S"
/*====================================Hi3518c start.S End=============================================*/
/*====================================Hi3518c lowlevelinit.s Begin=====================================*/
.text
.align 2
.global init_registers
.type init_registers, %function
init_registers:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r2, [r0, #0]
cmp r2, #0
mov r6, #1
bne .L43
.L2:
ldr r3, [r0, #4]
cmp r3, #0
bne .L43
ldr r3, [r0, #8]
cmp r3, #0
ldrne ip, [r0, #12]
bne .L3
ldr ip, [r0, #12]
cmp ip, #0
beq .L6
.L3:
cmp r1, #0
beq .L7
.L45:
tst ip, #2
beq .L8
and r4, ip, #248
mov r4, r4, lsr #3
add r4, r4, #1
cmp r4, #32
movne r4, r6, asl r4
andne ip, ip, #63488
ldr r5, [r2, #0]
movne ip, ip, lsr #11
subne r4, r4, #1
bicne r5, r5, r4, asl ip
ldrne r4, [r0, #4]
ldreq ip, [r0, #4]
orrne ip, r5, r4, asl ip
cmp r3, #0
str ip, [r2, #0]
beq .L11
.L29:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L29
.L11:
add r0, r0, #16
.L46:
ldr r2, [r0, #0]
cmp r2, #0
beq .L2
.L43:
cmp r1, #0
ldr r3, [r0, #8]
ldr ip, [r0, #12]
bne .L45
.L7:
tst ip, #4
beq .L18
and r4, ip, #248
mov r4, r4, lsr #3
add r4, r4, #1
cmp r4, #32
movne r4, r6, asl r4
andne ip, ip, #63488
ldr r5, [r2, #0]
movne ip, ip, lsr #11
subne r4, r4, #1
bicne r5, r5, r4, asl ip
ldrne r4, [r0, #4]
ldreq ip, [r0, #4]
orrne ip, r5, r4, asl ip
cmp r3, #0
str ip, [r2, #0]
beq .L11
.L32:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L32
add r0, r0, #16
b .L46
.L8:
tst ip, #131072
bne .L13
cmp r3, #0
beq .L11
.L31:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L31
add r0, r0, #16
b .L46
.L18:
tst ip, #262144
bne .L22
cmp r3, #0
beq .L11
.L34:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L34
add r0, r0, #16
b .L46
.L13:
and r4, ip, #16252928
mov r4, r4, lsr #19
add r4, r4, #1
mov r7, r6, asl r4
ldr r5, [r0, #4]
mov r8, ip, lsr #27
sub r7, r7, #1
.L16:
ldr ip, [r2, #0]
cmp r4, #32
andne ip, r7, ip, lsr r8
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
cmp r5, ip
bne .L16
cmp r3, #0
beq .L11
.L30:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L30
add r0, r0, #16
b .L46
.L22:
and r4, ip, #16252928
mov r4, r4, lsr #19
add r4, r4, #1
mov r8, r6, asl r4
ldr r5, [r0, #4]
sub r8, r8, #1
mov r7, ip, lsr #27
.L25:
ldr ip, [r2, #0]
cmp r4, #32
andne ip, r8, ip, lsr r7
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
cmp r5, ip
bne .L25
cmp r3, #0
beq .L11
.L33:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L33
add r0, r0, #16
b .L46
.L6:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
bx lr
/*====================================Hi3518c lowlevelinit.s End=====================================*/
1. 引言 1.1 编写目的
编写此文档记录学习uboot的过程,本文为系列第二篇
1.2 定义
无
2. 概述
U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:
(1)第一阶段的功能
· 硬件设备初始化
· 加载U-Boot第二阶段代码到RAM空间
· 设置好栈
· 跳转到第二阶段代码入口
(2)第二阶段的功能
· 初始化本阶段使用的硬件设备
· 检测系统内存映射
· 将内核从Flash读取到RAM中
· 为内核设置启动参数
· 调用内核
本文主要分析启动的第一阶段
3. 硬件设备初始化
根据链接脚本(本系列第一篇)\u-boot-2008.10\cpu\arm926ejs\start.s 文件为cpu上电后执行的第一的文件(第一段代码)
Start.s代码开头如下:
3.1 设置异常向量
.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 /* irq中断向量 */
ldr pc, _fiq /* 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
.balignl 16,0xdeadbeef //设置对齐方式为16位对齐方式,空白区域自动用0xdeafbeef填充
其中
_undefined_instruction;_software_interrupt为lable,和C语言里面的lable一样,lable的值为当前代码的地址。
.word为GCC汇编伪指令,表示在当前位置定义一个字的变量,变量的内容紧跟其后。
所以执行_undefined_instruction: .word undefined_instruction指令后的内存映像为:
地址
内容
大小
0x000000004
_undefined_instruction
undefined_instruction
Word(32)
以上代码设置了ARM异常向量表,各个异常向量介绍如下:
表 2.1 ARM异常向量表
地址
异常
进入模式
描述
0x00000000
复位
管理模式
复位电平有效时,产生复位异常,程序跳转到复位处理程序处执行
0x00000004
未定义指令
未定义模式
遇到不能处理的指令时,产生未定义指令异常
0x00000008
软件中断
管理模式
执行SWI指令产生,用于用户模式下的程序调用特权操作指令
0x0000000c
预存指令
中止模式
处理器预取指令的地址不存在,或该地址不允许当前指令访问,产生指令预取中止异常
0x00000010
数据操作
中止模式
处理器数据访问指令的地址不存在,或该地址不允许当前指令访问时,产生数据中止异常
0x00000014
未使用
未使用
未使用
0x00000018
IRQ
IRQ
外部中断请求有效,且CPSR中的I位为0时,产生IRQ异常
0x0000001c
FIQ
FIQ
快速中断请求引脚有效,且CPSR中的F位为0时,产生FIQ异常
在cpu\arm926ejs\start.s中还有这些异常对应的异常处理程序。当一个异常产生时,CPU根据异常号在异常向量表中找到对应的异常向量,然后执行异常向量处的跳转指令,CPU就跳转到对应的异常处理程序执行。
其中复位异常向量的指令“b start_code”决定了U-Boot启动后将自动跳转到标号“start_code”处执行。
3.2 设置定位lable
_TEXT_BASE:
.word TEXT_BASE
TEXT_BASE在系列一中有分析,在MAKEFIE 中通过TEXT_BASE指定代码段的VMA地址偏移,其中TEXT_BASE保存于board\hi3515v100\config.mk 中,在这里用来计算其他的地址偏移
.globl _armboot_start
_armboot_start:
.word _start
.globl _img_end
_img_end:
.word __img_end
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
以上代码定义了一些断地址,并导出为全局变量(.globle),在连接文件里面有对这些变量赋值,在这里同样用于计算偏移
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
此处尚有疑问
#ifdef CONFIG_HISILICON
_clr_remap_rom_entry:
.word ROM_TEXT_ADRS + do_clr_remap - TEXT_BASE
_clr_remap_nand_entry:
.word NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE
#endif
此处计算do_clr_remap的LMA,由于没有进行代码搬移前代码是执行在LMA地址上的(同时这一段代码也是地址无关的代码即PIC,关于地址无关的代码见博文http://hi.baidu.com/kinylei/blog/item/c7acf92235b8104493580795.html ),此处分别计算代码存储在norflash和nandflash里面的LMA.
3.3 设置其他相关
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
CPSR位图
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*
* 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) */
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
mcr p15, 0, r0, c1, c0, 0
以上禁止MMU
ldr r0, =REG_BASE_SCTL
ldr r1, [r0, #0x8c]
and r1, r1, #0x60
lsr r4, r1, #5
以上获取BOOT状态到R4
mov r0, pc, lsr#24s
cmp r0, #0x0
bne do_clr_remap
检测是否需要跳转,PC的高八位如果不为0(已经在ram中运行了)则跳转
cmp r4, #2 /* boot from nand flash*/
ldreq pc, _clr_remap_nand_entry
cmp r4, #0 /* boot from nor flash */
ldreq pc, _clr_remap_rom_entry
此处的_clr_remap_nand_entry与_clr_remap_rom_entry为LMA地址,前面已分析
do_clr_remap:
ldr r4, =REG_BASE_SCTL
@ldr r0, =REG_VALUE_SC_NOLOCK
@str r0, [r4, #REG_VALUE_SC_LOCKED]
ldr r0, [r4, #REG_SC_CTRL]
@Set clear remap bit.
orr r0, #(1<<8)
str r0, [r4, #REG_SC_CTRL]
@Setup ITCM (ENABLED, 4KB)
ldr r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)
mcr p15, 0, r0, c9, c1, 1
以上清除重映射,清除重映射后地址0x000000处安排为ITCM,此处有一个疑问,既然还运行在flash里面那么清重映射后就会运行在ITCM里面,但是ITCM里面保存有代码吗?
@enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
@Setup lowlevel sp
ldr sp, =(MEM_BASE_ITCM + MEM_SIZE_ITCM)
// @Check if I'm running in static mem bank
mov r0, pc, lsr#28
cmp r0, #(TEXT_BASE>>28)
/*
* Go setup Memory and board specific bits prior to relocation.
*/
beq relocate
bl lowlevel_init /* go setup pll,mux,memory */
#endif
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
ldr r0, =REG_BASE_SCTL
ldr r6, [r0, #0x8c]
and r6, #0x60
lsr r4, r6, #5
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, _img_end
sub r2, r3, r2 /* r2 <- size of armboot */
cmp r4, #2
ldreq r2, =(CFG_NAND_U_BOOT_ONE_PART)
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 */
以上重定位代码,既把代码段复制到ram空间里面
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
以上设置堆栈
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
以上清除BSS
ldr pc, _start_armboot
_start_armboot:
.word start_armboot
以上跳转到第二段
下图是分析到目前为止存储空间的示意图
- 嵌入式 hi3518c默认看门狗没有开启,uboot汇编start.s解析
- 嵌入式 hi3518c平台uboot中start.s小结
- 嵌入式 hi3518c平台uboot中start.s小结
- 嵌入式 关于hi3518c看门狗驱动程序示例
- 嵌入式 hi3518c看门狗驱动程序相关示例
- 嵌入式 hi3518c添加默认网关
- S5PV210-uboot解析(二)-start.S解析
- Uboot中start.S源码解析
- uboot移植之启动过程--汇编过程start.s
- S5PV210-uboot解析(二)-start.S解析-lowlevel_init函数分析
- 嵌入式 uboot、fs、kernel制作和烧录简记-hi3518c
- 嵌入式 uboot、fs、kernel制作和烧录简记-hi3518c
- uboot start.S分析
- uboot start.S分析
- UBoot的Start.S
- UBoot的Start.S
- uboot启动文件start.s和main.c解析
- uboot之start.s分析
- VMware和VirtualBox中的网络适配器类型及虚拟网络性能优化
- java.lang.NoSuchMethodError解决办法,
- 深入理解Servlet线程安全问题
- 5.容器配接器和字符串
- 人生何处不相逢
- 嵌入式 hi3518c默认看门狗没有开启,uboot汇编start.s解析
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
- 回文数(山东理工OJ)
- 【spark系列4】分类之SVMWithSGD
- 初识GCC
- 解决Qt中文乱码问题
- Graphics.MeasureString 不能获得精确宽度的问题
- ArrayList
- [Bzoj1588][HNOI2002]营业额统计 (Treap|Splay)