uboot 由两阶段代码组成:

•第一阶段主要步骤:

1.将cpu设置为svc模式

2.关闭mmu

3.设置外设端口地址

4.关闭watchdog

5.关闭中断

6.初始化时钟

7.初始化内存DRAM

8.把 nandflash 中的代码搬移到链接地址处

9.初始化堆栈

10.清bss段

11.使用与地址相关的跳转指令,跳转到 c 入口处。

OK6410上的启动代码如下:

@start.S
.text
.global _start
_start:
/*set the cpu to svc32 mode*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0 /*disable_mmu*/
mcr p15,0,r0,c7,c7,0
mrc p15,0,r0,c1,c0,0
bic r0,r0,#0x00000007
mcr p15,0,r0,c1,c0,0
/*peri port setup*/
ldr r0,=0x70000000
orr r0,r0,#0x13
mcr p15,0,r0,c15,c2,4
/*Disable Watchdog
*if you don't disable watchdog,because you don't to feed dog,so the CPU will conti *nue reboot.
*/
ldr r0,=0x7e000000
orr r0,r0,#0x4000
mov r1,#0
str r1,[r0]
/*Disable interrupt*/
mvn r1,#0
ldr r0,=0x71200014
str r1,[r0] ldr r0,=0x71300014
str r1,[r0] /*Init clock*/
#define APLL_LOCK 0x7e00f000
#define MPLL_LOCK 0x7e00f004
#define EPLL_LOCK 0x7e00f008
#define LOCK_TIME 0xffff #define OTHERS 0x7e00f900 #define CLK_DIV0 0x7e00f020 #define CLK_SRC 0x7e00f01c @ set the lock time to max
ldr r0, =LOCK_TIME
ldr r1, =APLL_LOCK
str r0, [r1]
ldr r1, =MPLL_LOCK
str r0, [r1]
ldr r1, =EPLL_LOCK
str r0, [r1] @ set async mode
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, #0xc0
str r1, [r0] loop1:
ldr r0, =OTHERS
ldr r1, [r0]
and r1, #0xf00
cmp r1, #0
bne loop1 @ set the divider #define DIV_VAL ( (0)|(1<<4)|(1<<8)|(1<<9)|(3<<12) )
ldr r0, =CLK_DIV0
ldr r1, =DIV_VAL
str r1, [r0] @ set APLL, MPLL, EPLL
#define SDIV 1
#define PDIV 3
#define MDIV 266
#define PLL_ENABLE ( 1 << 31 )
#define APLL_VAL ( (SDIV<<0)|(PDIV<<8)|(MDIV<<16)|(PLL_ENABLE) )
#define MPLL_VAL APLL_VAL
#define EPLL0_VAL ( (2<<0)|(1<<8)|(32<<16)|PLL_ENABLE)
#define EPLL1_VAL ( 0 ) #define APLL_CON 0x7e00f00c
#define MPLL_CON 0x7e00f010
#define EPLL_CON0 0x7e00f014
#define EPLL_CON1 0x7e00f018 ldr r0, =APLL_CON
ldr r1, =APLL_VAL
str r1, [r0] ldr r0, =MPLL_CON
ldr r1, =MPLL_VAL
str r1, [r0] ldr r0, =EPLL_CON0
ldr r1, =EPLL0_VAL
str r1, [r0] ldr r0, =EPLL_CON1
ldr r1, =EPLL1_VAL
str r1, [r0] @ select the source
ldr r0, =CLK_SRC
mov r1, #7
str r1, [r0] init_mem:
ldr r0,=0x7e00f120
mov r1, #0x8
str r1, [r0] ldr r0, =0x7e001004
mov r1, #0x4
str r1, [r0] ldr r0, =0x7e001010
ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001014
mov r1, #(3 << 1)
str r1, [r0] ldr r0, =0x7e001018
mov r1, #0x1
str r1, [r0] ldr r0, =0x7e00101c
mov r1, #0x2
str r1, [r0] ldr r0, =0x7e001020
ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001024
ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001028
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e00102c
ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001030
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001034
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001038
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e00103c
mov r1, #0x07
str r1, [r0] ldr r0, =0x7e001040
mov r1, #0x02
str r1, [r0] ldr r0, =0x7e001044
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e001048
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0] ldr r0, =0x7e00100c
ldr r1, =0x00010012
str r1, [r0] ldr r0, =0x7e00104c
ldr r1, =0x0b45
str r1, [r0] ldr r0, =0x7e001200
ldr r1, =0x150f8
str r1, [r0] ldr r0, =0x7e001304
mov r1, #0x0
str r1, [r0] ldr r0, =0x7e001008
ldr r1, =0x000c0000
str r1, [r0] ldr r1, =0x00000000
str r1, [r0] ldr r1, =0x00040000
str r1, [r0] ldr r1, =0x000a0000
str r1, [r0] ldr r1, =0x00080032
str r1, [r0] ldr r0, =0x7e001004
mov r1, #0x0
str r1, [r0] check_dmc1_ready: ldr r0, =0x7e001000
ldr r1, [r0]
mov r2, #0x3
and r1, r1, r2
cmp r1, #0x1
bne check_dmc1_ready
nop /*prepare C language environment*/ /*
*copy_to_ram:
* ldr r0,=0x0c000000
* ldr r1,=0x50000000
* add r3,r0,#1024*4
*copy_loop:
* ldr r2,[r0],#4
* str r2,[r1],#4
* cmp r0,r3
* bne copy_loop
*/ init_stack:
ldr sp,=0x54000000 copy_to_ram:
adr r0, _start /* »ñµÃ_startÖ¸ÁǰËùÔڵĵØÖ· : 0*/
ldr r1, =_start /* _startµÄÁ´½ÓµØÖ· 0x51000000 */ ldr r2, =bss_start /* bss¶ÎµÄÆðʼÁ´½ÓµØÖ· */ sub r2, r2, r1 cmp r0,r1
beq clean_bss bl copy2ddr
cmp r0, #0
bne halt
clean_bss:
ldr r0,=bss_start
ldr r1,=bss_end
cmp r0,r1
beq to_ddr
clean_loop:
mov r2,#0
str r2,[r0],#4
cmp r0,r1
bne clean_loop to_ddr:
bl light_led
ldr pc,=main light_led:
ldr r1, =0x7F008820
ldr r0, =0x1111
str r0, [r1] ldr r1, =0x7F008824
mov r0,#0xe
str r0,[r1]
mov pc, lr halt:
b halt
//nand.c

#define MEM_SYS_CFG     (*((volatile unsigned long *)0x7E00F120))
#define NFCONF (*((volatile unsigned long *)0x70200000))
#define NFCONT (*((volatile unsigned long *)0x70200004))
#define NFCMMD (*((volatile unsigned long *)0x70200008))
#define NFADDR (*((volatile unsigned long *)0x7020000C))
#define NFDATA (*((volatile unsigned char *)0x70200010))
#define NFSTAT (*((volatile unsigned long *)0x70200028)) #define NAND_DISABLE_CE() (NFCONT |= (1 << 1))
#define NAND_ENABLE_CE() (NFCONT &= ~(1 << 1))
#define NF_TRANSRnB() do { while(!(NFSTAT & (1 << 0))); } while(0) #define NAND_CMD_RESET 0xff
#define NAND_CMD_READID 0x90
#define NAND_CMD_READ0 0
#define NAND_CMD_READSTART 0x30 void nand_select(void)
{
NFCONT &= ~(1<<1);
} void nand_deselect(void)
{
NFCONT |= (1<<1);
} void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
} void nand_addr(unsigned char addr)
{
NFADDR = addr;
} unsigned char nand_get_data(void)
{
return NFDATA;
} void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0);
} void nand_reset(void)
{
/* Ñ¡ÖÐ */
nand_select(); /* ·¢³ö0xffÃüÁî */
nand_cmd(0xff); /* µÈ´ý¾ÍÐ÷ */
wait_ready(); /* È¡ÏûÑ¡ÖÐ */
nand_deselect();
} void nand_init(void)
{
/* ÈÃxm0csn2ÓÃ×÷nand flash cs0 ƬѡÒý½Å */
MEM_SYS_CFG &= ~(1<<1); /* ÉèÖÃʱ¼ä²ÎÊý:hclk = 7.5ns */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 1
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4)); /* ʹÄÜnand flash controller */
NFCONT |= 1; nand_reset();
} void nand_send_addr(unsigned int addr)
{
#if 0
unsigned int page = addr / 2048;
unsigned int colunm = addr & (2048 - 1); /* ÕâÁ½¸öµØÖ·±íʾ´ÓÒ³ÄÚÄÄÀ↑ʼ */
nand_addr(colunm & 0xff);
nand_addr((colunm >> 8) & 0xff); /* ÏÂÃæÈý¸öµØÖ·±íʾÄÄÒ»Ò³ */
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#else
nand_addr(addr & 0xff); /* a0~a7 */
nand_addr((addr >> 8) & 0x7); /* ³ÌÐòµÄ½Ç¶È: a8~a10 */ nand_addr((addr >> 11) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a11~a18 */
nand_addr((addr >> 19) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a19~a26 */
nand_addr((addr >> 27) & 0xff); /* ³ÌÐòµÄ½Ç¶È: a27 ~ */ #endif
} int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i, count = 0;
unsigned char *dest = (unsigned char *)ddr_start; /* Ñ¡ÖÐоƬ */
nand_select(); while (count < len)
{
/* ·¢³öÃüÁî0x00 */
nand_cmd(0x00); /* ·¢³öµØÖ· */
nand_send_addr(addr); /* ·¢³öÃüÁî0x30 */
nand_cmd(0x30); /* µÈ´ý¾ÍÐ÷ */
wait_ready(); /* ¶ÁÊý¾Ý */
for (i = 0; i < 2048 && count < len; i++)
{
dest[count++] = nand_get_data();
} addr += 2048;
} /* È¡ÏûƬѡ */
nand_deselect();
return 0;
} static int nandll_read_page (unsigned char *buf, unsigned long addr, int large_block)
{
int i;
int page_size = 512; if (large_block==2)
page_size = 4096; NAND_ENABLE_CE(); // Ñ¡ÖÐnand NFCMMD = NAND_CMD_READ0; /* Write Address */
NFADDR = 0; if (large_block)
NFADDR = 0; NFADDR = (addr) & 0xff;
NFADDR = (addr >> 8) & 0xff;
NFADDR = (addr >> 16) & 0xff; if (large_block)
NFCMMD = NAND_CMD_READSTART; NF_TRANSRnB(); for(i=0; i < page_size; i++) {
*buf++ = NFDATA;
} NAND_DISABLE_CE(); return 0;
} int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned char *dest = (unsigned char *)ddr_start;
int i; /* ³õʼ»¯nand flash controller */
nand_init(); /* ¶Ánand flash */
/* Read pages */
for (i = 0; i < 4; i++, dest+=2048){
nandll_read_page(dest, i, 2);
} /* Read pages */
for (i = 4; i < ((len+4096)>>13); i++, dest+=8192) {
nandll_read_page(dest, i, 2);
} return 0;
}
//main.c

#define rGPMCON        (*(volatile unsigned *)(0x7F008820))
#define rGPMDAT (*(volatile unsigned *)(0x7F008824))
#define rGPMPUD (*(volatile unsigned *)(0x7F008828)) void msDelay(int time)
{
volatile unsigned int i,j;
for (i=0;i<20000;i++)
for(j=0;j<time;j++);
} void GPIO_Init(void)
{
rGPMCON = 0x11111;
rGPMPUD = 0x00;
rGPMDAT = 0x1F;
} void LedTest(void)
{
volatile unsigned int i;
while(1)
{
for(i=0;i<4;i++)
{
rGPMDAT =~(1<<i);
msDelay(10);
}
}
}
int main()
{
GPIO_Init();
LedTest(); return 0;
}

总结如下:

第一阶段启动代码主要完成此阶段所需硬件的初始化。初始化 c 语言运行环境,即初始化堆栈。进入 c 语言,跳到第二阶段。

ok6410下的uboot分析与实现的更多相关文章

  1. 记录Ok6410 sd 启动uboot

    1\参考资料https://github.com/SeanXP/ARM-Tiny6410/tree/master/no-os/sd-no-os/u-boot 2\参考资料https://blog.cs ...

  2. u-boot分析(十)----堆栈设置|代码拷贝|完成BL1阶段

    u-boot分析(十) 上篇博文我们按照210的启动流程,分析到了初始化nand flash,由于接下来的关闭ABB比较简单所以跳过,所以我们今天按照u-boot的启动流程继续进行分析. 今天我们会用 ...

  3. u-boot分析(九)----nand flash初始化|nand flash读写分析

    u-boot分析(九) 上篇博文我们按照210的启动流程,分析到了初始化串口,由于接下来的取消存储保护不是很重要,所以我们今天按照u-boot的启动流程对nand flash初始化进行分析. 今天我们 ...

  4. u-boot分析(八)----串口初始化

    u-boot分析(八) 上篇博文我们按照210的启动流程,分析到了内存初始化,今天我们继续按照u-boot的启动流程对串口的初始化进行分析. 今天我们会用到的文档: 1.        2440芯片手 ...

  5. u-boot分析(六)----时钟初始化

    u-boot分析(六) 上篇博文我们按照210的启动流程,分析到了关闭看门狗,今天我们继续按照u-boot的启动流程进行分析,今天我们会主要分析时钟的初始化. 今天我们会用到的文档: 1.       ...

  6. u-boot分析(五)----I/D cache失效|关闭MMU和cache|关闭看门狗

    u-boot分析(五) 上篇博文我们按照210的启动流程,对u-boot启动中的设置异常向量表,设置SVC模式进行了分析,今天我们继续按照u-boot的启动流程对以下内容进行分析. 今天我们会用到的文 ...

  7. u-boot分析(四)---设置异常向量表|设置SVC模式

    u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblo ...

  8. u-boot分析(二)----工作流程分析

    u-boot分析(二) 由于这两天家里有点事,所以耽误了点时间,没有按时更新,今天我首先要跟大家说说我对于u-boot分析的整体的思路,然后呢我以后的博客会按照这个内容更新,希望大家关注. 言归正传, ...

  9. Apache Spark源码走读之15 -- Standalone部署模式下的容错性分析

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就standalone部署方式下的容错性问题做比较细致的分析,主要回答standalone部署方式下的包含哪些主要节点,当某一类节点出现问题时,系统是如 ...

随机推荐

  1. android 开发 实现RecyclerView的列表单选功能

    实现思维: 1.首先在一行的xml布局中添加一个选中效果的icon图片,未选中的情况下INVISIBLE或者GONE 都可以,推荐使用INVISIBLE它会占用布局位置但是不显示,这样可以避免布局中其 ...

  2. <spark> ~/spark/conf/spark-default.conf 配置文件

    因为看到我参考的Hadoop/spark集群搭建的文档中的都没有对 /spark-default.conf 的配置 合理地对 /spark-default.conf  进行配置,能够提高执行效率 -- ...

  3. code signing is required for product type 'Application' in SDK 'iOS 8.1' 错误分析以及解决方案

    在真机测试的时候往往会突然出现这样一个错误,code signing is required for product type 'Application' in SDK 'iOS 7.0'  ,就是说 ...

  4. kvm云主机使用宿主机usb设备

    有些时候KVM客户机还是要使用USB设备,比如USB密钥等 KVM命令行参数 -usb 打开usb驱动程序,启动客户机usb支持-usbdevice devname 为客户机增加usb设备,devna ...

  5. wgrib读grib数据

    该文章来自博客:http://windforestwing.blog.163.c ... 412007103084743804/如有错误 ,大家及时指出啊!ps:meteoinfo可以直接处理grib ...

  6. 《算法》第四章部分程序 part 9

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...

  7. zookeeper(4)--zookeeper分布式锁原理

    目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...

  8. Android自定义View学习笔记(一)

    绘制基础 参考:HenCoder Android 开发进阶: 自定义 View 1-1 绘制基础 Paint详解 参考:HenCoder Android 开发进阶: 自定义 View 1-2 Pain ...

  9. RxJava学习(一)——简介及其优势

    参考:给 Android 开发者的 RxJava 详解 RxJava是什么 RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynch ...

  10. Python基础1 介绍、基本语法

    ---恢复内容开始--- 本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表 ...