開發環境: CentOS5
第一天早上(toolchain preparation and compile u-boot):
1.下載ELDK4.1
   我下載的版本是 arm-linux-x86-uclibc. 底下是它的連結.
       ftp://ftp.denx.de/pub/eldk/4.1/arm-linux-x86-uclibc/iso/arm-2007-01-22-uclibc-src.iso

2. Install ELDK4.1
     用指令“install –d directory [cpu family]”安裝ELDK. 舉例來說, 輸入 “install –d /usr/local/eldk arm”
3. 下載 並解壓縮U-BOOT 1.3.2
ftp://ftp.denx.de/pub/u-boot/u-boot-1.3.2.tar.bz2
    輸入指令”tar jxvf u-boot-1.3.2.tar.bz2″
4. 編譯 U-BOOT 1.3.2
    進入 u-boot-1.3.2 的目錄, 輸入 “make smdk2410_config” 然候再輸入 “make all”
    I如果成功的話, 你會看到u-boot(elf image) 和u-boot.bin(binary  image)在u-boot的資料夾下

第一天中午(Let U-BOOT 1.3.2 start in ram)
讓u-boot在記憶體執行
修改 u-boot/include/configs/smdk2410.h
加入以下兩行

  #define CONFIG_SKIP_LOWLEVEL_INIT
  #define CONFIG_SKIP_RELOCATE_UBOOT
  修改 /u-boot/board/smdk2410/u-boot.lds
SECTIONS
   {
        . = 0x00000000;

 變成如下(修改執行位址)

SECTIONS
   {
        . = 0x33F80000;

3.用arm-elf-insight連結ICE的gdb server
   我用的是JLink(http://www.segger.de/).

4. 讓u-boot在ram中執行
   輸入“arm-elf-insight u-boot”, 你可以看到u-boot source出現了

  下載u-boot image至 0x33f80000

修改 PC(program counter) to 0x33f80000

 你可以單步執行或continue

如果選擇”continue”, 你會看到u-boot畫面已經出現在serial上了

 第二天早上(Let U-BOOT 1.3.2 start from NAND)
1. 加入NAND 開機碼 at /uboot/cpu/start.s
  底下是一個範例,請參考

/*
 *  armboot - Startup Code for ARM920 CPU-core
 *
 *  Copyright (c) 2001    Marius Gr鐷er <mag@sysgo.de>
 *  Copyright (c) 2002    Alex Zke <azu@sysgo.de>
 *  Copyright (c) 2002    Gary Jennejohn <gj@denx.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
 
 
#include <config.h>
#include <version.h>
#include <status_led.h>
 
/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */
 
/*.equ BOOTFromNAND , 0 */ /*0 means you boot from ice*/
.equ BWSCON       ,   0x48000000     /*Bus width & wait status*/
/*=================
 NAND flash
=================*/
.equ NFCONF      ,    0x4e000000     /*NAND Flash configuration*/
.equ NFCMD       ,    0x4e000004     /*NADD Flash command*/
.equ NFADDR      ,    0x4e000008     /*NAND Flash address*/
.equ NFDATA      ,    0x4e00000c     /*NAND Flash data*/
.equ NFSTAT      ,    0x4e000010     /*NAND Flash operation status*/
.equ NFECC       ,    0x4e000014     /*NAND Flash ECC*/
.globl _start
_start:    b       start_code
    ldr    pc, _undefined_instruction
    ldr    pc, _software_interrupt
    ldr    pc, _prefetch_abort
    ldr    pc, _data_abort
    ldr    pc, _not_used
    ldr    pc, _irq
    ldr    pc, _fiq
 
_undefined_instruction:    .word undefined_instruction
_software_interrupt:    .word software_interrupt
_prefetch_abort:    .word prefetch_abort
_data_abort:        .word data_abort
_not_used:        .word not_used
_irq:            .word irq
_fiq:            .word fiq
 
    .balignl 16,0xdeadbeef
 
 
/*
 *************************************************************************
 *
 * Startup Code (called from the ARM reset exception vector)
 *
 * do important init only if we don't start from memory!
 * relocate armboot to ram
 * setup stack
 * jump to second stage
 *
 *************************************************************************
 */
 
_TEXT_BASE:
    .word    TEXT_BASE
 
.globl _armboot_start
_armboot_start:
    .word _start
 
/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start
_bss_start:
    .word __bss_start
 
.globl _bss_end
_bss_end:
    .word _end
 
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
    .word    0x0badc0de
 
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
    .word 0x0badc0de
#endif
 
 
/*
 * the actual start code
 */
 
start_code:
    /*
     * set the cpu to SVC32 mode
     */
    mrs    r0,cpsr
    bic    r0,r0,#0x1f
    orr    r0,r0,#0xd3
    msr    cpsr,r0
 
    bl coloured_LED_init
    bl red_LED_on
 
#if    defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF)
    /*
     * relocate exception table
     */
    ldr    r0, =_start
    ldr    r1, =0x0
    mov    r2, #16
copyex:
    subs    r2, r2, #1
    ldr    r3, [r0], #4
    str    r3, [r1], #4
    bne    copyex
#endif
 
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
    /* turn off the watchdog */
 
# if defined(CONFIG_S3C2400)
#  define pWTCON        0x15300000
#  define INTMSK        0x14400008    /* Interupt-Controller base addresses */
#  define CLKDIVN    0x14800014    /* clock divisor register */
#else
#  define pWTCON        0x53000000
#  define INTMSK        0x4A000008    /* Interupt-Controller base addresses */
#  define INTSUBMSK    0x4A00001C
#  define CLKDIVN    0x4C000014    /* clock divisor register */
# endif
 
    ldr     r0, =pWTCON
    mov     r1, #0x0
    str     r1, [r0]
 
    /*
     * mask all IRQs by setting all bits in the INTMR - default
     */
    mov    r1, #0xffffffff
    ldr    r0, =INTMSK
    str    r1, [r0]
# if defined(CONFIG_S3C2410)
    ldr    r1, =0x3ff
    ldr    r0, =INTSUBMSK
    str    r1, [r0]
# endif
 
    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr    r0, =CLKDIVN
    mov    r1, #3
    str    r1, [r0]
#endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */
 
    /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit
#endif
 
#ifdef    CONFIG_AT91RM9200
 
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:                /* relocate U-Boot to RAM        */
    adr    r0, _start        /* r0 <- current position of code   */
    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
    cmp     r0, r1                  /* don't reloc during debug         */
    beq     stack_setup
 
    ldr    r2, _armboot_start
    ldr    r3, _bss_start
    sub    r2, r3, r2        /* r2 <- size of armboot            */
    add    r2, r0, r2        /* r2 <- source end address         */
 
copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop
#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */
#endif
    /* Set up the stack                            */
stack_setup:
    ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */
    sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area                      */
    sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
#ifdef CONFIG_USE_IRQ
    sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub    sp, r0, #12        /* leave 3 words for abort-stack    */
 
clear_bss:
    ldr    r0, _bss_start        /* find start of bss segment        */
    ldr    r1, _bss_end        /* stop here                        */
    mov     r2, #0x00000000        /* clear                            */
 
clbss_l:str    r2, [r0]        /* clear loop...                    */
    add    r0, r0, #4
    cmp    r0, r1
    ble    clbss_l
#ifdef NANDBOOT
/*For Nand Boot*/
    ldr    r0, =BWSCON
    ldr    r0, [r0]
    ands    r0, r0, #6        /*OM[1:0] != 0, NOR FLash boot*/
    bne    GoMain        /*do not read nand flash    */
    
    mov    r5, #NFCONF
    ldr    r0,    =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
    str    r0,    [r5]
    bl    ReadNandID
    mov    r6, #0
    ldr    r0, =0xec73
    cmp    r5,    r0
    beq    1f
    ldr    r0, =0xec75
    cmp    r5, r0
    beq    1f
    mov    r6, #1
1:   
    bl    ReadNandStatus   
    
    mov    r8, #0
    /*ldr    r9, =__main    */
    /*ldr r9,=0x33A00000*/
    ldr r9,=TEXT_BASE
2:   
    ands    r0, r8, #0x1f
    bne        3f
    mov        r0, r8
    bl        CheckBadBlk
    cmp        r0, #0
    addne    r8, r8, #32
    bne        4f
3:   
    mov    r0, r8
    mov    r1, r9
    bl    ReadNandPage
    add    r9, r9, #512
    add    r8, r8, #1
4:   
    cmp    r8, #400            /*524K*/
    bcc    2b
    
    mov    r5, #NFCONF            /*DsNandFlash*/
    ldr    r0, [r5]
    and    r0, r0, #~0x8000
    str    r0, [r5]
    ldr    pc, =GoMain
ReadNandID:
    mov         r7,#NFCONF   
    ldr      r0,[r7,#0]        /*NFChipEn();*/
    bic      r0,r0,#0x800
    str      r0,[r7,#0]   
    mov      r0,#0x90        /*WrNFCmd(RdIDCMD);*/
    strb     r0,[r7,#4]   
    mov      r4,#0            /*WrNFAddr(0);*/
    strb     r4,[r7,#8]   
1:                            /*while(NFIsBusy());*/
    ldr      r0,[r7,#0x10]   
    tst      r0,#1
    beq      1b
    ldrb     r0,[r7,#0xc]    /*id  = RdNFDat()<<8;*/
    mov      r0,r0,lsl #8   
    ldrb     r1,[r7,#0xc]    /*id |= RdNFDat();*/
    orr      r5,r1,r0   
    ldr      r0,[r7,#0]        /*NFChipDs();*/
    orr      r0,r0,#0x800
    str      r0,[r7,#0]   
    mov         pc,lr   
    
ReadNandStatus:
    mov         r7,#NFCONF
    ldr      r0,[r7,#0]        /*NFChipEn();*/
    bic      r0,r0,#0x800
    str      r0,[r7,#0]
    mov      r0,#0x70        /*WrNFCmd(QUERYCMD);*/
    strb     r0,[r7,#4]   
    ldrb     r1,[r7,#0xc]    /*r1 = RdNFDat();*/
    ldr      r0,[r7,#0]        /*NFChipDs();*/
    orr      r0,r0,#0x800
    str      r0,[r7,#0]
    mov         pc,lr
 
WaitNandBusy:
    mov      r0,#0x70        /*WrNFCmd(QUERYCMD);*/
    mov      r1,#NFCONF
    strb     r0,[r1,#4]
1:                            /*while(!(RdNFDat()&0x40));    */
    ldrb     r0,[r1,#0xc]
    tst      r0,#0x40
    beq           1b
    mov      r0,#0            /*WrNFCmd(READCMD0);*/
    strb     r0,[r1,#4]
    mov      pc,lr
 
CheckBadBlk:
    mov        r7, lr
    mov        r5, #NFCONF
    
    bic        r0, r0, #0x1f    /*addr &= ~0x1f;*/
    ldr      r1,[r5,#0]        /*NFChipEn()*/
    bic      r1,r1,#0x800
    str      r1,[r5,#0]   
 
    mov      r1,#0x50        /*WrNFCmd(READCMD2)*/
    strb     r1,[r5,#4]   
    mov         r1, #5
    strb     r1,[r5,#8]        /*WrNFAddr(5)*/
    strb     r0,[r5,#8]        /*WrNFAddr(addr)*/
    mov      r1,r0,lsr #8    /*WrNFAddr(addr>>8)*/
    strb     r1,[r5,#8]   
    cmp      r6,#0            /*if(NandAddr)        */
    movne    r0,r0,lsr #16    /*WrNFAddr(addr>>16)*/
    strneb   r0,[r5,#8]
    
    bl        WaitNandBusy    /*WaitNFBusy()*/
 
    ldrb    r0, [r5,#0xc]    /*RdNFDat()*/
    sub        r0, r0, #0xff
    
    mov      r1,#0            /*WrNFCmd(READCMD0)*/
    strb     r1,[r5,#4]   
    
    ldr      r1,[r5,#0]        /*NFChipDs()*/
    orr      r1,r1,#0x800
    str      r1,[r5,#0]
    
    mov        pc, r7
 
ReadNandPage:
    mov         r7,lr
    mov      r4,r1
    mov      r5,#NFCONF
 
    ldr      r1,[r5,#0]        /*NFChipEn()*/
    bic      r1,r1,#0x800
    str      r1,[r5,#0]   
 
    mov      r1,#0            /*WrNFCmd(READCMD0)*/
    strb     r1,[r5,#4]   
    strb     r1,[r5,#8]        /*WrNFAddr(0)*/
    strb     r0,[r5,#8]        /*WrNFAddr(addr)*/
    mov      r1,r0,lsr #8    /*WrNFAddr(addr>>8)*/
    strb     r1,[r5,#8]   
    cmp      r6,#0            /*if(NandAddr)        */
    movne    r0,r0,lsr #16    /*WrNFAddr(addr>>16)*/
    strneb   r0,[r5,#8]
    
    ldr      r0,[r5,#0]        /*InitEcc()*/
    orr      r0,r0,#0x1000
    str      r0,[r5,#0]   
    
    bl       WaitNandBusy    /*WaitNFBusy()*/
    
    mov      r0,#0            /*for(i=0; i<512; i++)*/
1:
    ldrb     r1,[r5,#0xc]    /*buf[i] = RdNFDat()*/
    strb     r1,[r4,r0]
    add      r0,r0,#1
    bic      r0,r0,#0x10000
    cmp      r0,#0x200
    bcc      1b
    
    ldr      r0,[r5,#0]        /*NFChipDs()*/
    orr      r0,r0,#0x800
    str      r0,[r5,#0]
        
    mov         pc,r7
#endif
GoMain:
    ldr    pc, _start_armboot
 
_start_armboot:    .word start_armboot
 
 
/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
 
 
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
    /*
     * flush v4 I/D caches
     */
    mov    r0, #0
    mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
    mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
 
    /*
     * disable MMU stuff and caches
     */
    mrc    p15, 0, r0, c1, c0, 0
    bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
    bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
    orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
    orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
    mcr    p15, 0, r0, c1, c0, 0
 
    /*
     * before relocating, we have to setup RAM timing
     * because memory timing is board-dependend, you will
     * find a lowlevel_init.S in your board directory.
     */
    mov    ip, lr
#if    defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF)
 
#else
    bl    lowlevel_init
#endif
    mov    lr, ip
    mov    pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */
 
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE    72
 
#define S_OLD_R0    68
#define S_PSR        64
#define S_PC        60
#define S_LR        56
#define S_SP        52
 
#define S_IP        48
#define S_FP        44
#define S_R10        40
#define S_R9        36
#define S_R8        32
#define S_R7        28
#define S_R6        24
#define S_R5        20
#define S_R4        16
#define S_R3        12
#define S_R2        8
#define S_R1        4
#define S_R0        0
 
#define MODE_SVC 0x13
#define I_BIT     0x80
 
/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */
 
    .macro    bad_save_user_regs
    sub    sp, sp, #S_FRAME_SIZE
    stmia    sp, {r0 - r12}            @ Calling r0-r12
    ldr    r2, _armboot_start
    sub    r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
    sub    r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
    ldmia    r2, {r2 - r3}            @ get pc, cpsr
    add    r0, sp, #S_FRAME_SIZE        @ restore sp_SVC
 
    add    r5, sp, #S_SP
    mov    r1, lr
    stmia    r5, {r0 - r3}            @ save sp_SVC, lr_SVC, pc, cpsr
    mov    r0, sp
    .endm
 
    .macro    irq_save_user_regs
    sub    sp, sp, #S_FRAME_SIZE
    stmia    sp, {r0 - r12}            @ Calling r0-r12
    add     r7, sp, #S_PC
    stmdb   r7, {sp, lr}^                   @ Calling SP, LR
    str     lr, [r7, #0]                    @ Save calling PC
    mrs     r6, spsr
    str     r6, [r7, #4]                    @ Save CPSR
    str     r0, [r7, #8]                    @ Save OLD_R0
    mov    r0, sp
    .endm
 
    .macro    irq_restore_user_regs
    ldmia    sp, {r0 - lr}^            @ Calling r0 - lr
    mov    r0, r0
    ldr    lr, [sp, #S_PC]            @ Get PC
    add    sp, sp, #S_FRAME_SIZE
    subs    pc, lr, #4            @ return & move spsr_svc into cpsr
    .endm
 
    .macro get_bad_stack
    ldr    r13, _armboot_start        @ setup our mode stack
    sub    r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
    sub    r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
 
    str    lr, [r13]            @ save caller lr / spsr
    mrs    lr, spsr
    str     lr, [r13, #4]
 
    mov    r13, #MODE_SVC            @ prepare SVC-Mode
    @ msr    spsr_c, r13
    msr    spsr, r13
    mov    lr, pc
    movs    pc, lr
    .endm
 
    .macro get_irq_stack            @ setup IRQ stack
    ldr    sp, IRQ_STACK_START
    .endm
 
    .macro get_fiq_stack            @ setup FIQ stack
    ldr    sp, FIQ_STACK_START
    .endm
 
/*
 * exception handlers
 */
    .align  5
undefined_instruction:
    get_bad_stack
    bad_save_user_regs
    bl     do_undefined_instruction
 
    .align    5
software_interrupt:
    get_bad_stack
    bad_save_user_regs
    bl     do_software_interrupt
 
    .align    5
prefetch_abort:
    get_bad_stack
    bad_save_user_regs
    bl     do_prefetch_abort
 
    .align    5
data_abort:
    get_bad_stack
    bad_save_user_regs
    bl     do_data_abort
 
    .align    5
not_used:
    get_bad_stack
    bad_save_user_regs
    bl     do_not_used
 
#ifdef CONFIG_USE_IRQ
 
    .align    5
irq:
    get_irq_stack
    irq_save_user_regs
    bl     do_irq
    irq_restore_user_regs
 
    .align    5
fiq:
    get_fiq_stack
    /* someone ought to write a more effiction fiq_save_user_regs */
    irq_save_user_regs
    bl     do_fiq
    irq_restore_user_regs
 
#else
 
    .align    5
irq:
    get_bad_stack
    bad_save_user_regs
    bl     do_irq
 
    .align    5
fiq:
    get_bad_stack
    bad_save_user_regs
    bl     do_fiq
 
#endif

2.    修改u-boot 1.3.2 的設定,讓它自NAND啟動
    修改 u-boot/include/configs/smdk2410.h. 把第一天我們加入的 “#define CONFIG_SKIP_LOWLEVEL_INIT” 註解掉
    修改 /u-boot/board/smdk2410/u-boot.lds

SECTIONS
{
        . = 0x00000000;
最後修改日期: 3 6 月, 2022

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。