第0步、建立自己的开发板配置文件。
1、打开u-boot主上目录下的Makefile , 找到smdk2410_config, 在其下,加入如下语句
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
/********************************** start ***************************/
Fs2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t fs2410 NULL s3c24x0
/********************************** end ***************************/
各项的意思如下:
arm: CPU的架构(ARCH)
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录
fs2410: 开发板的型号(BOARD),对应于board/fs2410子目录
NULL:开发者/或经销商(vender),我这里选空
S3c24x0:片上系统(SOC)
2、修改CROSS_COMPILE为自己的arm gcc编译器:
#Export PATH=/usr/local/arm/3.4.5/arm-linux/bin:$PATH
3、在board子目录下建立自己的开发板fs2410目录,然后,将smdk2410目录下的文件拷入此目录中,然后,将fs2410目录下的smdk2410.c改为fs2410.c,同时还得修改board/fs2410/Makefile文件。
……
/********************************** start ***************************/
COBJS := fs2410.o flash.o
/********************************** end ***************************/
……
4、在include/configs/下建立fs2410.h配置头文件
将smdk2410的相应头文件复制一份在相同目录下,并改名为fs2410.h
5、测试编译能否成功
(1)配置
[andy@localhost u-boot-2008.10]$ make fs2410_config
Configuring for fs2410 board...
(2)测试编译
[andy@localhost u-boot-2008.10]$ make
测试通过,则说明开发板配置平台搭建没问题,可以进行下一步工作。
第1步、修改相关文件,使u-boot能从nand中启动
1、修改cpu/arm920t/start.S
#include <config.h>
#include <version.h>
/********************************** start ***************************/
#ifdef CONFIG_AT91RM9200DK
#include <status_led.h> /*这是针对AT91RM9200DK开发板的,我们注释掉。*/
#endif
/********************************** end ***************************/
…………
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
/********************************** start ***************************/
#ifdef CONFIG_AT91RM9200DK
bl coloured_LED_init /*这是针对AT91RM9200DK开发板的。*/
bl red_LED_on
#endif
/********************************** end ***************************/
(1)修改中断禁止部分
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
/********************************** start ***************************/
ldr r1, =0x7ff //根据2410芯片手册,INTSUBMSK有11位可用
/********************************** end ***************************/
//应该为0x7ff,可U-Boot一直为0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
(2)修改时钟设置(可以不修改,因为后面的board_init函数也会设置时钟)
# 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
/********************************** start ***************************/
# define CLK_CTL_BASE 0x4C000000
# define MDIV_200 (0xa1 << 12)
# define PSDIV_200 0x31
#ifdef CONFIG_S3C2410
/********************************** end ***************************/
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/********************************** start ***************************/
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 202.8 MHz */
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_200 /* mpll_200MHz */
add r2, r2, #PSDIV_200
str r2, [r1, #0x04] /* MPLLCON */
#endif
/********************************** end ***************************/
(3)将u-boot从Nor Flash启动改成从NAND Flash启动
/********************************** start ***************************/
#if defined(CONFIG_S3C2410_NAND_BOOT)
@ 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
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq nand2
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
@ 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 U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #UBOOT_LENGTH
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 @ infinite loop
ok_nand_read:
@ verify
mov r0, #0
ldr r1, =TEXT_BASE
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 stack_setup
bne go_next
notmatch:
loop3: b loop3 @ infinite loop
#elif !defined(CONFIG_AT91RM9200) && !defined(CONFIG_SKIP_RELOCATE_UBOOT)
/********************************** end ***************************/
/********************************** start ***************************/
//#ifndef CONFIG_AT91RM9200
//#ifndef CONFIG_SKIP_RELOCATE_UBOOT
/********************************** end ***************************/
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
/********************************** start ***************************/
//#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
//#endif
#endif /* Boot Select */
/********************************** end ***************************/
在“_start_armboot: .word start_armboot”后加入
/********************************** start ***************************/
#if defined(CONFIG_S3C2410_NAND_BOOT)
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
#endif
/********************************** end ***************************/
此步骤中cpu/arm920t/start.S修改完毕。
2、在board/fs2410 目录中添加Nand Flash读函数文件,直接复制vivi中的nand_read.c文件到board/fs2410/目录下,并修改board/fs2410/Makefile:
……
/********************************** start ***************************/
COBJS := fs2410.o nand_read.o flash.o
/********************************** end ***************************/
……
3、修改include/configs/fs2410.h 添加相关宏定义。
NAND_CTL_BASE、oNFCONF……等宏定义在
……
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */
/********************************** start ***************************/
#define CONFIG_FS2410 1 /* on a SAMSUNG FS2410 Board */
/********************************** end ***************************/
……
……
/********************************** start ***************************/
#define CONFIG_S3C2410_NAND_BOOT 1
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x10000
#ifdef CONFIG_S3C2410_NAND_BOOT
#define UBOOT_LENGTH 0x40000 /* U-Boot Size 256K */
#define NAND_CTL_BASE 0x4E000000
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#endif
/********************************** end ***************************/
4、修改board/fs2410/lowlevel_init.S文件
这里参考了FS2410开发板自带S3C2410_BIOS,代码如下:
#include <config.h>
#include <version.h>
/* some parameters for the board */
/*
*
* Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
*
* Copyright (C) 2002 Samsung Electronics SW.LEE <hitchcar@sec.samsung.com>
*
*/
#define BWSCON 0x48000000
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW16)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
/* BANK0CON */
#define B0_Tacs 0x3 /* 0clk */
#define B0_Tcos 0x3 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x3 /* 0clk */
#define B0_Tah 0x3 /* 0clk */
#define B0_Tacp 0x1
#define B0_PMC 0x0 /* normal */
/* BANK1CON */
#define B1_Tacs 0x3 /* 0clk */
#define B1_Tcos 0x3 /* 0clk */
#define B1_Tacc 0x7 /* 14clk */
#define B1_Tcoh 0x3 /* 0clk */
#define B1_Tah 0x3 /* 0clk */
#define B1_Tacp 0x3
#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 0x1 /* 0clk */
#define B4_Tcos 0x1 /* 0clk */
#define B4_Tacc 0x6 /* 14clk */
#define B4_Tcoh 0x1 /* 0clk */
#define B4_Tah 0x1 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
#define B5_Tacs 0x1 /* 0clk */
#define B5_Tcos 0x1 /* 0clk */
#define B5_Tacc 0x6 /* 14clk */
#define B5_Tcoh 0x1 /* 0clk */
#define B5_Tah 0x1 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1
#define B6_SCAN 0x1 /* 9bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 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 1113 /* period="15".6us, HCLK="60Mhz", (2048+1-15.6*60) */
/**************************************/
_TEXT_BASE:
.word TEXT_BASE
.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
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
5、修改 cpu/arm920t/s3c24x0/interrupts.c 使用原来SMDK2410使用的代码也包含进来。
……
#elif defined(CONFIG_SBC2410X) || /
defined(CONFIG_SMDK2410) || /
/*************************** start *************************/
defined(CONFIG_FS2410) || /
/*************************** end *************************/
defined(CONFIG_VCMA9)
tbclk = CFG_HZ;
#else
……
6、第1步骤后记:
理论上来说。现在把编译好的u-boot.bin写入Nand Flash后,应该就可以了。不过,我移植的时候发现,u-boot老是死在 lowlevel_init.S中,经过反复测试,先排除了移植过程中的人为因素,仔细比对后,发现死在lowlevel_init.S的调用过程中。查看System.map发现编译后的,lowlevel_init函数在地址33f8d34c中,即33f8d34c - 33f80000 = 0xd34c。
33f8d34c T lowlevel_init
0xd34c已经超出来,S3C2410/S3C2440的4K steppingstone代码,怪不得要卡死呢?郁闷非常~~~
后来在网上查得。修改一下u-boot主目录下的Makefile文件即可。
/*************************** start *************************/
#__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))
/*************************** end *************************/
再次查看System.map
33f80524 T lowlevel_init
呵呵,4K之内,OK了。可是就是不知道为什么这么改,想想就是奇怪,同样是人,为什么其它兄弟能知道,我就不知道的呢?
第2步骤:Nand Flash 支持
u-boot2008.10中对NAND Flash的支持有新旧两套代码,新代码在drivers/mtd/nand目录下,旧代码在drivers/mtd/nand_legacy目录下。文档doc/README.nand对这两套代码有所说明:使用旧代码需要定义更多的宏,而新代码移植自Linux内核2.6.12,它更加智能,可以自动识别更多型号的NAND Flash。目前之所以还保留旧的代码,是因为两个目标板NETTA、NETTA_ISDN使用JFFS文件系统,它们还依赖于旧代码。当相关功能移植到新代码之后,旧的代码将从U-Boot中去除。
要让U-Boot支持NAND Flash,首先在配置文件include/configs/fs2410.h中,增加CONFIG_CMD_NAND,如下:
/*
* Command line configuration.
*/
#include <config_cmd_default.h>
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
/*************************** start *************************/
#define CONFIG_CMD_NAND
/*************************** end *************************/
……
然后选择使用哪套代码:在配置文件中定义宏CONFIG_NAND_LEGACY则使用旧代码,否则使用新代码。不过好像Legacy已经不能用在S3C2410中了,当定义了CONFIG_NAND_LEGACY时,编译时会出现如下错误:
error: #error "U-Boot legacy NAND support not available for S3C2410"
make[1]: *** [nand.o] 错误 1
所以我们这里使用新代码,即:不定义CONFIG_NAND_LEGACY。
Nand 的初始化顺序为:
lib_arm/board.c 中start_armboot() à drivers/mtd/nand/nand.c中nand_init() à nand_init_chip() àcpu/arm920t/s3c24x0/nand.c中board_nand_init() 以完成Nand Flash的初始化。
drivers/mtd/nand/nand.c中nand_init() à drivers/mtd/nand/nand_base.c中nand_scan() à nand_scan_ident() à nand_set_defaults()
nand_scan_ident() à nand_get_flash_type()
drivers/mtd/nand/nand_base.c中nand_scan() à nand_scan_tail()
nand_scan_ident() :Nand Flash设备扫描。
nand_scan_tail() :这是在nand_scan()中调用,它用于填充所有的初始化函数指针和扫描坏块表是否适当。
移植过程如下:
1、修改include/configs/fs2410.h,增加u-boot对NAND的支持(使用非LEGACY方式):
/*
* Command line configuration.
*/
#include <config_cmd_default.h>
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
/*************************** start *************************/
#define CONFIG_CMD_NAND
/*************************** end *************************/
……
/*************************** start *************************/
/*-----------------------------------------------------------------------
* NAND flash settings
*/
#if defined(CONFIG_CMD_NAND)
#define CFG_MAX_NAND_DEVICE 1 /* 最大nand flash设备数 */
#define SECTORSIZE 512 /* 1页的大小 */
#define ADDR_COLUMN 1 /* Column地址为1个字节 */
#define ADDR_PAGE 3 /* 页块地址为3个字节 */
#define ADDR_COLUMN_PAGE 4 /* 总地址为4字节 */
#define NAND_ChipID_UNKNOWN 0x00 /* 未知芯片的ID号 */
#define NAND_MAX_FLOORS 1 /* nand 最大层数 */
#define NAND_MAX_CHIPS 1 /* nand flash芯片数*/
#define CFG_NAND_BASE 0x4E000000 /* NAND控制器基地址*/
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
#endif /* CONFIG_CMD_NAND */
/*************************** end *************************/
2、在Nand Flash中保存 u-boot 参数
/*
* Command line configuration.
*/
#include <config_cmd_default.h>
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
/*************************** start *************************/
#define CONFIG_CMD_PING /*支持ping*/
#define CONFIG_CMD_NAND
#define CONFIG_CMD_ENV /* 添加saveenv命令的支持 */
……
/*#define CONFIG_ENV_IS_IN_FLASH 1 */
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_OFFSET 0x30000 /* 参数在Nand Flash中的起始位置 */
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
/*************************** end *************************/
3、在fs2410.h设置网络参数
/*************************** start *************************/
#define CONFIG_ETHADDR 08:00:3E:26:0A:5B /** MAC地址设置 */
#define CONFIG_NETMASK 255.255.255.0 /** 子网掩码 */
#define CONFIG_IPADDR 113.88.232.3 /** 默认IP地址 */
#define CONFIG_SERVERIP 113.88.232.1 /** 服务器IP地址 */
/*************************** end *************************/