分享

【原】s3c2410 u

 guitarhua 2012-10-16
【原】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
重新编译更新即可。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多