Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355061
  • 博文数量: 90
  • 博客积分: 2017
  • 博客等级: 大尉
  • 技术积分: 615
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-19 08:10
文章分类

全部博文(90)

文章存档

2012年(4)

2011年(74)

2010年(11)

2009年(1)

分类: 嵌入式

2011-05-20 16:33:21

自己写的嵌入式bootloader stage1,用LED完成测试(基于vivi)发布时间:2008-01-02 06:31:00  来源: ChinaUnix博客    作者: ChinaUnix博客    点击:291
1:做嵌入式bootloader开发也有一段时间了,今天终于重构了自己的第一个代码,主要目的用来测试,并验证stage1的启动,为后续开发增加点信息。从开始的毫无头绪,到现在自己写的这个代码。感觉上还是很有成就。 

硬件环境:
开发板:恒丰锐科 HF2410A +3.5"触摸屏
  • CPU:S3C2410AL ARMArray20t 
  • 存储器:
      1. 64M(32M*2) SDRAM(K4S561632H-UC75)
      2. 64M Nand Flash (KF1208) 
  • 一个总线扩展接口。 
  • 2个串口输出 
  • JTAG调试接口
    软件环境:
    XP+VMware+RH linux Array+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 
    关于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 程序的具体分析,包括硬件如何正确初始化,如何设置正确的寄存器的值,还有一些程序的理解在我的另一篇文章中有过详细而?嗦的描述。可供耐心的人参考~~网址如下
    http://blog.chinaunix.net/u1/58203/showart_48Array453.html

    下一步要做的是完成Stage2的结构分析,构建自己的bootloader stage2 然后加强其网络功能。期待ING
  • 阅读(1566) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~