博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单BootLoader
阅读量:6449 次
发布时间:2019-06-23

本文共 3850 字,大约阅读时间需要 12 分钟。

目录


title: 简单BootLoader

tags: linux
date: 2018-09-28 23:23:05
---

简单BootLoader

概述

目标: 启动内核,也就是需要读取内核到内存,也就是操作flash和内存

一个最基本的BootLoader应该有以下步骤:

  1. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
  2. 如果bootloader比较大,要把它重定位到SDRAM
  3. 把内核从NAND FLASH读到SDRAM
  4. 设置要传给内核的参数
  5. 跳转执行内核

优化: 为了加快运行速度,应该提高主频,打开Icach

/* 启动ICACHE */    mrc p15, 0, r0, c1, c0, 0   @ read control reg    orr r0, r0, #(1<<12)    mcr p15, 0, r0, c1, c0, 0   @ write it back

NOR与NAND启动

参考文档 ARM裸机>启动流程

  • NAND 启动自动复制到4KRAM

  • NOR启动,片内RAM为0x4000,0000

    mark

链接脚本规划

我们从上图可以看到,SDRAM的起始地址为0x3000,0000,SDRAM大小为64M,也就是地址顶端为0x3400,0000.预留512K给Bootloader,也就是规划hex(0x34000000-512*1024)=0x33f8,0000为Bootloader的起始地址.链接脚本考虑字节对齐.

SECTIONS {    . = 0x33f80000;    .text : { *(.text) }        . = ALIGN(4);    .rodata : {*(.rodata*)}         . = ALIGN(4);    .data : { *(.data) }        . = ALIGN(4);    __bss_start = .;    .bss : { *(.bss)  *(COMMON) }    __bss_end = .;}

链接脚本中有个COMMON段,这是未初始化的全局变量,一般情况下也是直接在链接阶段放在bss段进行清零.但是注意未初始化的全局变量与初始化为0的全局变量,并不对等.

对于全局变量来说,如果初始化了不为0的值,那么该全局变量则被保存在data段,如果初始化的值为0,那么将其保存在bss段,如果没有初始化,则将其保存在common段,等到链接时再将其放入到BSS段。关于第三点不同编译器行为会不同,有的编译器会把没有初始化的全局变量直接放到BSS段。

链接脚本中值的获取,具体参考./链接脚本.md

//汇编方法1.global _bss_start_bss_start:    .word __bss_startldr r1, _bss_start  //读取内存,这里是读取label所在内存的数据//汇编方法2ldr r1, =__bss_start//C方法extern int __bss_start;int val =&__bss_start;  //!< 获得__bss_start的值

初始化规划

#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))#define MEM_CTL_BASE    0x48000000.text.global _start_start:/* 1. 关看门狗 */    ldr r0, =0x53000000    mov r1, #0    str r1, [r0]/* 2. 设置时钟 */    ldr r0, =0x4c000014    //  mov r1, #0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1    mov r1, #0x05;            // FCLK:HCLK:PCLK=1:4:8    str r1, [r0]    /* 如果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       /* 写入控制寄存器 */    /* MPLLCON = S3C2440_MPLL_200MHZ */    ldr r0, =0x4c000004    ldr r1, =S3C2440_MPLL_400MHZ    str r1, [r0]    /* 启动ICACHE */    mrc p15, 0, r0, c1, c0, 0   @ read control reg    orr r0, r0, #(1<<12)    mcr p15, 0, r0, c1, c0, 0   @ write it back/* 3. 初始化SDRAM */    ldr r0, =MEM_CTL_BASE    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/* 4. 重定位 : 把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    /* 5. 执行main */    ldr lr, =halt    ldr pc, =mainhalt:    b haltsdram_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

参数设置

nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000);setup_start_tag();setup_memory_tags();setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");setup_end_tag();void setup_start_tag(void){    params = (struct tag *)0x30000100;    params->hdr.tag = ATAG_CORE;    params->hdr.size = tag_size (tag_core);    params->u.core.flags = 0;    params->u.core.pagesize = 0;    params->u.core.rootdev = 0;    params = tag_next (params);}

内核存储在0x60000+64,读取到运行地址0x30008000,参数存储在0x30000100,最后传入机器ID=362

theKernel = (void (*)(int, int, unsigned int))0x30008000;theKernel(0, 362, 0x30000100);

转载于:https://www.cnblogs.com/zongzi10010/p/10023691.html

你可能感兴趣的文章
oracle数据库中的事务
查看>>
line-height(行高)
查看>>
svn客户端使用
查看>>
Java代码调用RTX发送提醒消息
查看>>
entity 的特别用法
查看>>
运行系统命令而且将输出写到指定日志文件的shell脚本(2)
查看>>
第十五周学习进度
查看>>
Mounting File Systems
查看>>
jdbc连接各种数据库方式列表
查看>>
v4l2子系统学习心得
查看>>
jQuery 获取包含当前节点html的方法
查看>>
python作业1.1,编写登录模块
查看>>
2.03_Python网络爬虫Http和Https
查看>>
EasyUI Layout 布局_摘
查看>>
App递交的一般流程和注意事项
查看>>
六:在线工具网站,让你PC上要装的软件少一半!
查看>>
python操作Excel读写--使用xlrd
查看>>
UI Framework-1: Native Controls
查看>>
mysql 安装
查看>>
我也不知道什么玩意~
查看>>