U-boot start.s 详解

最近在学习Uboot,对其结构不清楚所以这篇文章还不错。

1、红色为汇编命令;棕色为gnu汇编命令; 蓝色 为寄存器;黑色为变量、常量、数字等;绿色为注释。
2、部分比较繁琐的注释用白色标出。

.globl _start 
       
@将_start声明为“全局变量”,且可以被外部引用。globl: makes the symbol visible to ld,在别的程序中出现:ldr   pc._star时,程序将跳转到这个地方执行

_start:
      b          reset     
@在_start行写入b reset语句 b指令就是无条件地跳到reset的地方运行
     ldr      pc ,  _undefined_instruction
@LDR 指令用于从存储器中将一个32 位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32 位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC 作为目的寄存器时,指令从存储器中读取的数据被当作目的地址,从而可以实现程序流程的跳转。
@ 发生中断 程序跳转到此行,程序将继续跳转到中断处理程序中执行。以下类同。我想一定是放在存储器0x00的位置,这样就可以系统可以根据中断向量的标号来找到跳转到对应的行。如中断向量是2,则会跳到 ldr    pc_prefetch_abort。
@ldr:load from memory into a register.
    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 

_undefined_instruction是一个标号,处理到这里时,as会把undefined_instruction的值按32bit(arm中的word指32位)的形式放在此标号处。
ldr pc, _undefined_instruction 就是从_undefined_instruction处取值,即undefined_instruction,并放入pc中。
*/
_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

/*上面这句,就是填充多少字节在后面。*/
.......

reset:          //复位启动子程序

       /* 设置CPUSVC32模式 */

//ARM 微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器

//和通用寄存器之间传送数据,程序状态寄存器访问指令包括以下两条:

//MRS 程序状态寄存器到通用寄存器的数据传送指令

//MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)

/*

MSR 通用寄存器到程序状态寄存器的数据传送指令

MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数

MSR 指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态寄存器中需要操作的位,32 位的程序状态寄存器可分为4 个域:

位[31:24]为条件标志位域,用f 表示;

位[23:16]为状态位域,用s 表示;

位[15:8]为扩展位域,用x 表示;

位[7:0]为控制位域,用c 表示;

MSR CPSR_c , R0 ;传送 R0 的内容到 SPSR ,但仅仅修改 CPSR 中的控制位域

*/

       mrs   r0,cpsr

/*

BIC{条件}{S} 目的寄存器,操作数1,操作数2

BIC 指令用于清除操作数1 的某些位,并把结果放置到目的寄存器中。操作数 1 应是一个寄存器,操作数 2可以是一个寄存器,被移位的寄存器,或一个立即数。操作数 2 为 32位的掩码,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。

指令示例:

BIC R0 , R0 ,#% 1011 ;该指令清除 R0 中的位 0 、 1 、和 3 ,其余的位保持不变。

*/

       bic   r0,r0,#0x1f // 清除r0的低五位。

/*

ORR 指令的格式为:

ORR{条件}{S} 目的寄存器,操作数1,操作数2

ORR 指令用于 在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数 1应是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数 1 的某些位。

指令示例:

ORR R0 , R0 ,# 3 ; 该指令设置 R0 的 0 、 1 位,其余位保持不变。

*/

       orr   r0,r0,#0xd3 // r0置位 d3=11010011

       msr   cpsr,r0 // r0写回cpsr

/*

COUNT EQU       0x40003100

LDR       R1,=COUNT是将COUNT这个变量的地址,也就是0x40003100放到R1中。

*/

# define pWTCON        0x53000000

# define INTMSK        0x4A000008

# define CLKDIVN    0x4C000014   

/* clock divisor register 此值来自于用户手册 */

//关闭看门狗

    ldr     r0, =pWTCON //把pWTCON的值装载到r0
    mov     r1, #0x0  // 0装载到r1
    str     r1, [r0] // 将0赋给r0指向的地址

// 禁止所有中断
 //禁止主中断控制器
    mov    r1, #0xffffffff  //把 0xffffffff 装载到 r1
    ldr    r0, =INTMSK  //把 INTMSK 的值装载到r0
    str    r1, [r0]  // 将 0xffffffff 赋给 INTMSK 指向的地址
# if defined(CONFIG_S3C2410)
//禁止子中断控制器
    ldr    r1, =0x3ff
    ldr    r0, =INTSUBMSK
    str    r1, [r0]
# endif
设置CPU的频率
CLKDIVN寄存器的reset默认值是0x00000000,
第0位=0,PCLK=HCLK;第0位=1,PCLK=HCLK/2;
第1位=0,HCLK=FCLK;第1位=1,HCLK=FCLK/2;
这里 HCLK=FCLK/2,PCLK=HCLK/2;
    ldr    r0, =CLKDIVN
    mov    r1, #3
    str    r1, [r0]

MCR 指令的格式为:

MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处

理器操作码2。

MCR 指令用于将ARM处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1 和协处理器操作码2为协处理器将要执行的操作,源寄存器为ARM 处理器的寄存器,目的寄存器1 和目的寄存器2 均为协处理器的寄存器。

指令示例:

MCR P3 , 3 , R0 , C4 , C5 , 6 ;该指令将 ARM 处理器寄存器 R0 中的数据传送到协处理器 P3 的寄存器 C4 和 C5 中。

5、MRC 指令

MRC 指令的格式为:

MRC{条件} 协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理

器操作码2。

MRC 指令用于将协处理器寄存器中的数据传送到ARM处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1 和协处理器操作码2为协处理器将要执行的操作,目的寄存器为ARM 处理器的寄存器,源寄存器1 和源寄存器2 均为协处理器的寄存器。

指令示例:

MRC P3 , 3 , R0 , C4 , C5 , 6 ;该指令将协处理器 P3 的寄存器中的数据传送到 ARM 处理器寄存器中.

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

    /*
     * before relocating, we have to setup RAM timing
     * because memory timing is board-dependend, you will
     * find a lowlevel_init.S in your board directory.
     */
    mov    ip, lr
    bl    lowlevel_init
    mov    lr, ip
    mov    pc, lr

你可能感兴趣的:(U-boot start.s 详解)