分类:
2010-09-28 21:18:26
u-boot- 1.1.6 已经可以通过"nand write..."、"nand write.jffs2..."等命令来烧写
cramfs、jffs2 文件系统映象文件,下面增加"nand write.yaffs..."
要使用JFFS2 文件系统要进行一下设置
加入CFG_CMD_JFFS2 命名的定义
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_JFFS2 | \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
增加JFFS2 命令行宏定义
#define CONFIG_JFFS2_CMDLINE 1
#define CONFIG_JFFS2_NAND 1
#define MTDIDS_DEFAULT "nand0=nandflash0"
#define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k@0(bios)," \
"128k(params)," \
"128k(toc)," \
"2m(kernel)," \
"-(root)"
在commom/cmd_nand.c 中增加"nand write.yaffs..." 的使用说明,代码添加如
下:458 行
U_BOOT_CMD(nand, 5, 1, do_nand,
"nand - NAND sub-system\n",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
"nand read[.jffs2] - addr off|partition size\n"
"nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
"nand read.yaffs addr off size - read the `size' byte yaffs image starting\n"
" at offset `off' to memory address `addr'\n"
"nand write.yaffs addr off size - write the `size' byte yaffs image starting\n"
" at offset `off' from memory address `addr'\n"
"nand erase [clean] [off size] - erase `size' bytes from\n"
" offset `off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
} else {
/* write */
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
/* opts.forcejffs2 = 1; */
opts.pad = 1;
opts.blockalign = 1;
opts.quiet = quiet;
ret = nand_write_opts(nand, &opts);
然后,在nand 命令的处理函数do_nand 中增加对"nand yaffs..."的支持。
do_nand 函数仍在commom/cmd_nand.c 中实现,代码修改如下: 354 行
if (s != NULL &&
(!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
if (read) {
/* read */
nand_read_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
opts.quiet = quiet;
ret = nand_read_opts(nand, &opts);
} else {
/* write */
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
/* opts.forcejffs2 = 1; */
opts.pad = 1;
opts.blockalign = 1;
opts.quiet = quiet;
ret = nand_write_opts(nand, &opts);
}
}else if ( s != NULL && !strcmp(s, ".yaffs")){
if (read) {
/* read */
nand_read_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
opts.readoob = 1;
opts.quiet = quiet;
ret = nand_read_opts(nand, &opts);
} else {
/* write */
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer = (u_char*) addr;
opts.length = size;
opts.offset = off;
/* opts.forceyaffs = 1; */
opts.noecc = 1;
opts.writeoob = 1;
opts.blockalign = 1;
opts.quiet = quiet;
opts.skipfirstblk = 1;
ret = nand_write_opts(nand, &opts);
}
}
else {
if (read)
ret = nand_read(nand, off, &size, (u_char *)addr);
else
ret = nand_write(nand, off, &size, (u_char *)addr);
}
printf(" %d bytes %s: %s\n", size,
read ? "read" : "written", ret ? "ERROR" : "OK");
return ret == 0 ? 0 : 1;
上述代码中,opts.skipfirstblk 是新增加的项,表示烧写时跳过第一个可用的逻
辑块, 这是由yaffs 文件系统的特性决定的。下面给opts.skipfirstblk 新增加项
重新定义nand_write_options_t 结构,并在下面调用的nand_write_opts 函数中对
他进行处理。
在include/nand.h 中进行如下修改,增加skipfirstblk 成员: 81 行
struct nand_write_options {
u_char *buffer; /* memory block containing image to write */
ulong length; /* number of bytes to write */
ulong offset; /* start address in NAND */
int quiet; /* don't display progress messages */
int autoplace; /* if true use auto oob layout */
int forcejffs2; /* force jffs2 oob layout */
int forceyaffs; /* force yaffs oob layout */
int noecc; /* write without ecc */
int writeoob; /* image contains oob data */
int pad; /* pad to page size */
int blockalign; /* 1|2|4 set multiple of eraseblocks
* to align to */
int skipfirstblk; /* if true, skip the first good block,
* set true when write the yaffs image,
*/
};
在drivers/nand/nand_util.c 修改nand_write_opts 函数,增加对skipfirstblk 成
员的支持: 301 行
int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)
{
int imglen = 0;
int pagelen;
int baderaseblock;
int blockstart = -1;
loff_t offs;
int readlen;
int oobinfochanged = 0;
int percent_complete = -1;
struct nand_oobinfo old_oobinfo;
ulong mtdoffset = opts->offset;
ulong erasesize_blockalign;
u_char *buffer = opts->buffer;
size_t written;
int result;
int skipfirstblk = opts->skipfirstblk;
428 行
/* skip the first good block when wirte yaffs image, by */
if (skipfirstblk) {
mtdoffset += erasesize_blockalign;
skipfirstblk = 0;
continue;
}
readlen = meminfo->oobblock;
if (opts->pad && (imglen < readlen)) {
readlen = imglen;
memset(data_buf + readlen, 0xff,
meminfo->oobblock - readlen);
}
进行上面移植后,u-boot 已经支持yaffs 文件系统映象的烧写,由于前面设置
"opts.noecc=1" 不使用ECC 校验码,烧写时会提示很多提示信息。
修改drivers/nand/nand_base.c 文件中的nand_write_page 函数, 将其注释
掉。
910 行
case NAND_ECC_NONE:
//printk (KERN_WARNING "Writing data without ECC to NANDFLASH
is not recommended\n");
完善do_go 函数
编辑common/cmd_boot.c 函数即可。
gedit common/cmd_boot.c
/*添加call_linux 函数*/
/**********************************************************************/
void call_linux(long a0, long a1, long a2)
{
__asm__(
" mov r1, #0\n"
" mov r1, #7 << 5\n" /* 8 segments */
"1: orr r3, r1, #63 << 26\n" /* 64 entries */
"2: mcr p15, 0, r3, c7, c14, 2\n" /* clean & invalidate D index */
" subs r3, r3, #1 << 26\n"
" bcs 2b\n" /* entries 64 to 0 */
" subs r1, r1, #1 << 5\n"
" bcs 1b\n" /* segments 7 to 0 */
" mcr p15, 0, r1, c7, c5, 0\n" /* invalidate I cache */
" mcr p15, 0, r1, c7, c10, 4\n" /* drain WB */
);
__asm__(
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c10, 4\n" /* drain WB */
"mcr p15, 0, r0, c8, c7, 0\n" /* invalidate I & D TLBs */
);
__asm__(
"mov r0, %0\n"
"mov r1, #0x0c1\n"
"mov r2, %2\n"
"mov ip, #0\n"
"mcr p15, 0, ip, c13, c0, 0\n" /* zero PID */
"mcr p15, 0, ip, c7, c7, 0\n" /* invalidate I,D caches */
"mcr p15, 0, ip, c7, c10, 4\n" /* drain write buffer */
"mcr p15, 0, ip, c8, c7, 0\n" /* invalidate I,D TLBs */
"mrc p15, 0, ip, c1, c0, 0\n" /* get control register */
"bic ip, ip, #0x0001\n" /* disable MMU */
"mcr p15, 0, ip, c1, c0, 0\n" /* write control register */
"mov pc, r2\n"
"nop\n"
"nop\n"
: /* no outpus */
: "r" (a0), "r" (a1), "r" (a2)
);
}
/*******************添加setup_linux_param 函数***********************/
static void setup_linux_param(ulong param_base)
{ struct param_struct *params = (struct param_struct *)param_base;
char *linux_cmd;
//linux_cmd = "noinitrd root=/dev/mtdblock/2 init=/linuxrc console=ttyS0";
linux_cmd = getenv("bootargs");
memset(params, 0, sizeof(struct param_struct));
params->u1.s.page_size = 0x00001000;
params->u1.s.nr_pages = (0x04000000 >> 12);
/* set linux command line */
memcpy(params->commandline, linux_cmd, strlen(linux_cmd) + 1);
}
/**************************在do_go()函数中添加*********************/
printf ("## Starting application at 0x%08lX ...\n", addr);
setup_linux_param(0x30000100);
call_linux(0,0x0c1,0x30008000);
printf("ok\n");
最后
make
没有错误。至此,Uboot 的移植就已经移好了。