板子配置如下:
CPU S3C2410AL-20
SDRAM HY57V561620FTP-H
4 Banks * 4M * 16bit
共 32M
NAND FLASH
K9F5608U0D-PCB0
32M*8bit
网卡 DM9000EP
其中 DM9000位于BANK2,SDRAM 位于 BANK6
直接从NAND FLASH启动
配置的时候需要看清楚器件的BANK 和 大小
两个参考的连接:
http://blog.chinaunix.net/u1/34474/showart.php?id=2085154
http://blog.chinaunix.net/u3/105764/showart_2091132.html
按照UBoot 的启动流程,修改代码如下
一、在U-Boot中建立自己的开发板类型,并测试编译
0. 在工作目录下解压 u-boot-2009.08.tar.bz2
1. 进入 UBoot 目录,修改 Makefile
$ gedit Makefile
为 my2410 建立编译项
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
my2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t my2410 samsung s3c24x0
各项的意思如下:
arm: CPU 的架构(ARCH)
arm920t: CPU 的类型(CPU),其对应于 cpu/arm920t 子目录。
my2410: 开发板的型号(BOARD),对应于 board/my/my2410 目录。
samsung: 开发者/或经销商(vender)。
s3c24x0: 片上系统(SOC)。
2. 在代码
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
前面添加代码
CROSS_COMPILE=/opt/crosstool/gcc-4.1.1-glibc-2.3.2/arm-linux/bin/arm-linux-
3. 修改下面
__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
修改为
__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))
4. 在/board 子目录中建立自己的开发板目录
$cd board/samsung
$mkdir my2410
$cp -arvf smdk2410/* my2410/ /*copy*/
将文件smdk2410.c重命名为 my2410.c
$cd my2410
$mv smdk2410.c my2410.c
5. 记得修改自己的开发板 my2410 目录下的 Makefile 文件,不然编译时会出错:
COBJS := my2410.o flash.o
$gedit Makefile
6. 在 include/configs/中建立配置头文件
$cd ../../..
$cp include/configs/smdk2410.h include/configs/my2410.h
7. 软浮点问题解决
若编译出现“……uses hardware FP, whereas u-boot uses software FP”,即软浮点问题
修改文件u-boot-2009.08/cpu/arm920t/config.mk,
(make distclean后,重新编译)
注释掉 -msoft-float
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 /
-msoft-float
改为:
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8
#/
# -msoft-float
8. 测试编译能否成功
$make my2410_config
Configuring for my2410 board...
(如果出现:
$ make my2410_config
Makefile:1927: *** 遗漏分隔符 。 停止。
请在 U-boot 的根目录下的 Makefile 的
@$(MKCONFIG) $(@:_config=) arm arm920t my2410 my)
前加上“Tab”键)
$make
二、 内存配置,搬运代码(copy U-Boot from NAND FLASH to RAM)
1. 修改文件config.mk
gedit board/samsung/my2410/config.mk
TEXT_BASE = 0x33F80000
改为
TEXT_BASE = 0x31F80000
这里说明一下TEXT_BASE的设置,smdk2410的标准配置为SDRAM为64M,所以通常设为0x33f00000,
我的是32M,所以只能设为0x31f00000
2. 修改文件 cpu/arm920t/start.S
注释掉 set the cpu to SVC32 mode 后面的语句
//bl coloured_LED_init
//bl red_LED_on
在代码
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
下面添加代码:
# define CLK_CTL_BASE 0x4C000000
# define MDIV_200 0xa1 << 12
# define PSDIV_200 0x31
在代码
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
下面添加代码:
用于设置时钟频率(202.8MHz)
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0 /*write ctrl register */
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_200
add r2, r2, #PSDIV_200
str r2, [r1, #0x04]
修改:
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
为
# if defined(CONFIG_S3C2410)
ldr r1, =0x7ff
3. 下面进入内存配置阶段
bl cpu_init_crit
修改文件board/my/my2410/lowlevel_init.S
可以参考这个博客
http://blog.csdn.net/Apollo5520/archive/2009/11/09/4792003.aspx
修改代码
#define B1_BWSCON (DW32)
#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)
为
#define B1_BWSCON (DW16)
#define B2_BWSCON (DW32)
#define B3_BWSCON (DW16)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW16)
#define B7_BWSCON (DW16)
这里需要说明一下B2_BWSCON的设置,一般的DM9000都是16条控制总线,所以设为DW16,
但u-boot-2009.08功能强大,打开ping命令后,自动检测网卡的位数,我的检测为32位……
修改刷新律
#define REFCNT 1268 /* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */
修改如下部分
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
修改 word 0x32 为 word 0xb2
修改如下部分
#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 B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x0 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x0 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x0 /* 6clk */
#define B3_PMC 0x0 /* normal */
4. 进行代码搬运工作
如下注释掉以前的搬运代码
#if 0
#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
紧接着添加如下代码:
/*copy U-Boot to RAM*/
#define LENGTH_UBOOT 0x40000
#define NAND_CTL_BASE 0x4E000000
#ifdef CONFIG_S3C2410
/* Offset */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFSTAT 0x10
@ 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, #LENGTH_UBOOT
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
#endif
在代码
_start_armboot: .word start_armboot
下面添加:
#define STACK_BASE 0x31f00000
#define STACK_SIZE 0x8000
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
STACK_BASE的设置,与上面TEXT_BASE的设置原因相同
5. 在文件my2410.h的最后添加
$ gedit include/configs/my2410.h
/* nand boot */
#define CONFIG_S3C2410 1
修改常量
#define CONFIG_SYS_MEMTEST_END 0x31F00000 /* 31 MB in DRAM */
#define CONFIG_SYS_LOAD_ADDR 0x30008000 /* default load address */
#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */
6. 在 board/my/my2410 中加入 nand Flash 读函数,建立 nand_read.c,供 start.S 调用,
代码如下:
#include <config.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#if defined(CONFIG_S3C2410)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define BUSY 1
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
inline void wait_idle(void) {
int i;
while(!(NFSTAT & BUSY))
for(i=0; i<10; i++);
}
/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /* invalid alignment */
}
/* chip Enable */
NFCONF &= ~0x800;
for(i=0; i<10; i++);
for(i=start_addr; i < (start_addr + size); i += NAND_SECTOR_SIZE) {
/* READ0 */
NFCMD = 0;
/* Write Address */
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++) {
*buf = (NFDATA & 0xff);
buf++;
}
}
/* chip Disable */
NFCONF |= 0x800; /* chip disable */
return 0;
}
#endif
7. 修改文件 Makefile,在目录/u-boot-1.2.0/board/my/my2410
COBJS := my2410.o flash.o nand_read.o
8. 进入C函数,修改函数 board_init() board/my/my2410/my2410.c
修改下面的配置
gpio->GPFCON = 0x000051AA;
gpio->GPFUP = 0x000000EF;
gpio->GPGCON = 0xFD95FFBA;
gpio->GPGUP = 0x0000EFFF;
gpio->GPHCON = 0x0016FAAA;
在上面配置下添加代码:
gpio->EXTINT0=0x22222222;
gpio->EXTINT1=0x22222222;
gpio->EXTINT2=0x22222222;
三、 去掉Nor Flash 部分
1. 修改配置文件 include/configs/my2410.h
注释 CONFIG_AMD_LV400
#if 0
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif
去掉:
//#define CONFIG_ENV_IS_IN_FLASH 1
//#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
添加:
#define CONFIG_SYS_NO_FLASH 1
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_ENV_OFFSET 0X60000
#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
2. 修改:
$ gedit board/samsung/my2410/Makefile
COBJS := my2410.o nand_read.o
3. 因为没有 Nor Flash芯片,所以注释掉 /common/cmd_bootm.c中关于 imls命令的程序段和
/common/cmd_flash.c中的程序。不然,按上面的修改,编译会出错。
/common/cmd_bootm.c第75行:(“0”后面一定要换行!!!不然还会错!!!)
#if 0
#if defined(CONFIG_CMD_IMLS)
#include <flash.h>
extern flash_info_t flash_info[]; /* info for FLASH chips */
static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#endif
#endif
/common/cmd_bootm.c第1124行:(“0”后面一定要换行!!!不然还会错!!!)
改为:
#if 0
defined(CONFIG_CMD_IMLS)
/common/cmd_flash.c 32行后面的所有部分均注释掉:(“0”后面一定要换行!!!不然还会错!!!)
#if 0
defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
4. 修改配置文件,添加对NAND FLASH的支持 include/configs/my2410.h
在 Command line configuration 部分,添加
#define CONFIG_CMD_NAND
在最后添加
#if defined(CONFIG_CMD_NAND)
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_NAND_BASE 0x4E000000
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define SECTORSIZE 512
#define SECTORSIZE_2K 2048
#define NAND_SECTOR_SIZE SECTORSIZE
#define NAND_SECTOR_SIZE_2K SECTORSIZE_2K
#define NAND_BLOCK_MASK 511
#define NAND_BLOCK_MASK_2K 2047
#define NAND_MAX_CHIPS 1
#define CONFIG_MTD_NAND_VERIFY_WRITE
#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */
#endif /* CONFIG_CMD_NAND */
5. 在下面文件添加 board/samsung/my2410/my2410.c
添加:
#if defined(CONFIG_CMD_NAND)
#include <linux/mtd/nand.h>
#endif
6. 编译,运行
make distclean
make my2410_config
make