WDS1期第9课 uboot 2 之Makefile, uboot启动第一段


在这里插入图片描述

之前的裸机程序,上电需要做的事情在.S里边,大致步骤:

  1. 初始化
    关看门狗
    初始化时钟
    初始化SDRAM
  2. 把程序从nand拷贝到SDRAM
  3. 设置sp(使sp指向main所在内存)

uboot程序上电需要做的事情分为两段,第一段主要是底层的硬件初始化:

  1. 设为管理模式
  2. 关闭看门狗
  3. 屏蔽中断
  4. 初始化SDRAM(需要配置存储管理器等)
  5. 设置栈
  6. 时钟
  7. 重定位(代码从flash拷贝到SDRAM)
  8. 清bss段
  9. 调用start_armboot (c代码,串口/USB/网卡等等 )

cpu/arm920t/start.S

.globl _start
_start:	b       reset

首先跳转到reset的地方,将cpu设置为管理模式

reset:
	/*
	 * set the cpu to SVC32 mode # 设置为管理模式
	 */
	mrs	r0,cpsr
	bic	r0,r0,#0x1f
	orr	r0,r0,#0xd3
	msr	cpsr,r0

关闭看门狗

#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

读取中_start的地址,与_TEXT_BASE比较:
如果是上电运行,代码的前4K会被自动从nand拷贝到内部的SRAM中,则_start的地址就是0;
如果程序是通过调试器仿真器直接下载到SDRAM,则_start的地址就是链接地址0x33F80000。

	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	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         */
	blne	cpu_init_crit
#endif

比较结果不等说明SDRAM还没有被初始化,需要到cpu_init_crit去初始化SDRAM:

  1. 关flush清空cache
  2. 关MMU
  3. 初始化存储控制器(lowlevel_init在board/100ask24x0/lowlevel_init.S)
#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
	...
	...
		bl	lowlevel_init

栈的划分:
在这里插入图片描述

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

初始化时钟,usb,系统的时钟

bl clock_init

clock_init在board/100ask24x0/boot_init.c,

void clock_init(void)
        /* 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;

重定位:代码从flash中读到SDRAM中,地址为链接地址,

#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     clear_bss
	
	ldr	r2, _armboot_start
	ldr	r3, _bss_start
	sub	r2, r3, r2		/* r2 <- size of armboot            */
#if 1
	bl  CopyCode2Ram	/* r0: source, r1: dest, r2: size */
#else
	add	r2, r0, r2		/* r2 <- source end address         */

CopyCode2Ram在board/100ask24x0/boot_init.c中,

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;
    }
}

其中bBootFrmNORFlash是判断从nand启动还是从nor启动,判断方式是看0地址可写与否,如果写进去和读出来的数据同则为nand启动;因为nor不能像RAM一样去写,所以读出来的不等于写进去的数据。
int bBootFrmNORFlash(void)
{
    volatile unsigned int *pdw = (volatile unsigned int *)0;
    unsigned int dwVal;
    
    /*
     * 无论是从NOR Flash还是从NAND Flash启动,
     * 地址0处为指令"b	Reset", 机器码为0xEA00000B,
     * 对于从NAND Flash启动的情况,其开始4KB的代码会复制到CPU内部4K内存中,
     * 对于从NOR Flash启动的情况,NOR Flash的开始地址即为0。
     * 对于NOR Flash,必须通过一定的命令序列才能写数据,
     * 所以可以根据这点差别来分辨是从NAND Flash还是NOR Flash启动:
     * 向地址0写入一个数据,然后读出来,如果没有改变的话就是NOR Flash
     */

    dwVal = *pdw;       
    *pdw = 0x12345678; // 重点
    if (*pdw != 0x12345678)
    {
        return 1;
    }
    else
    {
        *pdw = dwVal;
        return 0;
    }
}

清bss段:

clear_bss:
	ldr	r0, _bss_start		/* find start of bss segment        */
	ldr	r1, _bss_end		/* stop here                        */
	mov 	r2, #0x00000000		/* clear                            */

board/100ask24x0/uboot.lds文件中,意思是存放所有文件的bss段

	. = ALIGN(4);
	__bss_start = .;
	.bss : { *(.bss) }
	_end = .;

以上都是硬件相关的初始化,是uboot的第一阶段。
启动ARM核:

ldr	pc, _start_armboot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值