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. [离散时间信号处理学习笔记] 10. z变换与LTI系统

    我们前面讨论了z变换,其实也是为了利用z变换分析LTI系统. 利用z变换得到LTI系统的单位脉冲响应 对于用差分方程描述的LTI系统而言,z变换将十分有用.有如下形式的差分方程: $\displays ...

  2. rsync 服务器搭建遇到的问题

    问题一: @ERROR: chroot failed rsync error: error starting client-server protocol (code 5) at main.c(152 ...

  3. AtCoder Regular Contest 102 E Stop. Otherwise...

    题目链接:atcoder 大意:有\(n\)个骰子,每个骰子上面有\(k\)个数,分别是\(1\text ~ k\),现在求\(\forall i\in[2...2k]\),求出有多少种骰子点数的组合 ...

  4. 【XSY1642】Another Boring Problem 树上莫队

    题目大意 给你一棵\(n\)个点的树,每个点有一个颜色\(c_i\),每次给你\(x,y,k\),求从\(x\)到\(y\)的路径上出现次数第\(k\)多的颜色的出现次数 \(n,q\leq 1000 ...

  5. Breakable loop in Scratch

    Breakable loop in Scratch https://stackoverflow.com/questions/30682144/breakable-loop-in-scratch Bre ...

  6. Linux 日志分析脚本

    #### 以下代码,若出现无法使用,请根据底下图片,更改参数.根据 apache 日志格式修改 查看 apache 进程ps aux | grep httpd | grep -v grep | wc ...

  7. 数论细节梳理&模板

    初阶 扩展欧拉 \(k\ge\varphi(m)\)时,\(b^k\equiv b^{k\%\varphi(m)+\varphi(m)}(\bmod m\)) 扩展CRT 推式子合并同余方程. htt ...

  8. Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)

    题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...

  9. Hdoj 2454.Degree Sequence of Graph G 题解

    Problem Description Wang Haiyang is a strong and optimistic Chinese youngster. Although born and bro ...

  10. 【BZOJ5314】[JSOI2018]潜入行动(动态规划)

    [BZOJ5314][JSOI2018]潜入行动(动态规划) 题面 BZOJ 洛谷 题解 不难想到一个沙雕\(dp\),设\(f[i][j][0/1][0/1]\)表示当前点\(i\),子树中一共放了 ...