今天又抽了两个多小时折腾了一会儿...按照start_armboot里初始化的过程...一步一步的修改代码.
首先碰到的就是nand_init了.但是s3c2410的默认配置是不在start_armboot里调用nand_init。
如下:
#if defined(CONFIG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
所以首先需要再$SRCDIR/include/config/smdk2410.h里增加
#define CONFIG_CMD_NAND 1
BTW:起始应该新创建代码树来进行移植的...可我不想这样做.虽然网上一般都用这种方法...
跟踪源代码. nand_init()定义在$SRCDIR/drivers/mtd/nand/nand.c文件中。
nand_init()进而调用nand_init_chip(). 在nand_init_chip里又会调用board_nand_init(),
看名字就知道这个函数是与开发板相关的.重点就在这个函数里了.
board_nand_init()定义在$SRCDIR/cpu/arm920t/s3c24x0/nand.c文件中。
其作用就是初始化nand flash芯片.然后挂上一些与硬件相关的钩子函数...
由于从u-boot是从nand flash引导启动的.所以可以跳过这里的nand flash芯片初始化过程.
但为了保证兼容和通用性.
增加#ifndef CONFIG_BOOT_FROM_NAND #else #endif条件编译指令.
#ifndef CONFIG_BOOT_FROM_NAND
# ifndef CONFIG_S3C2440
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
DEBUGN("board_nand_init()\n");
clk_power->CLKCON |= (1 << 4);
/* initialize hardware */
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);
NFCONF = cfg;
# else
boot_nand_init();
# endif
保留s3c2410的代码. 若是s3c2440直接调用boot_nand_init()。这个函数是因为需要从nand flash启动而定义的初始化nand flash的函数.既然是从nand flash引导的.这里的代码就不会被编译进u-boot.
由于s3c2440和s3c2410的nand flash控制器的几个寄存器的地址和功能不一样.还需要修改寄存器地址.
# define NF_BASE 0x4e000000
# define NFCONF __REGi(NF_BASE + 0x0)
# define NFCONT __REGb(NF_BASE + 0x4)
# define NFCMD __REGb(NF_BASE + 0x8)
# define NFADDR __REGb(NF_BASE + 0xc)
# define NFDATA __REGb(NF_BASE + 0x10)
# define NFSTAT __REGb(NF_BASE + 0x20)
在看看后面挂入的几个钩子函数.
对于s3c2410_hwcontrol函数需要修改的就是使能和禁止nand flash片选信号的操作.
在文件头添加:
#define NAND_SELECT_CHIP (~(1 << 1))
#define NAND_DESELECT_CHIP (1 << 1)
为了保留s3c2410的代码.也采用条件编译.
对于s3c2440的函数如下:
static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip *chip = mtd->priv;
DEBUGN("hwcontrol(): 0x%02x: ", cmd);
switch (cmd) {
case NAND_CTL_SETNCE:
NFCONT &= NAND_SELECT_CHIP;
DEBUGN("SETNCE!\n");
break;
case NAND_CTL_CLRNCE:
NFCONT |= NAND_DESELECT_CHIP;
DEBUGN("CLRNCE\n");
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = NF_BASE + 0xc;
DEBUGN("SETALE\n");
break;
case NAND_CTL_SETCLE:
chip->IO_ADDR_W = NF_BASE + 0x8;
DEBUGN("SETCLE\n");
break;
default:
chip->IO_ADDR_W = NF_BASE + 0x10;
break;
}
return;
}
如果不需要硬件ecc检测.其他的地方就不需要修改了...
这时候编译会产生错误:
说的是没有定义CFG_MAX_NAND_DEVICE和CFG_NAND_BASE
在$SRC/include/config/smdk2410添加;
#define CFG_MAX_NAND_DEVICE 1
#define CFG_NAND_BASE 0
CFG_MAX_NAND_DEVICE根据板子上nand flash的个数来定义.
CFG_NAND_BASE任意定义都可以.
在board_nand_init()中会进行正确的修改.
然后再编译运行...u-boot就可以识别nand flash了...当然是其已经支持的nand flash的型号.
我的板子显示如下:
NAND: nand_maf_id: 236
nand_dev_id: 218
256 MiB
移植到现在...u-boot的完整输出如下:
U-Boot 1.3.4 (Dec 19 2010 - 17:34:43)
U-Boot code: 33F80000 -> 33FA2740 BSS: -> 33FA8280
RAM Configuration:
Bank #0: 30000000 64 MB
NAND: nand_maf_id: 236
nand_dev_id: 218
256 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
### main_loop entered: bootdelay=3
### main_loop: bootcmd=""
SMDK2410 #
可以使用一些命令了...不过其他的硬件是否能够正常工作还不清楚...
再有空的时候继续看源码...继续移植咯.
另外很闹人的是. 在初始化调用board_init配置GPIO引脚的时候. 按照默认的设置...蜂鸣器老会响.
真是凡人...我现在也不太清楚怎样把这个弄好...
索性直接把GPBCON的配置注释掉了...又时间再研究...
阅读(976) | 评论(0) | 转发(0) |