【原】s3c2410 u-boot-1.3.3移植记录
|
发布时间:2009-06-26 15:37:01 |
技术类别:ARM
|
|
将u-boot-1.3.3.tar.bz2解压,得到文件夹u-boot-1.3.3 ================================================================ 第 1 阶段 ================================================================
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 <config_cmd_default.h> #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 <config.h>
#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 重新编译更新即可。
|