注意:红色标记为修改的地方
4.1 Nand Flash相关代码的修改
在U-boot 启动的第一阶段,初始化了Nand Flash 控制器。但到第二阶段start_armboot函数还是会再次初始化Nand Flash 控制器。因为第二阶段和第一阶段的代码基本是独立的,第一阶段的代码基本只起到代码重定位的作用,到了第二阶段才是真正U-boot 的开始,以前的初始化过程还会重做一遍,比如始化Nand Flash 控制器、CPU 频率等。
因为S3C2440 和S3C2410 之间的很大差别就是:S3C2410 的Nand Flash 控制器只支持512B+16B 的Nand Flash,而S3C2440 还支持2KB+64B 的大容量Nand Flash。所以在Nand Flash 控制器上寄存器和控制流程上的差别很明显,底层驱动代码的修改也是必须的。具体的差别还是需要对比芯片数据手册的,下面是关于Nand Flash 底层驱动代码的修改:
打开/drivers/mtd/nand/s3c2410_nand.c文件
#include<s3c2410.h>
#include <asm/io.h>
#define NF_BASE 0x4e000000
#if defined(CONFIG_S3C2410)
#define S3C2410_NFCONF_EN (1<<15)
#define S3C2410_NFCONF_512BYTE (1<<14)
#define S3C2410_NFCONF_4STEP (1<<13)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<11)
#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
#define S3C2410_ADDR_NALE 4
#define S3C2410_ADDR_NCLE 8
#endif
#if defined(CONFIG_S3C2440)
#define S3C2410_NFCONT_EN (1<<0)
#define S3C2410_NFCONT_INITECC (1<<4)
#define S3C2410_NFCONT_nFCE (1<<1)
#define S3C2410_NFCONT_MAINECCLOCK(1<<5)
#define S3C2410_NFCONF_TACLS(x) ((x)<<12)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C2410_ADDR_NALE 0x08
#define S3C2410_ADDR_NCLE 0x0c
#endif
ulong IO_ADDR_W = NF_BASE;
static void s3c2410_hwcontrol(struct mtd_info *mtd,int cmd, unsigned int ctrl)
{
// structnand_chip *chip = mtd->priv;
structs3c2410_nand *nand = s3c2410_get_base_nand();
debugX(1,"hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
if (ctrl& NAND_CTRL_CHANGE) {
// ulongIO_ADDR_W = (ulong)nand;
IO_ADDR_W = (ulong)nand;
if(!(ctrl & NAND_CLE))
IO_ADDR_W|= S3C2410_ADDR_NCLE;
if(!(ctrl & NAND_ALE))
IO_ADDR_W|= S3C2410_ADDR_NALE;
// chip->IO_ADDR_W= (void *)IO_ADDR_W;
#if defined(CONFIG_S3C2410)
if (ctrl& NAND_NCE)
writel(readl(&nand->NFCONF)& ~S3C2410_NFCONF_nFCE,
&nand->NFCONF);
else
writel(readl(&nand->NFCONF)| S3C2410_NFCONF_nFCE,
&nand->NFCONF);
}
#endif
#if defined(CONFIG_S3C2440)
if(ctrl & NAND_NCE)
writel(readl(&nand->NFCONT)& ~S3C2410_NFCONT_nFCE,
&nand->NFCONT);
else
writel(readl(&nand->NFCONT)| S3C2410_NFCONT_nFCE,
&nand->NFCONT);
}
#endif
if (cmd !=NAND_CMD_NONE)
// writeb(cmd, chip->IO_ADDR_W);
writeb(cmd, (void *)IO_ADDR_W);
}
……….
void s3c2410_nand_enable_hwecc(struct mtd_info *mtd,int mode)
{
structs3c2410_nand *nand = s3c2410_get_base_nand();
debugX(1,"s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
#if defined(CONFIG_S3C2410)
writel(readl(&nand->NFCONF)| S3C2410_NFCONF_INITECC, &nand->NFCONF);
#endif
#if defined(CONFIG_S3C2440)
writel(readl(&nand->NFCONT)| S3C2410_NFCONT_INITECC, &nand->NFCONT);
#endif
}
………..
int board_nand_init(struct nand_chip *nand)
{
…………
debugX(1, "board_nand_init()\n");
writel(readl(&clk_power->CLKCON)| (1 << 4), &clk_power->CLKCON);
#if defined(CONFIG_S3C2410)
/* initializehardware */
twrph0 = 3;
twrph1 = 0;
tacls = 0;
cfg = S3C2410_NFCONF_EN;
cfg |=S3C2410_NFCONF_TACLS(tacls - 1);
cfg |=S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |=S3C2410_NFCONF_TWRPH1(twrph1 - 1);
writel(cfg,&nand_reg->NFCONF);
/* initializenand_chip data structure */
nand->IO_ADDR_R= nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;
#endif
#if defined(CONFIG_S3C2440)
twrph0= 4;
twrph1= 2;
tacls= 0;
cfg= 0;
cfg|= S3C2410_NFCONF_TACLS(tacls - 1);
cfg|= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg|= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
writel(cfg,&nand_reg->NFCONF);
cfg=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);
writel(cfg,&nand_reg->NFCONT);
/* initialize nand_chip data structure */
nand->IO_ADDR_R= nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;
#endif
/* read_buf and write_buf are default */
/* read_byteand write_byte are default */
4.2 修改网络相关代码
以前的U-boot 对于网络延时部分有问题,需要修改许多地方。但是现在的U-boot 网络部分已经基本不需要怎么修改了,只有在DM9000 的驱动和NFS 的TIMEOUT 参数上需要稍微修改一下:
对于 DM9000 的驱动,只是屏蔽了一点代码:
打开/drivers/net/dm9000x.c文件
static int dm9000_init(struct eth_device *dev, bd_t*bd)
{
……………
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 1000) {
// printf("couldnot establish link\n");
// return0;
break;
}
}
/* see whatwe've got */
lnk = phy_read(17) >> 12;
对于 NFS,增加了延时,否则会出现“*** ERROR: Cannot mount”的错误
打开net/nfs.c文件
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */
#define NFS_RETRY_COUNT 30
#define NFS_TIMEOUT (10*2000UL)
static int fs_mounted = 0;
static unsigned long rpc_id = 0;