UBOOT源码分析1-汇编部分

UBOOT的源码分析1–汇编部分

  1. 关于汇编:
    没有错,基本进入公司汇编是不会让你弄的,但是你要懂最基本的“能了解”。
    因为基本所有的处理器启动代码都是从汇编开始的,因为C语言需要搭建环境。
    学习汇编入门,仅仅只需要把他们以C语言相对应起来,这样学的比较快。
    上一篇博文简单的写了几个C语言和汇编对应的例子。
  2. UBOOT的汇编部分(基于ARM9)
    2.1、设置处理器的模式为管理模式
    2.2、关闭看门狗
    2.3、屏蔽中断
    2.4、SDRAM初始化
    2.5、设置栈 (有了堆栈才有所谓的C语言)
    2.6、设置时钟
    2.7、重定位 (代码从FLASH拷贝到SDRAM内存里面去)
    2.8、清除BSS段 (全局变量弄为0)
    2.9、调用C函数 (start_armboot)

所有的上面的内容可以看成是处理器的–硬件初始化

  1. 基于UBOOT的例子分析(CPU/ARM920T/start.s)
    3.0 :刚开始的启动模式
.globl _start
_start: b       reset
    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

3.1 :把CPU设置为SVC32的管理模式

reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0xd3
    msr cpsr,r0

3.2 :关闭看门狗

/* turn off the watchdog */
#if defined(CONFIG_S3C2400)
# define pWTCON     0x15300000
# define INTMSK     0x14400008  /* Interupt-Controller base addresses */
# define CLKDIVN    0x14800014  /* clock divisor register */
#elif defined(CONFIG_S3C2410)
# define pWTCON     0x53000000
# define INTMOD     0X4A000004
# define INTMSK     0x4A000008  /* Interupt-Controller base addresses */
# define INTSUBMSK  0x4A00001C
# define CLKDIVN    0x4C000014  /* clock divisor register */
#endif

3.3 :屏蔽所有的中断

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
    ldr     r0, =pWTCON
    mov     r1, #0x0
    str     r1, [r0]

    /*
     * mask all IRQs by setting all bits in the INTMR - default
     */
    mov r1, #0xffffffff
    ldr r0, =INTMSK
    str r1, [r0]
# if defined(CONFIG_S3C2410)
    ldr r1, =0x3ff
    ldr r0, =INTSUBMSK
    str r1, [r0]
# endif

3.4 :进行一些CPU的初始化

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    adr r0, _start      /* r0 <- current position of code   */
如果说我们的程序是通过仿真器烧写进去的话,地址是0x30ff80
如果直接是通过NandFLASH烧写进去的话,那么地址就应该是0
    ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */
    cmp     r0, r1                  /* don't reloc during debug         */
    blne    cpu_init_crit
#endif

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 */
/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */

3.5 :初始化内存

lowlevel_init:
    mov r0, #0x70       /* 32-bit code + data, MMU mandatory */
    mcr p15, 0, r0, c1, c0, 0   /* MMU init */

    mov r0, #0
    mcr p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
    mcr p15, 0, r0, c8, c7, 0   /* flush v4 TLB */

    mov r0, #0x80000000     /* I/O base */

    mov r1, #0x6        /* CLKCTL_73 in SYSCON3 */
    add r2, r0, #0x2200     /* address of SYSCON3 in r2 */
    str r1, [r2]        /* set clock speed to 73.728 MHz */

    mov r1, #0x81       /* 64KHz DRAM refresh period */
    str r1, [r0, #0x200]    /* set DRFPR */

    mov r1, #0x500      /* permanent enable, 16bits wide */
    add r1, r1, #0x42       /* 128Mbit, CAS lat = 2 SDRAM */
    add r2, r0, #0x2300     /* load address in r2 */
    str r1, [r2]

    mov r1, #0x100      /* SDRAM refresh rate */
    add r2, r0, #0x2340     /* load address in r2 */
    str r1, [r2]

    mov sp, #SRAM_START     /* init stack pointer */
    add sp, sp, #SRAM_SIZE

    /* everything is fine now */
    mov pc, lr

3.6 :设置栈

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

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl clock_init
#endif    

3.7 :接下来初始化时钟

void clock_init(void)
{
    S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000;

    /* support both of S3C2410 and S3C2440, by www.100ask.net */
    if (isS3C2410)
    {
        /* FCLK:HCLK:PCLK = 1:2:4 */
        clk_power->CLKDIVN = S3C2410_CLKDIV;

        /* change to asynchronous bus mod */
        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */  
                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */  
                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */  
                    :::"r1"
                    );

        /* to reduce PLL lock time, adjust the LOCKTIME register */
        clk_power->LOCKTIME = 0xFFFFFFFF;

        /* configure UPLL */
        clk_power->UPLLCON = S3C2410_UPLL_48MHZ;

        /* some delay between MPLL and UPLL */
        delay (4000);

        /* configure MPLL */
        clk_power->MPLLCON = S3C2410_MPLL_200MHZ;

        /* some delay between MPLL and UPLL */
        delay (8000);
    }
    else
    {
        /* FCLK:HCLK:PCLK = 1:4:8 */
        clk_power->CLKDIVN = S3C2440_CLKDIV;

        /* change to asynchronous bus mod */
        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */  
                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */  
                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */  
                    :::"r1"
                    );

        /* to reduce PLL lock time, adjust the LOCKTIME register */
        clk_power->LOCKTIME = 0xFFFFFFFF;

        /* configure UPLL */
        clk_power->UPLLCON = S3C2440_UPLL_48MHZ;

        /* some delay between MPLL and UPLL */
        delay (4000);

        /* configure MPLL */
        clk_power->MPLLCON = S3C2440_MPLL_400MHZ;

        /* some delay between MPLL and UPLL */
        delay (8000);
    }
}

3.8 :把代码从NorFLASH中存储到FLASH中

int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
{
    unsigned int *pdwDest;
    unsigned int *pdwSrc;
    int i;

    if (bBootFrmNORFlash())
    {
        pdwDest = (unsigned int *)buf;
        pdwSrc  = (unsigned int *)start_addr;
        /* 从 NOR Flash启动 */
        for (i = 0; i < size / 4; i++)
        {
            pdwDest[i] = pdwSrc[i];
        }
        return 0;
    }
    else
    {
        /* 初始化NAND Flash */
        nand_init_ll();
        /* 从 NAND Flash启动 */
        nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
        return 0;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值