Chinaunix首页 | 论坛 | 博客
  • 博客访问: 195316
  • 博文数量: 67
  • 博客积分: 3415
  • 博客等级: 中校
  • 技术积分: 860
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-27 17:05
文章分类

全部博文(67)

文章存档

2010年(64)

2009年(3)

我的朋友

分类: LINUX

2010-06-10 18:58:48

之前一直为是否自己写一个启动代码而犹豫不决。现在下决心写了,努力了三天终于将这个代码写出来了,写的过程中学到了不少ARM的汇编,硬件知识,看来还是写启动代码对学习ARM也是很有帮助的。
很感谢大大luzhengmao 对我RO,RW,ZI理解的指点,谢谢了。

使用方法:
由于我手头上没有下载NAND的工具,我是用板上带的启动代码super vivi下到vivi分区运行的,如果有NAND下载工具的朋友就更好办了,将起始地址设为0,下到NAND就行了。由于启动代码中会进行sdram的清0,nand的复制,启动过程大概要等5,6秒(不要以为死机了~~~)。

待一会儿附上程序的讲解。。。






    GET 2440addr.inc
    GET memery.inc
    GET option.inc


BLOCK_STA EQU 0   ;//起始BLOCK
BLOCK_END EQU 13  ;//结束BLOCK
SDRAM_ADDR EQU 0x30000000 ;//SDRAM起始地址

;//*************R0,RW,ZI*******************//

    IMPORT  |Image$$ALL_RO$$Base|
IMPORT  |Image$$ALL_RO$$Limit|
IMPORT  |Image$$ALL_RW$$Base|
IMPORT  |Image$$ALL_RW$$Limit|
IMPORT  |Image$$ALL_ZI$$Base|
IMPORT  |Image$$ALL_ZI$$Limit|


;//引入异常处理函数//
IMPORT  UNDEF
IMPORT  SWI
IMPORT  PABORT
IMPORT  DABORT
IMPORT  IRQ_DEPATE
IMPORT  FIQ

;//引入主函数Main()//
    IMPORT Main

AREA Init,code,readonly

ENTRY_POINT
ENTRY
    b RESET
    b UNDEF
    b SWI
    b PABORT
    b DABORT
    b .
    b IRQ_DEPATE
    b FIQ

    
RESET
;//   关闭看门狗   //
    ldr r0,=WTCON
    ldr r1,=0x0
    str r1,[r0]

;//   关闭中断    //
    ldr r0,=INTMSK
    ldr r1,=0xffffffff
    str r1,[r0]
    
    ldr r0,=INTSUBMSK
    ldr r1,=0x3ff
    str r1,[r0]
    
;//    设置LOCK TIME  //
ldr r0,=LOCKTIME
ldr r1,=0xffffffff
str r1,[r0]

;//    设置  FCLK:HCLK:PCLK    //
ldr r0,=CLKDIVN
ldr r1,=0x7    ;//设置分频比为1:3:6
str r1,[r0]

;//    设置  UPLL 时钟   //
ldr r0,=UPLLCON
ldr r1,=((56<<12)+(2<<4)+(2<<0))  ;//设置USB时钟为48.00MHZ
str r1,[r0]
nop
nop
nop
nop
nop
nop
nop


;//    设置  MPLL 时钟   //
ldr r0,=MPLLCON
ldr r1,=((68<<12)+(1<<4)+(1<<0))   ;//设置MPLL时钟为304.00MHZ
str r1,[r0]

;//    设置  CAMARA 分频时钟   //
ldr r0,=CAMDIVN
ldr r1,=0x0
str r1,[r0]

;//    设置内存   //

;//  BANK总设置  //
ldr r0,=BWSCON
ldr r1,=SET_BWSCON
str r1,[r0]

;// 设置BANK0时钟 //
ldr r0,=BANKCON0
ldr r1,=SET_BANKCON0
str r1,[r0]

;// 设置BANK1~BANK5时钟 //
ldr r0,=BANKCON1
ldr r3,=BANKCON5
ldr r1,=SET_BANKCON
loop
    cmp r0,r3
    strcc r1,[r0],#4
    bcc loop
    
;//  设置BANK6,BANK7时钟,模式  //
    ldr r0,=BANKCON6
    ldr r3,=BANKCON7
    ldr r1,=SET_BANKCON67
    str r1,[r0]
    str r1,[r3]
    
;//  设置BANK6,BANK7刷新控制  //
    ldr r0,=REFRESH
    ldr r1,=SET_REFRESH
    str r1,[r0]
    
;//  设置BANKSIZE,MRSRB6,MRSRB7 //
    ldr r0,=BANKSIZE
    ldr r1,=MRSRB6
    ldr r2,=MRSRB7
    ldr r3,=SET_BANKSIZE
    ldr r4,=SET_MRSRB67
    str r3,[r0]
    str r4,[r1]
    str r4,[r2]

     
;//  初始化各模式堆栈 //
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack ; UndefStack=0x33FF_5C00

orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack ; AbortStack=0x33FF_6000

orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack ; IRQStack=0x33FF_7000

orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack ; FIQStack=0x33FF_8000

bic r0,r0,#MODEMASK|NOINT;//允许FIQ,IRQ中断
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack ; SVCStack=0x33FF_5800 //最后设置SVC模式


;//清零SDRAM
mov r0,#0
ldr r8,=0x30000000
ldr r9,=0x34000000
    
CLR_SDRAM
    cmp r8,r9
    
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4
    strcc r0,[r8],#4

    bcc CLR_SDRAM




;//  初始化NAND  //
ldr r8,=NFCONF
ldr r9,=BLOCK_STA
ldr r10,=BLOCK_END
ldr r11,=SDRAM_ADDR


ldr r0,=SET_NFCONF
ldr r1,=SET_NFCONT
str r0,[r8];//设置NFCONF
str r1,[r8,#4];//设置NFCONT

bl READ_ID
ldr r0,=0xec76
cmp r3,r0;//检测NAND ID
beq READ_BLOCK

b . ;//ID不对,停止

;//  读取NAND  //
READ_BLOCK

mov r5,r9,lsl #5;//得到row首地址

mov r6,r10,lsl #5;//得到row末地址

cmp r5,r6
beq ER_MOVE
b READ_PAGE


READ_ID
ldr r0,[r8,#4]
bic r0,r0,#2
str r0,[r8,#4];//使能NAND

ldr r0,=CMD_READ_ID
strb r0,[r8,#8];//写命令
mov r0,#0
strb r0,[r8,#12];//写地址
mov r0,#40
    
    nop
    nop
    nop
    
ldrb r1,[r8,#16]
ldrb r2,[r8,#16];//获得ID

mov r3,r1,lsl #8
orr r3,r3,r2;//Maker code. Device code.

ldr r0,[r8,#4]
orr r0,r0,#2
str r0,[r8,#4];//禁止NAND

mov pc,lr

NAND_BUSY

WAIT
    ldr r0,[r8,#32];//读NFSTAT
    ands r0,r0,#1;//读状态
    beq WAIT
    
    mov pc,lr


READ_PAGE
    mov r7,#512

ldr r0,[r8,#4]
bic r0,r0,#2
str r0,[r8,#4];//使能NAND

ldr r0,=CMD_READ0
strb r0,[r8,#8];//写命令
mov r0,#0
strb r0,[r8,#12];//写cloumn地址
mov r0,r5
strb r0,[r8,#12];//写row地址
mov r0,r5,lsr #8
strb r0,[r8,#12];//写row地址
mov r0,r5,lsr #16
strb r0,[r8,#12];//写row地址

    bl NAND_BUSY;//读状态

READ_LOOP

    ldr r0,[r8,#16];//读取一个字
    ldr r1,[r8,#16];//读取一个字
    ldr r2,[r8,#16];//读取一个字
    ldr r3,[r8,#16];//读取一个字

    stmia r11!,{r0-r3};//转移四个字到SDRAM
            
    subs r7,r7,#16
    bne READ_LOOP;//读完512字节?
    
    ldr r0,[r8,#4]
orr r0,r0,#2
str r0,[r8,#4];//禁止NAND

    add r5,r5,#1;//row地址加1
    cmp r5,r6
    beq ER_MOVE
    b READ_PAGE 



ER_MOVE

    ldr r3,=  |Image$$ALL_RO$$Base|  
  ldr r4,=  |Image$$ALL_RO$$Limit|
ldr r5,=  |Image$$ALL_RW$$Base|
ldr r6,=  |Image$$ALL_RW$$Limit|
ldr r7,=  |Image$$ALL_ZI$$Base|
ldr r8,=  |Image$$ALL_ZI$$Limit|
ldr r9,=   ENTRY_POINT

mov r0,#0
ALL_ZI_CLR  ;//清零ZI段
cmp r7,r8
strcc r0,[r7],#4
bcc ALL_ZI_CLR


;//  跳到主函数Main()  // 
 
bl Main

    
LTORG

END
阅读(1416) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~