第2阶段——编写uboot之硬件初始化和制作链接脚本lds(1)
目标:
第一阶段:
1.关看门狗
2.设置时钟
3.初始化SDRAM (初始化寄存器以及清除bss段)
4.重定位 (将nand/nor中代码COPY到链接地址上,需要初始化nandflash,读flash)
5.执行main
进入第二阶段:
6.写main函数,在main()中设置要传给内核的参数,然后跳转内核基地址处
7.制作uboot.lds链接脚本
编写步骤:
1.创建个名为"my_bootloader"根目录,方便编写uboot
2.新建my_bootloader/si目录,创建source insight工程
2.1 新建my_bootloader/start.S (后缀名必须是大写的S,或者后面编译会报错)
编写start.S (第一阶段初始硬件文件):
start.s任务:
1.关看门狗
2.设置时钟
3.初始化SDRAM
4.重定位(把bootloader本身的代码从flash复制到它的链接地址(c函数编写),然后清空bss段(c函数编写))
5.执行main
/* 看门狗寄存器 */
#define WTCON 0x53000000 /* 2.时钟寄存器 */
#define CLKDIVN 0x4C000014 //设置FCLK,HCLK,PCLK比例
#define MPLLCON 0x4C000004 //设置FCLK频率
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02)) //设置FCLK=200MHZ
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) //设置FCLK=400MHZ /* 3.bank寄存器 */
#define BWSCON 0x48000000 .text /*设置代码段*/
.global _start /*定义全局变量,要被连接脚本用到*/
_start: /*_start跳转到这里实现硬件初始化*/ /* 1.关看门狗 */
ldr r0,=WTCON
mov r1,#0
str r1,[r0] /* 2.设置时钟(必须设为异步总线模式) */ ldr r0,=CLKDIVN
mov r1,#3 /*FCLK:HCLK:PCLK=1:2:4*/
str r1,[r0]
mrc p15, 0, r1, c1, c0 /* 读出控制寄存器 */
orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */
ldr r0,=MPLLCON
ldr r1,=S3C2440_MPLL_200MHZ //使用复杂的数不能用mov,需要用ldr
str r1,[r0] /* 3.初始化SDRAM */
ldr r0,=BWSCON //r0=SDRAM寄存器基地址
adr r1,SDRAM_CONFIG //使用adr相对跳转,因为SDRAM未初始化
add r2,r0,#(13*4) //r2等于 SDRAM尾地址+4 0:
ldr r3,[r1],#4 //r3=r1里的 内容, &r1+=4;
str r3,[r0],#4 //*r0=r3,&r0+=4
cmp r0,r2
bne 0b //(ne:no equal b:bank) 若r0!=r2,跳转到后面的0处 /* 4.重定位 */
ldr sp,=0x34000000 //64Msdram,所以设置栈SP=0x34000000,避免堆栈溢出
mov r0,#0 //r0->src
ldr r1,=_start //r1->dest
ldr r2,=__bss_start //r2->len->__bss_start-_start
sub r2,r2,r1
bl copy_code_to_sdram //复制代码到SDRAM连接地址dest上
bl clear_bss //清除bss段 /* 5.执行main */
ldr lr,=halt //执行一个子程序调用返回时,需要先将返回地址赋给lr链接寄存器
ldr pc,=main //初始化SDRAM后,可以使用pc 绝对跳转到SDRAM地址上
mov pc,lr //若main函数跳出后,使PC等于lr链接寄存器,避免程序跑飞 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
3 新建my_bootloader/init.c,用于重定位,bss段清除,初始化NandFlash等
在重定位函数中的nand驱动在(入口:http://www.cnblogs.com/lifexy/p/7097695.html)里详细介绍了,这里就不描述了.
3.1编写copy_code_tosdram() 重定位函数
void copy_code_to_sdram(unsigned char *src,unsigned char *dest,unsigned int len) //复制代码到SDRAM连接地址dest上
{
unsigned int i;
/*判断nor启动还是nand启动*/
if(is_boot_from_norflash()) //nor启动,直接复制
{
for(i=0;i<len;i++)
{
dest[i]=src[i];
}
}
else
{
nand_init(); nand_read((unsigned int)src,dest,len); }
}
3.2编写isBootFramNorFlash()函数,来判断nand启动还是nor启动
/*判断nor启动还是nand启动*/
unsigned char is_boot_from_norflash(void)
{
volatile unsigned int *p=(volatile unsigned int *)0;
unsigned int i;
i=*p;
*p=0x12345678;
if(*p==0x12345678) //nand
{
*p=i;
return 0;
}
else //nor
{
*p=i;
return 1;
}
3.3编写clear_bss()函数
void clear_bss(void) //清除BSS段
{
extern int __bss_start,__bss_end;
int *p=&__bss_start;
for( ;p<&__bss_end;p++)
{
*p=0;
}
}
4编写连接脚本uboot.lds (参考硬件实验里的uart.lds和u-boot-1.1.6里的u-boot.lds)
SECTIONS {
. = 0x33f80000; //0地址里存放0X33F80000
. = ALIGN(4); .text : { *(.text) }
. = ALIGN(4); .rodata : { *(.rodata) }
. = ALIGN(4); .data : { *(.data) }
. = ALIGN(4); __bss_start = .;
.bss : { *(.bss) *(COMMON) }
__bss_end = .;
}
其中0x33f80000就是链接地址首地址,共512K空间存放bootloader
定义__bss_start和__bss_end符号,是用来程序开始之前将这些未定义的变量清0,节省内存
且bss_start-0x33f80000就等于代码的大小(copy_code_tosdram函数中len值)
第2阶段——编写uboot之硬件初始化和制作链接脚本lds(1)的更多相关文章
- 第2阶段——编写uboot之启动内核和制作Makefile(2)
目标: 1 添加头文件setup.h和serial.h 2 写main函数 2.1 帮内核设置串口0, (内核启动会打印出启动信息) 2.2把内核读入到SDRAM 2.3设置参数(参考u- ...
- 第2阶段——编写uboot之编译测试以及改进(3)
编译测试: 1.将写好的uboot复制到linux下面 2.make编译,然后将错误的地方修改,生成boot.bin (编译出错的解决方案:http://www.cnblogs.com/lifexy/ ...
- 第1阶段——uboot分析之硬件初始化start_armboot函数(5)
start_armboot()分析:在start.S初始化后跳转到start_armboot实现第2阶段硬件相关的初始化(烧写擦除flash,网卡驱动,usb驱动,串口驱动,从FLASH读内核,启动内 ...
- 第1阶段——uboot分析之硬件初始化start.S(4)
分析uboot第一个执行函数_start(cpu/arm920t/start.S) 打开cpu/arm920t/start.S .globl _start // .globl定义一个全局符号" ...
- u-boot中nandflash初始化流程分析(转)
u-boot中nandflash初始化流程分析(转) 原文地址http://zhuairlunjj.blog.163.com/blog/static/80050945201092011249136/ ...
- 硬件初始化,nand flash固化操作,系统启动简单流程
2015.3.27星期五 晴 链接脚本定义代码的排放顺序 硬件系统初始化:一:arm核初始化:(里面有指令)初始化ARM核的时候需要看arm核的手册指令:1.异常向量(最起码有个复位异常,初始化模式- ...
- 15.uboot study 串口初始化
3. 串口初始化 4. 代码实现 关于串口 对于嵌入式设备的开发,刚开始好多设备都无法使用,由于无法获得程序的运行状态,调试程序需要花费好多时间和精力,因此串口对于嵌入式程序的调试的作用显而易见,当串 ...
- 第1阶段——关于u-boot目标文件start.o中.globl 和.balignl理解(3)
汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为伪操作. .globl _start 作用:声明一个_start全局符号(Symbol), 这个_sta ...
- u-boot的配置、编译及链接
第一次写技术博客,还有些兴奋呢.我是CrazyCatJack,大家可以叫我CCJ或者疯猫.我即将成为一名嵌入式Linux的驱动工程师,现在还是一枚大四狗,呼呼~大学期间做了一些项目和比赛,都是基于32 ...
随机推荐
- 爬虫协议robots
前面的话 Robots协议(也称为爬虫协议.机器人协议等)全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页 ...
- WebApi Ajax 跨域请求解决方法(CORS实现)
概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题, 特别 ...
- Linux Command Line(II): Intermediate
Prerequisite: Linux Command Line(I): Beginner ================================ File I/O $ cat > a ...
- 【Spring】浅谈ContextLoaderListener及其上下文与DispatcherServlet的区别
一般在使用SpingMVC开发的项目中,一般都会在web.xml文件中配置ContextLoaderListener监听器,如下: <listener> <listener-clas ...
- Selenium对于对话框alert,confirm,prompt的处理
html 源码: <html> <head> <title>Alert</titl ...
- easyui&8Jquery ztree树插件
7Jquery easyui前台UI框架 开发包: 7.1Layout页面布局 将课后资料中后台系统前台页面素材导入项目中 1.导入Jquery,easyui相关js,css文件 <link r ...
- python学习之核心数据类型
python核心数据类型 对象类型 例子 数字 1234,-345 字符串 'spam' 列表 [1,3,'ds'] 元组 (1,'spam',6) 字典 {'name':'lili','age':1 ...
- db2 表关联查询
今天在MapReduce的练习中看到了一个题目: file: CHILD PARENT ---------- ---------- tom lucy tom jack jone lucy jone j ...
- SQL连接操作
一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...
- UML类图及依赖,泛化,关联,聚合,组合,实现
UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...