分类: LINUX
2011-07-18 17:15:34
1)、在u-boot-1.3.3/board下找个与2410相似的开发板,这里smdk2410为例。
2)、将u-boot-1.3.3/board/smdk2410目录复制到当前目录下,并改名为edukit2410。
3)、把smdk2410.c改名为edukit2410.c,修改Makefile中的 COBJS := edukit2410.o pcmcia.o,保存。
4)、将u-boot-1.3.3/include/configs/smdk2410.h,复制到当前目录,并改名为edukit2410.h。
5)、修改u-boot-1.3.3/Makefile的内容
ifeq ($(ARCH),arm)
CROSS_COMPILE = /usr/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux-(交叉编译工具安装目录)
6)、在u-boot-1.3.3/Makefile中添加
edukit2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t edukit2410 NULL s3c24x0
7)、打开超级终端,切换到u-boot-1.3.3目录,敲入命令
# make edukit2410_config
Configuring for edukit2410 board...
8)、之后就可以# make了。
================================================================
第 2 阶段
================================================================
为了方便在linux下进行u-boot的修改和烧写,其实u-boot可通过一些命令和串口传输(使用ckermit)传输来实现自已烧写自已。下面是步骤:
1)、#protect off all 去保护
2)、#erase 00000 1ffff 擦除 00000H ~ 1ffffH的内容。
3)、#loadb
4)、用ckermit发送文件的方法:
按下ctrl + \,再按c切换到kermit输入命令 send /.../u-boot.bin,等待发送完毕。
5)、#cp.b 33000000 00000 200000
等待烧写完毕。
================================================================
第 3 阶段
================================================================
1)、将u-boot-1.3.3/include/configs/edukit2410.h中的
#define CFG_PROMPT "SMDK2410 # " /* Monitor Command Prompt */
改为
#define CFG_PROMPT "EDUKIT2410 # " /* Monitor Command Prompt */
这是u-boot命令前面的提示符
2)、将u-boot-1.3.3/include/configs/edukit2410.h中的
#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
#define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000) /* addr of environment */
改为
#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */
#define CFG_MAX_FLASH_SECT (35) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x1F0000) /* addr of environment */
3)、将将u-boot-1.3.3/include/configs/edukit2410.h中的
/*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
改为
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.2.201
#define CONFIG_SERVERIP 192.168.2.80
将同一文件中的关于CS8900的内容更改为:(这些内容可从其它带有DM9000的开发板中查找,然后修改内容,主要是片选和CMD片选)
/*
* Davicom DM9000 Network Card
*/
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+0x100000)
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_NET_RETRY_COUNT 10
然后将ping命令加入,即在同一文件中加入以下定义
#define CONFIG_CMD_PING
重新编译,然后设置相关的环境变量,如IP地址,物理地址等,保存。即可用ping 命令来测试网络是否通了。
4)、由于驱动里用的是dm9000x,开发板上用的是dm9000A,有所不同,如果直接用uboot自带的驱动ping不能。
需要将/root/Desktop/linux2410/SRC/u-boot-1.3.3/drivers/net/dm9000x.c的内容
/* Check packet ready or not */
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
在前面需要加两句:
/* Check packet ready or not */
DM9000_ior(DM9000_MRRH); /* The follow code is special in DM9000A */
DM9000_ior(DM9000_MRRL);
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
保存重新编译即可ping通。
5)、“could not establish link” 提示和慢响应的解决方法:
将/root/Desktop/linux2410/SRC/u-boot-1.3.3/drivers/net/dm9000x.c内容中
i = 0;
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 10000) {
printf("could not establish link\n");
return 0;
}
}
/* see what we've got */
lnk = phy_read(17) >> 12;
printf("operating at ");
switch (lnk) {
case 1:
printf("10M half duplex ");
break;
case 2:
printf("10M full duplex ");
break;
case 4:
printf("100M half duplex ");
break;
case 8:
printf("100M full duplex ");
break;
default:
printf("unknown: %d ", lnk);
break;
}
printf("mode\n");
屏蔽掉。即在头和尾加上
#if 0
...
#endif
================================================================
第 4 阶段
================================================================
1)、经过上面的修改,以太网已通,在PC上建立tftp服务,具体在FC7下如何安装和设置tftp服务,可查看邮箱的记载。在建立tftp服务之后
可通过u-boot的tftp命令下载内核镜象或者u-boot.bin来更新自已了。(这里PC的tftp服务根目录为/tftpboot/,内核文件名为zImage.img)
2)、在u-boot下通过命令已经可以下载内核或u-boot.bin了。但是发现在u-boot启动的时候没有出现 Hit any key to stop autoboot: 3
也就是说直接进入命令行,而不能自动引导。这个问题困拢了一天,后面通过看源代码,发现是由于环境变量的问题。环境变量中必须存在变量bootcmd,
否则不会等 待,直接进入命令行。u-boot启动时环境变量的初始化是先从flash中读取,如果flash中为空,则使用程序中的默认环境变量。
3)、我的u-boot是由smdk2410移植 过来的,smdk2410里/u-boot-1.3.3/include/configs/smdk2410.h里关于bootcmd等的环境变量已注
释掉:
#define CONFIG_BOOTDELAY 3
/*#define CONFIG_BOOTARGS "root=ramfs devfs="mount" console="ttySA0",9600" */
/*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.0.0.110
#define CONFIG_SERVERIP 10.0.0.1
/*#define CONFIG_BOOTFILE "elinos-lart" */
/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
其中CONFIG_BOOTARGS---对应环境变量---bootargs
CONFIG_BOOTFILE---对应环境变量---bootfile
CONFIG_BOOTCOMMAND---对应环境变量---bootcmd
4)、在上面的那三个相关的注释都去掉之后,重新编译链接,将u-boot更新。为什么一进u-boot还是进入命令行呢,是由于u-boot启动时环境变量
的初始化是先从flash中读取,如果flash中为空,则使用程序中的默认环境变量。由于我以前曾经把环境变量写到flash中(2M Nor Flash的最后
一个扇区,第35个扇区)。即使u-boot已更新,但是环境变量毫无变化,这样导致u-boot启动时的环境变量不是代码中的环境变量,而是以前烧在Flash
的旧环境变量。而这些旧环境变量中没有bootcmd项,所以u-boot启动之后直接进入命令行了。所以,为了使用程序中最新的环境变量,可将最后一块flash
擦掉。当然也可新增bootcmd变量,然后再saveenv。下次启动时会有等 待时间,并能进入自动引导模式。个人建议先不要把环境变量写入flash,等最后
确定之后,再写入不迟。当然没有写入flash时,会有提示*** Warning - bad CRC, using default environment。这是没关系的。使用程序中的
环境变量更有助于我们调试。
5)、将/u-boot-1.3.3/include/configs/edukit2410.h中已注释的地方
/*#define CONFIG_BOOTFILE "elinos-lart" */
/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
修改为
#define CONFIG_BOOTFILE "zImage.img"
#define CONFIG_BOOTCOMMAND "tftp 30008000 zImage.img; bootm 30008000"
保存并重新编译链接。并更新开发板上的u-boot。这样在u-boot启动时可自动将linux内核从pc上下载到SDRAM上运行。
================================================================
第 5 阶段 nand驱动
================================================================
1)、在u-boot-1.3.3/include/configs/edukit2410.h的
#ifndef __CONFIG_H
#define __CONFIG_H
前面增加以下定义
/*
add by xionggang.run on embest edukit iv board.
nand flash:K9F1208U0B,refer to web file
"移植U-Boot.1.3.1到S3C244和S3C2410"
*/
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#define rNFCONF (*(volatile unsigned int *)0x4e000000)
#define rNFCMD (*(volatile unsigned char *)0x4e000004)
#define rNFADDR (*(volatile unsigned char *)0x4e000008)
#define rNFDATA (*(volatile unsigned char *)0x4e00000c)
#define rNFSTAT (*(volatile unsigned int *)0x4e000010)
#define rNFECC (*(volatile unsigned int *)0x4e000014)
#define rNFECC0 (*(volatile unsigned char *)0x4e000014)
#define rNFECC1 (*(volatile unsigned char *)0x4e000015)
#define rNFECC2 (*(volatile unsigned char *)0x4e000016)
2)、在u-boot-1.3.3/include/configs/edukit2410.h的最后面加上,注意要放在最后一条语句
#endif /* __CONFIG_H */
之前
/*-----------------------------------------------------------------------
* NAND flash settings add by xionggang.refer to web file
"移植U-Boot.1.3.1到S3C244和S3C2410"
*/
#if defined(CONFIG_CMD_NAND)
#define CFG_NAND_BASE 0x4E000000
/* NandFlash控制器在SFR区起始寄存器地址 */
#define CFG_MAX_NAND_DEVICE 1
/* 支持的最在Nand Flash数据 */
#define SECTORSIZE 512
/* 1页的大小 */
#define NAND_SECTOR_SIZE SECTORSIZE
#define NAND_BLOCK_MASK 511
/* 页掩码 */
#define ADDR_COLUMN 1
/* 一个字节的Column地址 */
#define ADDR_PAGE 3
/* 3字节的页块地址*/
#define ADDR_COLUMN_PAGE 4
/* 总共4字节的页块地址*/
#define NAND_ChipID_UNKNOWN 0x00
/* 未知芯片的ID号 */
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
/* Nand Flash命令层底层接口函数 */
#define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;}
#define WRITE_NAND(d, adr) {rNFDATA = d;}
#define READ_NAND(adr) (rNFDATA)
#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
#define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* 允许Nand Flash写校验 */
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
#endif /* CONFIG_CMD_NAND */
3)、在u-boot-1.3.3/board/edukit2410/edukit2410.c文件的末尾添加对Nand Flash 的初始化函数(在后面Nand Flash的操作都要用到)
u-
boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand
flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调
用
drivers/nand/nand.c中的nand_init();否则调用自己在u-boot-1.3.3/board/edukit2410
/edukit2410.c中的nand_init()函数。这里我选择第二种方式。
在u-boot-1.3.3/board/edukit2410/edukit2410.h的内容
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
后加上以下宏:
#define CFG_NAND_LEGACY
然后在u-boot-1.3.3/board/edukit2410/edukit2410.c的最后添加下内容:
/*
add by xionggang.run on embest edukit iv board.
nand flash:K9F1208U0B
refer to "vcma9.h"
*/
#if defined(CONFIG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)/* 控制寄存器设置 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd) /* 命令寄存器传递命令 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd) /* 命令寄存器写操作 */
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr) /* 地址寄存器设置 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s) /* 设置nand flash的片选信号 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
break;
}
}
static inline void NF_WaitRB(void) /* 等待 nand flash处于 Ready状态 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data) /* 写数据操作 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFDATA = data;
}
static inline u8 NF_Read(void) /* 读数据操作 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void) /* 初始化ECC */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void) /* 读取ECC值 */
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFECC);
}
/*
add by xionggang.refer to "sbc2410x.c"
*/
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 1
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
/*nand->NFCONF
=
(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
*/
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE="H" tACLS tWRPH0 tWRPH1 */
NF_Reset();
}
void nand_init(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif
4)、u-boot-1.3.3/include/linux/mtd/nand_ids.h的结构体nand_flash_ids加入
static struct nand_flash_dev nand_flash_ids[] = {
...
{"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, // add by xionggang
{NULL,}
};
5)、最后记得在u-boot-1.3.3/board/edukit2410/edukit2410.h的
#include
#define CONFIG_CMD_PING
后加上flash命令:
#define CONFIG_CMD_NAND
最后保存#make,将生成的u-boot.bin下载到SRAM然后更新。上电运行。
u-boot启动后,可键入命令nand erase clean将整块nand flash擦除。
为了测试nand flash的驱动,可将u-boot.bin先下到33000000。然后通过u-boot命令nand write 33000000 0000 20000
将u-boot.bin烧写到nand flash。完成以后,再上电运u-boot。通过u-boot命令nand read 32000000 0000 20000
将u-boot.bin拷贝到32000000,然后go 32000000。如果u-boot能正常启动则说明nand的读写完好。
注:在添加了nand flash驱动之后,可能会编译通不过,主要是由于以下两个宏的定义所导致的:
#if defined(CONFIG_CMD_NAND)
#if !defined(CFG_NAND_LEGACY)
...
#else
// #error "U-Boot legacy NAND support not available for S3C2410" // by xionggang
#endif
#endif
解决办法是将
#error "U-Boot legacy NAND support not available for S3C2410" 注释掉。
================================================================
第 6 阶段 根据需从nor启动改为nand启动。 注:经过以上步骤编译成的u-boot.bin烧写到norflash的前面,设置成从nor启动,可以正常启动运行。
下面将实现从nand启动,只需将编译生成的bin烧写到nandflash的前面,设置成nand启动即可引导u-boot,在功能上与norflash启动的完全一样。
================================================================
1)、修改/cpu/arm920t/start.S
在
#ifndef 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
将#ifndef CONFIG_AT91RM9200改为#ifdef CONFIG_AT91RM9200,目的是启动时不执行relocate。以从nand启动。
并在其后加上:
// add by xionggang,start
#ifdef CONFIG_S3C2410_NAND_BOOT
@ one half leds off
ldr r0,=0x21180000
ldr r1,=0xA
strb r1,[r0]
@ 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, #0x20000
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 @ infinite loop
ok_nand_read:
@ the other half leds on
ldr r0,=0x21180000
ldr r1,=0x5
strb r1,[r0]
@ 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 @ CONFIG_S3C2410_NAND_BOOT
// add by xionggang,end
2)、在
_start_armboot: .word start_armboot
后加上:
// add by xionggang
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
3)、在board/edukit2410/下添加NAND Flash读函数文件nand_read.c,内容如下:(参考vivi中nand_read.c)
/*
add by xionggang
*/
#include
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#if defined(CONFIG_S3C2410)
#define NFCONF __REGi(NF_BASE + 0x0)
#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
inline void wait_idle(void) {
int i;
while(!(NFSTAT & BUSY))
for(i=0; i<10; i++);
}
/* low level nand read function ,refer to vivi*/
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j, t;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /* invalid alignment */
}
/* chip Enable */
NFCONF &= ~0x800;
for (t = 0; t < 100; t++);
for(i=start_addr; i < (start_addr + size);) {
/* READ0 */
NFCMD = 0;
/* Write Address */
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
//for (t = 0; t < 1500; t++); /* add by thisway, if not, will not work at some case */
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA & 0xff);
buf++;
}
}
/* chip Disable */
NFCONF |= 0x800; /* chip disable */
return 0;
}
# endif
4)、修改board/edukit2410/Makefile文件
......
OBJS := tekkaman2440.o nand_read.o flash.o
......
5)、修改include/configs/edukit2410.h,添加如下内容:
/*
* add by xionggang ,In order to Nandflash Boot
*/
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
#define CONFIG_S3C2410_NAND_BOOT
/* NAND Flash Controller */
#define NAND_CTL_BASE 0x4E000000
#define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb))
6)、如果按照u-boot.1.3.3以前的版本,如果u-boot.1.3.1,经过以上步聚编译之后烧写到nandflash应该可以正常运行。
同样的步聚在1.3.1可以正常运行,但是在1.3.3上不能正常运行。后来经过对比System.map文件中函数地址发现了原因。
在1.3.1中默认链接下,start.o放在最前面,后面紧接着nand_read.o和lowlevel_init.o。并且这三部分加起来大小小于4K。
在1.3.3中默认链接下,start.o放在最前面,后面不是紧跟nand_read.o和lowlevel_init.o。中间有许多其它函数。而且
nand_read.o和lowlevel_init.o与start.o的距离远大于4K。当从nand启动时,只将最开始的4K搬到SRAM中,而这4K中不包
括nand_read.o和lowlevel_init.o,但是要能正常启动,必须在前4k里调用该两个文件中的函数!因此在默认情况下是不能
正常运行的。需要手动改改链接脚本。
修改board/edukit2410/u-boot.lds文件,在
cpu/arm920t/start.o (.text)后加上
board/edukit2410/lowlevel_init.o (.text)
board/edukit2410/nand_read.o (.text)
这样指定start.o、nand_read.o、lowlevel_init.o放在最前面4K中。重新编译运行就可以正常从nand启动了!!!
================================================================
第 7 阶段 将环境变量从保存到nor flash改成保存到nand flash。
================================================================
1)、将include/configs/edukit2410.h中的
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
改为:
//#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_IS_IN_NAND 1 /* add by xionggang,save env to nand flash */
#define CFG_ENV_OFFSET 0X20000 /* add by xionggang */
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
2)、修改common/env_nand.c
在
int nand_legacy_rw (struct nand_chip* nand, int cmd,
size_t start, size_t len,
size_t * retlen, u_char * buf);
后面添加
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; /* add by xionggang */
extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean); /* add by xionggang */
将
extern nand_info_t nand_info[];
修改为:
extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];
3)、在当前文件中修改#else /* ! CFG_ENV_OFFSET_REDUND */后的saveenv函数:
将if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
替换成:
if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
将ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
替换成:
ret = nand_legacy_rw(nand_dev_desc + 0,0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,&total,(u_char*)env_ptr);
修改#else /* ! CFG_ENV_OFFSET_REDUND */后的env_relocate_spec函数:
将ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
替换成:
ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);
重新编译运行,即可将环境变量保存到nand flash而非nor flash了。
注:在用u-boot来给linux内核传递参数里需要增加对以下宏的定义:
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
注:四型箱的Mini2410子板上也有一个DM9000A的网卡芯片,以上的驱动针对主板上的DM9000A,如果需要使用子板上的DM9000A,
只需将include/configs/edukit2410.h中的
/*
* Davicom DM9000 Network Card
* 使用EduKit IV主板上的网卡
*/
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+0x100000)
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_NET_RETRY_COUNT 10
修改为:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x10000000
#define DM9000_IO (CONFIG_DM9000_BASE)
#define DM9000_DATA (CONFIG_DM9000_BASE+2)
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_NET_RETRY_COUNT 10
重新编译更新即可。