Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90911
  • 博文数量: 13
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-28 21:12
文章分类
文章存档

2011年(1)

2008年(12)

我的朋友

分类: LINUX

2008-03-14 22:31:12

1:做嵌入式bootloader开发也有一段时间了,今天终于重构了自己的第一个代码,主要目的用来测试,并验证stage1的启动,为后续开发增加点信息。从开始的毫无头绪,到现在自己写的这个代码。感觉上还是很有成就。
 
硬件环境:

开发板:恒丰锐科 HF2410A +3.5"触摸屏

  1. CPU:S3C2410AL ARM920t
  2. 存储器:
       1. 64M(32M*2) SDRAM(K4S561632H-UC75)
       2. 64M Nand Flash (KF1208)
  3. 一个总线扩展接口。
  4. 2个串口输出
  5. JTAG调试接口
软件环境:

XP+VMware+RH linux 9+Source Insight

 
 
 
stage1:软件架构参考下图
软件大体分为三部分:主代码区、调用子函数代码区、数据区
 
 
/*
 * vivi/arch/s3c2410/head.S:
 *
 * bootloader stage1
 *
 * modify by forl on 2008/3/14
 */


#include "config.h"
#include "linkage.h"
#include "machine.h"

.text
/*
  **********************************************
  *
  *code Area
  *
  **********************************************
  */
  
/*
  ***********************************************
  *
  * Exception vector table
  *
  ***********************************************
  */

.globl _start
_start: b Reset
       b    undefined_instruction
    b    software_interrupt
    b    prefetch_abort
    b    data_abort
    b    not_used
    b    irq
    b    fiq
    
/*
  **************************************************
  *
  *the actual reset code
  *
  **************************************************
  */
Reset:
    /*disable watch dog timer*/
    
    mov    r1, #0x53000000
    mov    r2, #0x0
    str    r2, [r1]
    
    /*disable all interrupts*/
    
    mov    r1, #0x4A000000
    mov    r2, #0xffffffff
    str    r2, [r1, #0x08]
    ldr    r2, =0x7ff
    str    r2, [r1, #0x1C]    

    /* initialise system clocks*/
    mov    r1, #0x4C000000
    mvn    r2, #0xff000000
    str    r2, [r1, #0x00]

    @ 1:2:4
    mov    r1, #0x4C000000
    mov    r2, #0x3
    str    r2, [r1, #0x14]

    mrc    p15, 0, r1, c1, c0, 0        @ read ctrl register
    orr    r1, r1, #0xc0000000        @ Asynchronous
    mcr    p15, 0, r1, c1, c0, 0        @ write ctrl register

    @ now, CPU clock is 200 Mhz
    mov    r1, #0x4C000000
    ldr r2, mpll_200mhz
    str    r2, [r1, #0x04]


        
         /*
         *********************
             *
             *initialise memory
             *
         *********************
         */
       
     bl memsetup
     bl led_memsetup


         /*
         *********************
             *
             * SDRAM test
             *
         *********************
         */

     bl memtest
     bl led_memtest


   
         /*
         *********************
             *
             *initialise uart 0
             *
         *********************
         */
         
     bl init_uart   @独立用c函数完成
 
     bl led_init_uart  
    

         /*
         *********************
             *
             *copy vivi to SDRAM
             *
         *********************
         */
         
     bl copy_myself
     bl led_copy_myself
    

          /*
         *********************
             *
             *jump to ram
             *
         *********************
         */
         
    ldr r1, =on_the_ram
    add    pc, r1, #0
    nop
    nop
1:  b    1b        @ infinite loop

on_the_ram:

    @ get read to call C functions
    ldr    sp, DW_STACK_START    @ setup stack pointer
    mov    fp, #0            @ no previous frame, so fp=0
    mov    a2, #0            @ set argv to NULL
    
    bl led_main
    bl    main            @ call main

    mov    pc, #0x000        @ otherwise, reboot

/*
  ***********************************************************
  *
  * End VIVI head
  *
  ***********************************************************
  */

/*
  ***********************************************************
  *
  * sub program
  *
  ************************************************************
  */

 /* initialise memory*/

     /* initialise SDRAM*/
 
memsetup:

    mov    r1, #0x48000000
    adrl    r2, mem_cfg_val
    add    r3, r1, #52
1:  ldr    r4, [r2], #4
    str    r4, [r1], #4
    cmp    r1, r3
    bne    1b



/*
  ***********************************************************
  *
  * copy_myself: copy vivi to ram
  *
  ************************************************************
  */

copy_myself:
    mov    r10, lr
    
    /*initialise NAND flash*/
    mov    r1, #0x4E000000
    ldr    r2, =0xf830        @ initial value
    str    r2, [r1, #0x00]
    ldr    r2, [r1, #0x00]
    bic    r2, r2, #0x800        @ enable chip
    str    r2, [r1, #0x00]
    mov    r2, #0xff         @ RESET command
    strb    r2, [r1, #0x40]
    mov    r3, #0             @ wait
1:  add    r3, r3, #0x1
    cmp    r3, #0xa
    blt    1b
2:  ldr    r2, [r1, #0x10]    @ wait ready
    tst    r2, #0x1
    beq    2b
    ldr    r2, [r1, #0x00]
    orr    r2, r2, #0x800        @ disable chip
    str    r2, [r1, #0x00]
    
    /*get read to call C functions (for nand_read())*/
    
    ldr sp, DW_STACK_START @ setup stack pointer
    mov fp, #0 @ no previous frame, so fp=0
    
    @ copy vivi to RAM
    ldr    r0, =VIVI_RAM_BASE
    mov r1, #0x0
    mov    r2, #0x20000
    bl    nand_read_ll

    cmp    r0, #0x0
    beq    ok_nand_read

         /*bad nand read*/

bad_nand_read:

bl led_bad_nand_read
1: b  1b    @ infinite loop

     /*ok nand read*/
ok_nand_read:
 
    /*verify 0x000-0x400 and 0x33f0000-0x33f0400*/
    mov    r0, #0
    ldr    r1, =0x33f00000
    mov    r2, #0x400    @ 4 bytes * 1024 = 4K-bytes
go_next:
 
    ldr r3, [r0], #4
    ldr    r4, [r1], #4
    teq    r3, r4
    bne    notmatch
    subs    r2, r2, #4
    beq    done_nand_read    
    bne    go_next
    
notmatch:

 bl led_notmatch
    
1:    b    1b

  /* done nand read to ram*/
done_nand_read:

  mov lr, r10
  mov pc, lr

    
/*
  *******************************************************
  *
  *Simple memory test function
  *
  *******************************************************
  */
memtest:

 mov r10, lr
 /* check the first 1MB of BLOB_START in increments of 4k */
 mov r7, #0x1000
 mov r6, r7, lsl #8 /* 4k << 2^8 = 1MB */
 mov r5, #0x30000000

mem_test_loop:
mov r0, r5
bl testram

 teq r0, #1
 beq badram
 add r5, r5, r7
 subs r6, r6, r7
 bne mem_test_loop
 
 mov    lr, r10
 mov pc, lr


testram:
        ldmia r0, {r1, r2} @ store current value in r1 and r2
        mov r3, #0x55 @ write 0x55 to first word
        mov r4, #0xaa @ 0xaa to second
        stmia r0, {r3, r4}
        ldmia r0, {r3, r4} @ read it back
        teq r3, #0x55 @ do the values match
        teqeq r4, #0xaa
        bne bad @ oops, no
        mov r3, #0xaa @ write 0xaa to first word
        mov r4, #0x55 @ 0x55 to second
        stmia r0, {r3, r4}
        ldmia r0, {r3, r4} @ read it back
        teq r3, #0xaa @ do the values match
        teqeq r4, #0x55
bad: stmia r0, {r1, r2} @ in any case, restore old data
        moveq r0, #0 @ ok - all values matched
        movne r0, #1 @ no ram at this location
        mov pc, lr

badram:
    mov    r6, #2
    b    endless_blink

endless_blink:
  bl wait
    mov    r0, r6
    bl   led_badram
    b    endless_blink

/*memory test end*/


/*
  *************************************************
  *
  *Exception handling functions
  *
  *************************************************
  */

undefined_instruction:
    mov    r12, r14
1:    b    1b        @ infinite loop

software_interrupt:
    mov    r12, r14
1:    b    1b        @ infinite loop

prefetch_abort:
    mov    r12, r14
1:    b    1b        @ infinite loop

data_abort:
    mov    r12, r14
1:    b    1b        @ infinite loop

irq:
    mov    r12, r14
1:    b    1b        @ infinite loop

fiq:
    mov    r12, r14
1:    b    1b        @ infinite loop

not_used:
    mov    r12, r14
1:    b    1b        @ infinite loop






/*
  *************************************************
  *
  *Led test code
  *
  *************************************************
  */
  
  led_memsetup:
  
  /*led test&&&&display GPF4 */
  mov r11,lr
    mov r1, #0x56000000
  add r1, r1, #0x50
    ldr    r2,=0x55aa
    str    r2, [r1, #0x0]
    mov    r2, #0xff
    str    r2, [r1, #0x8]
    mov    r2, #0xef
    str    r2, [r1, #0x4]
    
    bl wait
    mov lr,r11
    mov pc,lr
    
  /*led test end&&&&display GPF4*/

  led_memtest:

      /*led test&&&&display GPF5*/
      
     mov r11,lr
       
     mov r1, #0x56000000
     add r1, r1, #0x50
     ldr    r2,=0x55aa
     str    r2, [r1, #0x0]
     mov    r2, #0xff
     str    r2, [r1, #0x8]
     mov    r2, #0xdf
     str    r2, [r1, #0x4]
     
     bl wait
     mov lr,r11
     mov pc,lr
/*led test end&&&&display GPF5*/
    
    
led_badram:

  /*led test&&&&display GPF4 GPF6 */
    mov r11,lr
    
  mov r1, #0x56000000
  add r1, r1, #0x50
    ldr    r2,=0x55aa
    str    r2, [r1, #0x0]
    mov    r2, #0xff
    str    r2, [r1, #0x8]
    mov    r2, #0xaf
    str    r2, [r1, #0x4]
    
    mov lr,r11
    mov pc,lr
    /*led test end&&&&display GPF4 GPF6 */

led_init_uart:
/*led test&&&&display GPF6*/

   mov r11,lr
   mov r1, #0x56000000
   add r1, r1, #0x50
     ldr    r2,=0x55aa
     str    r2, [r1, #0x0]
     mov    r2, #0xff
     str    r2, [r1, #0x8]
     mov    r2, #0xbf
     str    r2, [r1, #0x4]

     bl wait
     mov lr,r11
     mov pc,lr
 /*led test end&&&&display GPF6*/
    
    
led_copy_myself:
 
    /*led test&&&&&&display GPF7 */
    
     mov r11,lr
    
   mov r1, #0x56000000
   add r1, r1, #0x50
     ldr    r2,=0x55aa
     str    r2, [r1, #0x0]
     mov    r2, #0xff
     str    r2, [r1, #0x8]
     mov    r2, #0x7f
     str    r2, [r1, #0x4]
    
     bl wait
     mov lr,r11
     mov pc,lr
      /*led test end &&&&&&display GPF */

  led_main:

/*led test&&&&display all led*/

   mov r11,lr
   mov r1, #0x56000000
   add r1, r1, #0x50
     ldr    r2,=0x55aa
     str    r2, [r1, #0x0]
     mov    r2, #0xff
     str    r2, [r1, #0x8]
     mov    r2, #0x0f
     str    r2, [r1, #0x4]

     bl wait
     mov lr,r11
     mov pc,lr
 /*led test end&&&&display all led*/
 
      
    
    

 
 led_bad_nand_read:
 
  /*led test&&&&display GPF7 GPF6*/
  mov r11,lr
  mov r1, #0x56000000
  add r1, r1, #0x50
    ldr    r2,=0x55aa
    str    r2, [r1, #0x0]
    mov    r2, #0xff
    str    r2, [r1, #0x8]
    mov    r2, #0x3f
    str    r2, [r1, #0x4]
    
     mov lr,r11
     mov pc,lr
    
 /*led test end&&&&display GPF7 GPF6*/

led_notmatch:
  
     /*led test&&&&display GPF5 GPF4*/
     
    mov r11,lr
    mov r1, #0x56000000
    add r1, r1, #0x50
    ldr    r2,=0x55aa
    str    r2, [r1, #0x0]
    mov    r2, #0xff
    str    r2, [r1, #0x8]
    mov    r2, #0xcf
    str    r2, [r1, #0x4]
    
     mov lr,r11
     mov pc,lr
 /*led test end&&&&display GPF5 GPF4*/





/*
  *************************************************
  *
  *delay
  *
  *************************************************
  */
wait:
    mov    r5, #0x200000
1: subs    r5, r5, #1
    bne    1b
    mov pc,lr



    

/*
  *************************************************
  *
  *Data Area
  *
  *************************************************
  */

/*Memory registers configuration values*/
.align 4
mem_cfg_val:
     .long 0x22111110
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00018005
        .long 0x00018005
        .long 0x008e0459
        .long 0xb2
        .long 0x30
        .long 0x30
/* Processor clock values*/
.align 4

mpll_200mhz:
    .long    vMPLLCON_200
    
.align 2
DW_STACK_START:
    .word    STACK_BASE+STACK_SIZE-4

关于led测试:

在开发板上有四个led灯 D2、D3、D4、D5查看开发板原理图,其与GPIO的GPF[4:7]

一一对应。利用写GPF[4:7]的值来调试查看程序的运行。对于延时程序可以利用S3C2410自带的硬件计时器,亦可软件实现(本人所采用)

调试stage1过程中D2、D3、D4、D5依次顺序点亮,最后全亮,其对应的程序运行点如下:

 D2

 memsetup

 D3

 memtest

 D4

init_uart

 D5

 copy_myself

 D2,D3,D4,D5

 main

上面这个可以自己设置,个性化的东西。

 

调试:

这是个很花时间的过程,一个小小的问题都会导致整个过程从来。而用JTAG烧写程序看程序运行状态的方法实在笨的不行。又占PC资源,又慢。所以开始编译时一定要小心。特别是注意不要转入某个循环不出来(因为这种情况交叉编译是能通过的),这点要注意保存程序指针。

我就陷入过其中,检查不出来,不得不用设置多个led点的方法看其出错地点,然后去修改。
 
开始写程序,没有初始化串口(开始以为在第二阶段初始化),结果bootloader运行正常,没有启动信息输出,着实郁闷了我。
 
调试是个痛快的过程,有耐心的可以试下,以上的程序我已经过验证,pass。^_^
 
后记:
关于bootloader stage1 程序的具体分析,包括硬件如何正确初始化,如何设置正确的寄存器的值,还有一些程序的理解在我的另一篇文章中有过详细而啰嗦的描述。可供耐心的人参考~~网址如下
 
下一步要做的是完成Stage2的结构分析,构建自己的bootloader stage2 然后加强其网络功能。期待ING
 
阅读(1922) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-10-13 10:41:19

mov r2, #0xff @ RESET command strb r2, [r1, #0x40] 上面的错了,应该是strb r2, [r1, #0x04]

chinaunix网友2010-10-09 15:33:39

badram: mov r6, #2 b endless_blink endless_blink: bl wait mov r0, r6 bl led_badram b endless_blink 上面这一段的,mov r6, #2有什么用啊,又后面mov r0, r6 ,望楼主说明一下