Bootloader学习笔记 12

    xiaoxiao2021-03-25  95

    Bootloader简介 开发板在系统上电时,需要一段程序来进行初始化:关闭看门狗(WATCHDOG)、改变系统时钟、初始化存储控制器、将后续的代码复制到内存中等。像这样一段代码,它能将操作系统内核从本地或者远端复制到内存中运行,我们称之为Bootloader. 简而言之,Bootloader的目标,在系统上电时开始执行,初始化硬件设备、准备好软件环境,最后启动内核。 如何编写Bootloader 一、 搭建系统框架 1. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH 2. 如果bootloader比较大,要把它重定位到SDRAM 3. 把内核从NAND FLASH读到SDRAM 4. 设置”要传给内核的参数” 5. 跳转执行内核 完善代码 1.新建source insight 工程,新建start.s文件参考芯片手册

    根据芯片手册中看门狗和系统时钟寄存器的值设置如下代码

    #define WTCON 0x53000000 #define CLKDIVN 0x4c000014 #define MPLLCON 0x4c000004 #define CLKDIVN 0x4c000014 .text .global _start _start: /* 1. 关看门狗 */ ldr r0, =WTCON mov r1, #0 // 0 disable str r1, [r0] /* 2. 设置时钟 */ ldr r0, =CLKDIVN mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1 str r1, [r0]

    在HDIVN不等于0的时候需要加人如下代码改变CPU总线模式

    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */ mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */ mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */

    由系统可知,输入频率为12MHZ,要想得到200MHZ的输出频率根据下表可得 MDIV选取0x5c这一行,400MHz再进行2分频可得200MHz即如下所示可以得到200MHz的寄存器值

    #define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))

    设置时钟频率

    /* MPLLCON = S3C2440_MPLL_200MHZ */ ldr r0, =MPLLCON ldr r1, =S3C2440_MPLL_200MHZ str r1, [r0]

    接着开始初始化SDRAM,设置BWSCON(BUS WIDTH&WAIT CONTROL REGISTER) 存储控制器总共有13个寄存器每个寄存器地址相差4,根据操作手册配置各个寄存器 首先将各个寄存器的配置放入数组中

    sdram_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

    然后循环初始化SDRAM

    /* 3. 初始化SDRAM */ ldr r0, =BWSCON adr r1, sdram_config /* sdram_config的当前地址 */ add r3, r0, #(13*4) 1: ldr r2, [r1], #4 str r2, [r0], #4 cmp r0, r3 /* 比较当前寄存器地址和最后一个寄存器地址*/ bne 1b /* break not equle 1 backward; 1f 1 forward*/

    初始化完成进行重定位,由于重定位比较麻烦,这里采用C语言处理

    /* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */ ldr sp, =0x34000000 /*设置栈:我们的内存为64M基地址0x30000000 一个地址对应16位,由于栈往下增长所以设置最高位就为0x30000000|(64M/16)*/ bl nand_init /*C函数 初始化NANDFLASH*/ mov r0, #0 /*copy_code_to_sdram函数的第一个参数*/ ldr r1, =_start ldr r2, =__bss_start sub r2, r2, r1 bl copy_code_to_sdram bl clear_bss

    初始化完成后进入主函数 C语言部分见 Bootloader学习笔记 2/2

    /* 5. 执行main */ ldr lr, =halt /*设置main函数返回地址*/ ldr pc, =main /*bl为当前指令无法跳到SDRAM里边执行,所以使用ldr*/ halt: b halt /*main 函数返回后进入死循环*/
    转载请注明原文地址: https://ju.6miu.com/read-24953.html

    最新回复(0)