简单BootLoader
目录
- 简单BootLoader
- 概述
- NOR与NAND启动
- 链接脚本规划
- 初始化规划
- 参数设置
简单BootLoader
概述
目标: 启动内核,也就是需要读取内核到内存,也就是操作flash和内存
一个最基本的BootLoader应该有以下步骤:
- 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
- 如果bootloader比较大,要把它重定位到SDRAM
- 把内核从NAND FLASH读到SDRAM
- 设置要传给内核的参数
- 跳转执行内核
优化: 为了加快运行速度,应该提高主频,打开Icach
/* 启动ICACHE */mrc p15, 0, r0, c1, c0, 0 @ read control regorr 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, =0x53000000mov r1, #0str r1, [r0]/* 2. 设置时钟 */ldr r0, =0x4c000014// mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8str 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, =0x4c000004ldr r1, =S3C2440_MPLL_400MHZstr r1, [r0]/* 启动ICACHE */mrc p15, 0, r0, c1, c0, 0 @ read control regorr r0, r0, #(1<<12)mcr p15, 0, r0, c1, c0, 0 @ write it back/* 3. 初始化SDRAM */ldr r0, =MEM_CTL_BASEadr r1, sdram_config /* sdram_config的当前地址 */add r3, r0, #(13*4)
1:ldr r2, [r1], #4str r2, [r0], #4cmp r0, r3bne 1b/* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */ldr sp, =0x34000000bl nand_initmov r0, #0ldr r1, =_startldr r2, =__bss_startsub r2, r2, r1bl copy_code_to_sdrambl clear_bss/* 5. 执行main */ldr lr, =haltldr pc, =main
halt: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
简单BootLoader相关推荐
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(1)-实现一个简单的bootloader
直接看代码,即使已经理解了代码,但是还是会有种没有学到手的感觉.真正的掌握来自实践,来自己动手做出来."简单AB任务切换程序"系列文章的目的是,在bochs下,实践出简单AB两个任 ...
- stm32 通用bootloader_stm32最简单的实现BootLoader
BootLoader大家应该都知道是干什么的,简单的来说就是程序开始运行前的一段程序. 在成熟的产品中,通常都是采用BootLoader方式来升级产品的程序.也就是IAP升级. 在了解完基本的实现原理 ...
- 从零开始写一个简单的bootloader(1)
前言 之前学习嵌入式裸板程序也有一定的时间了,而一个bootloader则是裸板程序的一个集大成者,能包含很多的知识点,所以编写一个bootloader能巩固之前的所学.废话少讲,下面就开始正式的编写 ...
- 自己动手写一个简单的bootloader
自己动手写一个简单的bootloader 15年10月31日19:44:27 (一) start.S 写这一段代码前,先要清楚bootloader开始的时候都做什么了.无非就是硬件的初始化,我们想要写 ...
- 【实现操作系统 01】CentOS 9 安装配置 Bochs 2.7 虚拟机,及编写简单的 bootloader 并写入软盘启动
系统环境: OS:CentOS Stream release 9 (cmd: cat /etc/redhat-release) Linux Kernel:Linux 5.14.0-142.el9.x8 ...
- ARM的位置无关程序设计在Bootloader中的应用
http://www.mcuol.com/tech/107/26052.htm 引言 基于位置无关代码PIC(PositionIndependent Code)的程序设计在嵌入式应用系统开发中具有重 ...
- Bootloader
在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行.可以初始化硬件设备.建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境.在嵌入 ...
- bootloader烧写
http://blog.chinaunix.net/space.php?uid=7313069&do=blog&id=1676091 关于bootloader,先简要地总结一下.经过了 ...
- Linux内核启动速度优化,嵌入式Linux启动时间优化的秘密之五-Bootloader
描述 本文主要讲述嵌入式Linux启动时间优化的秘密,我们继续上篇没有讲完的嵌入式Linux启动时间优化方法,本文主要会讲Bootloader.想看上一篇的请查看本文结尾的链接. Bootloader ...
最新文章
- 【已解决】Win7搭建Python环境:Eclipse + PyDev插件
- TCP协议可靠性保证(确认应答机制,超时重传机制,流量控制,拥塞窗口)
- c语言小游戏贪吃神,[原创]自己编的一个贪吃蛇小游戏
- c++ 删除二叉树的子树_数据结构—树|二叉树|前序遍历、中序遍历、后序遍历【图解实现】...
- How To Install IonCube Loader
- jquery on()绑定的点击事件在js动态新添加的元素上无效
- MySQL/MariaDB数据库备份与恢复
- lamp一键安装包+linux,linux下的lanmp/lamp/lnmp一键安装包
- 阵列卡在服务器什么位置,阵列卡是什么
- sqlserver2000局域网无法远程访问
- 曾拯救Apple Watch的苹果工程师如今后继无人,美国制造业回流的人才之痛
- Chrome隐私设置错误,您的链接不是私密连接
- android 编译
- CoBOT检测出AI开源框架TensorFlow中的缺陷
- 华为过程可信cib是指_华为流程规范考.doc
- 转载:80,90后需要提前领悟的至高心法
- android控件属性padding
- Landsat5数据下载中国地区1988年
- Oracle 用户无法登录 LOCKED(TIMED)
- 一些关于通信拓扑、图论的内容笔记