Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1371446
  • 博文数量: 244
  • 博客积分: 10311
  • 博客等级: 上将
  • 技术积分: 3341
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-14 21:50
文章分类

全部博文(244)

文章存档

2013年(6)

2012年(5)

2011年(16)

2010年(11)

2009年(172)

2008年(34)

分类: LINUX

2009-05-15 17:13:52

本文档旨在叙述从原始代码开始到具备基本引导功能可以在相应设备运行的具体步骤,对于背后的原理叙述有限,见谅。如有兴趣,请关注日后的文章连载。
 
    首先,从下载最近的稳定版本,经过几个版本的交叉编译环境的测试,2.95.3,3.3.2两个版本可以编译。
  1. 刚开始默认编译通不过,错误为信息为:
    cc1: error: invalid option `abi=apcs-gnu'
    经过搜索u-boot的mailinglist得知解决方法:
出错的文件是/cpu/arm920t/下的config.mk:

PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)

  2.板子是从//cpu/arm920t/start.S开始执行,因为原来的代码中是从nor flash中启动执行,我们的设备是
SMDK2410,没有nor flash,所以必须拷贝vivi中的相关代码实现从nand flash将他自己拷贝sdram.我们的nand 
flash设备是samsung的k9f1208,所以必须对于s3c2410的有关nand控制的寄存器进行设置:
在start.S中需要在设置nand的代码前面定义如下变量:
#define NAND_CTL_BASE 0x4E000000
/* Offset */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
将start.S中的:
#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 */
改成:
#ifndef CONFIG_S3C2410_NAND_BOOT
#ifdef  CFG_CMD_NAND
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait 
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
#endif
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*/
#else
        mov     r0,  pc
ldr      r1,  =0x30000000
cmp     r0,  r1
bls      nand_copy

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

nand_copy:
       bl      copy_myself
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
基本的执行顺序就是从#else以下开始执行(因为我们要在'设置头文件smdk2410.h'中定义CONFIG_S3C2410_NAND_BOOT这个宏,这都是后话了)然后跳到nand_copy段执行,进入copy_myself
子程序。


/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */
之前加入:
@
@ copy_myself: copy u-boot.bin  to ram
@
copy_myself:
mov r10, lr

@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait 
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]

@ get read to call C functions (for nand_read())
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    */
mov fp, #0 @ no previous frame, so fp=0

@ copy u-boot.bin to RAM
ldr r0, _TEXT_BASE
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2              @ u-boot size
mov r1, #0x0
bl nand_read_ll

tst r0, #0x0
beq ok_nand_read
#ifdef CONFIG_DEBUG_LL
bad_nand_read: 
ldr r0, STR_FAIL
bl PrintWord
1: b 1b @ infinite loop 
#endif

ok_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
bl PrintWord
#endif

@ verify
mov r0, #0
ldr r1, =0x33f80000 //注意这个地方,这里的地址必须和程序在SDRAM中的地址一样才可以,否则                                //会导致程序不能正常运行。
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:
#ifdef CONFIG_DEBUG_LL
sub r0, r0, #4
bl PrintHexWord
ldr r0, STR_FAIL
bl PrintWord
#endif
1: b 1b
done_nand_read:

#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
bl PrintWord
#endif

mov pc, r10

@ clear memory
@ r0: start address
@ r1: length
mem_clear:
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2

clear_loop:
stmia r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop

mov pc, lr
以上都是取自vivi中的。

3.SDRAM中的初始化。
  在拷贝自己之前有一段:
    bl  cpu_init_crit
他跳转到/board/smdk2410/lowlevel_init.s中的lowlevel_init中:

.globl lowlevel_init
lowlevel_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr     r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add     r2, r0, #13*4
的后面加上一下代码:
     mov    r3,  pc
     ldr     r4,  =0xffff0000
     and     r3, r3, r4
     add     r0, r0, r3
     add     r2, r2, r3

目的是获得真正的sdram寄存器地址。
将相关设置改成如下设置,具体sdram芯片是HY57V561620(L)T,细节参看datasheet
/* BANK1CON */
#define B1_Tacs   0x0 /*  0clk */
#define B1_Tcos   0x0 /*  0clk */
#define B1_Tacc   0x7 /* 14clk */
#define B1_Tcoh   0x0 /*  0clk */
#define B1_Tah   0x0 /*  0clk */
#define B1_Tacp   0x0
#define B1_PMC   0x0

#define B2_Tacs   0x0
#define B2_Tcos   0x0
#define B2_Tacc   0x7
#define B2_Tcoh   0x0
#define B2_Tah   0x0
#define B2_Tacp   0x0
#define B2_PMC   0x0

#define B3_Tacs   0x0 /*  0clk */
#define B3_Tcos   0x3 /*  4clk */
#define B3_Tacc   0x7 /* 14clk */
#define B3_Tcoh   0x1 /*  1clk */
#define B3_Tah   0x0 /*  0clk */
#define B3_Tacp   0x3     /*  6clk */
#define B3_PMC   0x0 /* normal */

#define B4_Tacs   0x0 /*  0clk */
#define B4_Tcos   0x0 /*  0clk */
#define B4_Tacc   0x7 /* 14clk */
#define B4_Tcoh   0x0 /*  0clk */
#define B4_Tah   0x0 /*  0clk */
#define B4_Tacp   0x0
#define B4_PMC   0x0 /* normal */

#define B5_Tacs   0x0 /*  0clk */
#define B5_Tcos   0x0 /*  0clk */
#define B5_Tacc   0x7 /* 14clk */
#define B5_Tcoh   0x0 /*  0clk */
#define B5_Tah   0x0 /*  0clk */
#define B5_Tacp   0x0
#define B5_PMC   0x0 /* normal */

#define B6_MT   0x3 /* SDRAM */
#define B6_Trcd     0x2
#define B6_SCAN   0x1 /* 9bit */

#define B7_MT   0x3 /* SDRAM */
#define B7_Trcd   0x2 /* 3clk */
#define B7_SCAN   0x1 /* 9bit */

/* REFRESH parameter */
#define REFEN   0x1 /* Refresh enable */
#define TREFMD   0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp   0x0 /* 2clk */
#define Trc   0x3 /* 7clk */
#define Tchr   0x2 /* 3clk */
#define REFCNT   300 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */

以上步骤做完,基本可以从串口看到U-boot的启动信息了。
阅读(1141) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~