Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371402
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类: 嵌入式

2010-12-19 17:47:20

    今天又抽了两个多小时折腾了一会儿...按照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的配置注释掉了...又时间再研究...
阅读(4144) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~