目标:

第一阶段:

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)的更多相关文章

  1. 第2阶段——编写uboot之启动内核和制作Makefile(2)

    目标: 1   添加头文件setup.h和serial.h 2   写main函数   2.1 帮内核设置串口0, (内核启动会打印出启动信息) 2.2把内核读入到SDRAM 2.3设置参数(参考u- ...

  2. 第2阶段——编写uboot之编译测试以及改进(3)

    编译测试: 1.将写好的uboot复制到linux下面 2.make编译,然后将错误的地方修改,生成boot.bin (编译出错的解决方案:http://www.cnblogs.com/lifexy/ ...

  3. 第1阶段——uboot分析之硬件初始化start_armboot函数(5)

    start_armboot()分析:在start.S初始化后跳转到start_armboot实现第2阶段硬件相关的初始化(烧写擦除flash,网卡驱动,usb驱动,串口驱动,从FLASH读内核,启动内 ...

  4. 第1阶段——uboot分析之硬件初始化start.S(4)

    分析uboot第一个执行函数_start(cpu/arm920t/start.S) 打开cpu/arm920t/start.S .globl _start // .globl定义一个全局符号" ...

  5. u-boot中nandflash初始化流程分析(转)

    u-boot中nandflash初始化流程分析(转) 原文地址http://zhuairlunjj.blog.163.com/blog/static/80050945201092011249136/ ...

  6. 硬件初始化,nand flash固化操作,系统启动简单流程

    2015.3.27星期五 晴 链接脚本定义代码的排放顺序 硬件系统初始化:一:arm核初始化:(里面有指令)初始化ARM核的时候需要看arm核的手册指令:1.异常向量(最起码有个复位异常,初始化模式- ...

  7. 15.uboot study 串口初始化

    3. 串口初始化 4. 代码实现 关于串口 对于嵌入式设备的开发,刚开始好多设备都无法使用,由于无法获得程序的运行状态,调试程序需要花费好多时间和精力,因此串口对于嵌入式程序的调试的作用显而易见,当串 ...

  8. 第1阶段——关于u-boot目标文件start.o中.globl 和.balignl理解(3)

    汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为伪操作. .globl _start 作用:声明一个_start全局符号(Symbol), 这个_sta ...

  9. u-boot的配置、编译及链接

    第一次写技术博客,还有些兴奋呢.我是CrazyCatJack,大家可以叫我CCJ或者疯猫.我即将成为一名嵌入式Linux的驱动工程师,现在还是一枚大四狗,呼呼~大学期间做了一些项目和比赛,都是基于32 ...

随机推荐

  1. oracle 修改表空间文件路径方法

     比如说修改 user01.dbf  文件 的路径 1.先登录sqlplus:    C:\Documents and Settings\chezh>sqlplus  system/passwo ...

  2. Dapper入门教程(一)——Dapper介绍

    Dapper是什么? Dpper是一款.Net平台简单(Simple)的对象映射库,并且Dapper拥有着"微型ORM之王"的称号.就速度而言与手写ADO.NET SqlDateR ...

  3. Java虚拟机垃圾回收机制

    在Java虚拟机中,对象和数组的内存都是在堆中分配的,垃圾收集器主要回收的内存就是再堆内存中.如果在Java程序运行过程中,动态创建的对象或者数组没有及时得到回收,持续积累,最终堆内存就会被占满,导致 ...

  4. NYOJ--139--我排第几个(康托展开)

    我排第几个 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一 ...

  5. AsyncTask用法解析-下载文件动态更新进度条

    1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. ...

  6. java网络编程实现两端聊天

    网络编程的三要素: ip地址:唯一标识网络上的每一台计算机 端口号:计算机中应用的标号(代表一个应用程序),0-1024系统使用或者保留端口,有效端口0-65535(short) 通信协议:通信的规则 ...

  7. 邻接表(C++)

    adj_list_network_edge.h // 邻接表网边数据类模板 template <class WeightType> class AdjListNetworkEdge { p ...

  8. angular或者js如何确定选中ul中的哪几个li

    刚来新公司接到新的需求做一个知识库页面 红色的是单选    蓝色的是多选     这些都是需要传递到后台的 开始不知道如何解决  下班后在家想到一个很巧妙的办法  不多说上代码 箭头所指就是在li里写 ...

  9. ubuntu 15.10 安装jdk

    转http://www.bkjia.com/xtzh/881605.html 第一步,下载Linux版JDK 可以通过访问Oracle官网下载,或者直接通过命令行下载. lxh@ubuntu:~$ w ...

  10. python2 接口测试一般方法.

    接口测试方法: 1. import requests 2. 创建一个url变量,并经访问的地址赋值给它.(包括端口后面的 接口的部分) 例如: url = "http://124.193.9 ...