3.2【U-boot分析】从零手写BootLoader

一、BootLoader的目标是启动内核

        1)从Flash上把内核读入内存

                a)能读取Flash

                b)初始化内存/时钟/其他

        2)启动

                a)设置参数

                b)跳转执行

二、最简单的BootLoader编写步骤

        1)初始化硬件、关闭看门狗、设置时钟、设置SDRAM、初始化NAND FLASH。   

        2)如果BootLoader比较大,需要重定位到SDRAM

        3)把内核从NAND FLASH读到SDRAM中

        4)设置要传给内核的参数

        5)跳转到内核

 

    一>编写程序

1)初始化硬件、关闭看门狗、设置时钟、设置SDRAM、初始化NAND FLASH。——start.S

.text

.globl _start

_start:



/*第一步:关闭看门狗*/

       ldr   r0, =0x53000000

       mov   r1, #0

       str   r1, [r0]   /* 看门狗控制器的最低位为0时,看门狗不输出复位信号 */

/*第二步:设置时钟*/

             ldr      r0,   =0x4c000014

             mov    r1,  #0x03  //tFCLK:tHCLK:tPCLK = 1:2:4

             str       r1, [r0]

            //设置异步模式

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

       orr r0,r0,#R1_nF:OR:R1_iA

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


       ldr r0, =0x4C000004

       ldr r1, =(92<<12)|(1<<4)|(1<<0)

       str r1, [r0]

/*第三步:初始化SDRAM*/

       ldr r0, =0x48000000

       adr r1, sdram_config     /* sdram_config的当前地址 */

       add r3, r0, #(13*4)

1:

       ldr r2, [r1], #4U-Boot第二阶段代码分析

       str r2, [r0], #4

       cmp r0, r3

       bne 1b

/*第四步:重定位: 把bootloader本身的代码从flash复制到它的链接地址去*/

    ldr sp, =0x34000000

    bl nand_init



    mov r0, #0

    ldr r1, =_start

    ldr r2, =__bss_start

    sub r2, r2, r1

    bl copy_code_to_sdram

    bl clear_bss



/*第五步:执行main方法*/

       ldr lr, =halt

       ldr pc, =main

halt:

       b halt


dram_config:

    .long 0x22011110     //BWSCON

    .long 0x00000700     //BANKCON0

    .long 0x00000700     //BANKCON1

    .long 0x00000700     //BANKCON2

    .long 0x00000700     //BANKCON3  

    .long 0x00000700     //BANKCON4

    .long 0x00000700     //BANKCON5

    .long 0x00018005     //BANKCON6

    .long 0x00018005     //BANKCON7

    .long 0x008C04F4     // REFRESH

    .long 0x000000B1     //BANKSIZE

    .long 0x00000030     //MRSRB6

    .long 0x00000030     //MRSRB7

j

 

2)如果BootLoader比较大,需要重定位到SDRAM——init.c

/* NAND FLASH控制器 */

#define NFCONF (*((volatile unsigned long *)0x4E000000))

#define NFCONT (*((volatile unsigned long *)0x4E000004))

#define NFCMMD (*((volatile unsigned char *)0x4E000008))

#define NFADDR (*((volatile unsigned char *)0x4E00000C))

#define NFDATA (*((volatile unsigned char *)0x4E000010))

#define NFSTAT (*((volatile unsigned char *)0x4E000020))

/* GPIO */

#define GPHCON              (*(volatile unsigned long *)0x56000070)

#define GPHUP               (*(volatile unsigned long *)0x56000078)

/* UART registers*/

#define ULCON0              (*(volatile unsigned long *)0x50000000)

#define UCON0               (*(volatile unsigned long *)0x50000004)

#define UFCON0              (*(volatile unsigned long *)0x50000008)

#define UMCON0              (*(volatile unsigned long *)0x5000000c)

#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)

#define UTXH0               (*(volatile unsigned char *)0x50000020)

#define URXH0               (*(volatile unsigned char *)0x50000024)

#define UBRDIV0             (*(volatile unsigned long *)0x50000028)

#define TXD0READY   (1<<2)



void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);



int isBootFromNorFlash(void){

    volatile int *p = (volatile int *)0;

    int val;

    val = *p;

    *p = 0x12345678;

    if (*p == 0x12345678)

    {

        /* 写成功, 是nand启动 */

        *p = val;

        return 0;

    }

    else

    {

        /* NOR不能像内存一样写 */

        return 1;

    }

}









int cpoy_code_to_sdram(){

    int i = 0;

    

    /* 如果是NOR启动 */

    if (isBootFromNorFlash())

    {

        while (i < len)

        {

            dest[i] = src[i];

            i++;

        }

    }

    else

    {

        //nand_init();

        nand_read((unsigned int)src, dest, len);

    }

}

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林零七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值