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

链接脚本规划

我们从上图可以看到,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的全局变量,并不对等.[未初始化的全局变量(COMMON段)为弱符号,如果有同名的全局变量,可能会存在覆盖的情况]

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

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

//汇编方法1
.global _bss_start
_bss_start:
.word __bss_start
ldr r1, _bss_start //读取内存,这里是读取label所在内存的数据
//汇编方法2
ldr 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, =main
halt:
b halt 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

参数设置

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

简单BootLoader的更多相关文章

  1. ucore-lab1-练习1report

    练习1 report 问题1:OS镜像文件ucore.img是如何一步一步生成的(需要比较详细地解释Makefile中的每一条相关命令和命令参数的含义,以及说明命令导致的结果)? GNU make是一 ...

  2. stm32最简单的实现BootLoader

    BootLoader大家应该都知道是干什么的,简单的来说就是程序开始运行前的一段程序. 在成熟的产品中,通常都是采用BootLoader方式来升级产品的程序.也就是IAP升级.在了解完基本的实现原理后 ...

  3. 最简单的bootloader的编写

    目标:写出bootloader的第一阶段代码和第二阶段代码,并测试. 最简单的bootloader的编写步骤: 1. 初始化硬件:关看门狗.设置时钟.设置SDRAM.初始化NAND FLASH2. 如 ...

  4. Android Bootloader LittleKernel的两篇文章 【转】

    转自:http://blog.csdn.net/loongembedded/article/details/41747523 2014-12-05 14:37 3599人阅读 评论(2) 收藏 举报 ...

  5. Xmodem Bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 多年前玩Cisco交换 ...

  6. 自己用C语言写单片机PIC16 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 为什么自己写bootl ...

  7. PyInstaller 安装方法 及简单的编译exe (python3)

    安装PyInstaller //地址 https://github.com/pyinstaller/pyinstaller/tree/python3 //上面的链接已经失效,新的(20160809更) ...

  8. bootloader(转)

    本文详细地介绍了基于嵌入式系统中的 OS 启动加载程序 ―― Boot Loader 的概念.软件设计的主要任务以及结构框架等内容. 1. 引言在专用的嵌入式板子运行 GNU/Linux 系统已经变得 ...

  9. BootLoader 详解(3)

    BootLoader的stage2 stage2的代码是C语言来实现的,以便于实现更复杂的功能和取得更好的代码可读性和移植性.它与普通C语言程序不同的是,在编译和链接BootLoader这样的程序时, ...

随机推荐

  1. BZOJ1005 HNOI2008明明的烦恼(prufer+高精度)

    每个点的度数=prufer序列中的出现次数+1,所以即每次选一些位置放上某个点,答案即一堆组合数相乘.记一下每个因子的贡献分解一下质因数高精度乘起来即可. #include<iostream&g ...

  2. 微信小程序——常用快捷键【四】

    格式调整 ctrl+[, ctrl+]:代码行缩进(向前|向后) ctrl+shift+[, ctrl+shift+] :折叠打开代码块 ctrl+C, ctrl+V:复制粘贴,如果没有选中任何文件则 ...

  3. MySql 主从同步 (库名不同)

    主库:192.168.1.250 从库:192.168.1.199 主库  my.ini # For advice on how to change settings please see # htt ...

  4. lemon special judge模板

    /* argv[1]:输入文件 argv[2]:选手输出文件 argv[3]:标准输出文件 argv[4]:单个测试点分值 argv[5]:输出最终得分的文件 argv[6]:输出错误报告的文件 */ ...

  5. 「CF838B」 Diverging Directions

    B. Diverging Directions 题意 给出一个n个点2n-2条边的有向图.n-1条指向远离根方向的边形成一棵树,还有n-1条从非根节点指向根节点的边. q次操作,1修改第x条边权值为y ...

  6. 洛谷P4891 序列(势能线段树)

    洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...

  7. 搭建本地yum源并定时同步

    在生产中内网的机器都是不能访问外网,所以需要搭建本地yum源.以中国科学科技大学的yum源为基准.http://mirrors.ustc.edu.cn/ 有些模块会同步失败,可以wget下载至指定位置 ...

  8. 【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)

    [BZOJ5303][HAOI2018]反色游戏(Tarjan,线性基) 题面 BZOJ 洛谷 题解 把所有点全部看成一个\(01\)串,那么每次选择一条边意味着在这个\(01\)串的基础上异或上一个 ...

  9. 【lua】lua安装学习

    Lua 是用标准C语言编写并以源代码形式开放的一种轻量小巧的脚本语言,设计目的是为了嵌入应用程序中,为应用程序提供灵活的扩展和定制功能. lua官网 http://www.lua.org/ 安装lua ...

  10. poj 3186 Treats for the Cows(dp)

    Description FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for gi ...