修改 UBOOT (支持 NFS 和 yaffs)
1.
针对 NFS 的如下错误
ERROR: Cannot umount
修改uboot如下:
u-boot-2009.08/net/nfs.c
455行 左右修改如下
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
去掉 if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
添加 if ((ntohl(rpc_pkt.u.reply.id)+1) != rpc_id)
return -1;
2.
对yaffs 的支持,参考如下patch,patch转载自如下网址
http://blog.chinaunix.net/u1/34474/article_62956.html
不过现在好像不在了,我贴到下面吧
diff -uaNr u-boot-2009.08/common/cmd_nand.c u-boot-2009.08_tekkaman/common/cmd_nand.c
--- u-boot-2009.08/common/cmd_nand.c 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/common/cmd_nand.c 2009-10-28 21:20:49.000000000 +0800
@@ -389,6 +389,28 @@
else
ret = nand_write_skip_bad(nand, off, &size,
(u_char *)addr);
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ }else if ( s != NULL &&
+ (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))){
+ if(read) {
+ //nand->rw_oob = 1;
+ //ret = nand_read_skip_bad(nand,off,&size,(u_char *)addr);
+ // nand->rw_oob = 0;
+ printf("nand read.yaffs[1] is not provide temporarily!");
+ } else {
+ nand->rw_oob = 1;
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+ nand->skipfirstblk = 1;
+#else
+ nand->skipfirstblk = 0;
+#endif
+ ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr);
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+ nand->skipfirstblk = 0;
+#endif
+ nand->rw_oob = 0;
+ }
+#endif
} else if (!strcmp(s, ".oob")) {
/* out-of-band data */
mtd_oob_ops_t ops = {
@@ -496,6 +518,13 @@
" to/from memory address 'addr', skipping bad blocks./n"
"nand erase [clean] [off size] - erase 'size' bytes from/n"
" offset 'off' (entire device if not specified)/n"
+#if defined(ENABLE_CMD_NAND_YAFFS)
+// "nand read[.yaffs[1]] addr off size - read the `size' byte yaffs image starting/n"
+// " at offset `off' to memory address `addr' (.yaffs1 for 512+16 NAND)/n"
+ "nand read[.yaffs[1]] is not provide temporarily!/n"
+ "nand write[.yaffs[1]] addr off size - write the `size' byte yaffs image starting/n"
+ " at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)/n"
+#endif
"nand bad - show bad blocks/n"
"nand dump[.oob] off - dump page/n"
"nand scrub - really clean NAND erasing bad blocks (UNSAFE)/n"
diff -uaNr u-boot-2009.08/drivers/mtd/nand/nand_base.c u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_base.c
--- u-boot-2009.08/drivers/mtd/nand/nand_base.c 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_base.c 2009-10-28 21:19:23.000000000 +0800
@@ -1958,7 +1958,30 @@
{
struct nand_chip *chip = mtd->priv;
int ret;
-
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code!*/
+ //æ€æ®µæ°æ®æ¯å°èŠåå
¥çæ°æ®äžçæ£åžžæ°æ®ç§»å°bufäžçå段ïŒæoobæ°æ®ç§»å°å段ã
+ int oldopsmode = 0;
+ if(mtd->rw_oob==1) {
+ size_t oobsize = mtd->oobsize; //å®ä¹oobsizeç倧å°
+ size_t datasize = mtd->writesize;
+ int i = 0;
+ uint8_t oobtemp[16];
+ int datapages = 0;
+ datapages = len/(datasize); //äŒ è¿æ¥çlenæ¯æ²¡æå
æ¬oobçæ°æ®é¿åºŠ
+ for(i=0;i<(datapages);i++) {
+ memcpy((void *)oobtemp,
+ (void *)(buf+datasize*(i+1)),
+ oobsize);
+ memmove((void *)(buf+datasize*(i+1)),
+ (void *)(buf+datasize*(i+1)+oobsize),
+ (datapages-(i+1))*(datasize)+(datapages-1)*oobsize);
+ memcpy((void *)(buf+(datapages)*(datasize+oobsize)-oobsize),
+ (void *)(oobtemp),
+ oobsize);
+ }
+ }
+#endif
/* Do not allow reads past end of device */
if ((to + len) > mtd->size)
return -EINVAL;
@@ -1969,14 +1992,30 @@
chip->ops.len = len;
chip->ops.datbuf = (uint8_t *)buf;
- chip->ops.oobbuf = NULL;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code!*/
+ if(mtd->rw_oob!=1) {
+ chip->ops.oobbuf = NULL;
+ } else {
+ chip->ops.oobbuf = (uint8_t *)(buf+len); //å°oobçŒåçæéæåbufçå段ïŒå³oobæ°æ®åºçèµ·å§å°åã
+ chip->ops.ooblen = mtd->oobsize;
+ oldopsmode = chip->ops.mode;
+ chip->ops.mode = MTD_OOB_RAW; //å°åå
¥æš¡åŒæ¹äžºçŽæ¥ä¹ŠåoobåºïŒå³åå
¥æ°æ®æ¶ïŒäžè¿è¡ECCæ ¡éªç计ç®ååå
¥ãïŒyaffsæ åçoobæ°æ®äžïŒæ¬èº«å°±åžŠæECCæ ¡éªïŒ
+ }
+#else
+ chip->ops.oobbuf = NULL;
+#endif
ret = nand_do_write_ops(mtd, to, &chip->ops);
*retlen = chip->ops.retlen;
nand_release_device(mtd);
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code!*/
+ chip->ops.mode = oldopsmode; //æ¢å€åæš¡åŒ
+#endif
return ret;
}
diff -uaNr u-boot-2009.08/drivers/mtd/nand/nand_util.c u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_util.c
--- u-boot-2009.08/drivers/mtd/nand/nand_util.c 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_util.c 2009-11-01 14:18:28.000000000 +0800
@@ -480,6 +480,26 @@
size_t left_to_write = *length;
size_t len_incl_bad;
u_char *p_buffer = buffer;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code*/
+ //è¿æ®µçšåºäž»èŠæ¯ä»yaffsæ åäžæåèŠåå
¥çæ£åžžæ°æ®çé¿åºŠïŒå³äžå
æ¬oobæ°æ®çæ°æ®é¿åºŠ
+ if(nand->rw_oob==1) {
+ size_t oobsize = nand->oobsize; //å®ä¹oobsizeç倧å°
+ size_t datasize = nand->writesize;
+ int datapages = 0;
+
+ //é¿åºŠäžæ¯528æŽæ°åïŒè®€äžºæ°æ®åºéã
+ if (((*length)%(nand->oobsize+nand->writesize)) != 0) {
+ printf ("Attempt to write error length data!/n");
+ return -EINVAL;
+ }
+
+ datapages = *length/(datasize+oobsize);
+ *length = datapages*datasize;
+ left_to_write = *length;
+// nand->skipfirstblock=1;
+ }
+#endif
/* Reject writes, which are not page aligned */
if ((offset & (nand->writesize - 1)) != 0 ||
@@ -494,7 +514,9 @@
printf ("Attempt to write outside the flash area/n");
return -EINVAL;
}
-
+
+#if !defined(ENABLE_CMD_NAND_YAFFS)
+/*by hugerat,phase 6 æ€æ®µçšåºæ¬ææ¯æ²¡æååæ¶ïŒäžè¿è¡ååæ£æ¥çŽæ¥åïŒäœæ²¡æ蟟å°ç®çïŒäžäœ¿æåå ççšåºäžèœæ£åžžå·¥äœïŒæ³šæ*/
if (len_incl_bad == *length) {
rval = nand_write (nand, offset, length, buffer);
if (rval != 0)
@@ -503,7 +525,7 @@
return rval;
}
-
+#endif
while (left_to_write > 0) {
size_t block_offset = offset & (nand->erasesize - 1);
size_t write_size;
@@ -516,12 +538,21 @@
offset += nand->erasesize - block_offset;
continue;
}
-
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code*/
+ if(nand->skipfirstblk==1) { //åŠéè·³è¿ç¬¬äžäžªå¥œåïŒåè·³è¿ç¬¬äžäžªå¥œåã
+ nand->skipfirstblk=0;
+ printf ("Skip the first good block %llx/n",
+ offset & ~(nand->erasesize - 1));
+ offset += nand->erasesize - block_offset;
+ continue;
+ }
+#endif
if (left_to_write < (nand->erasesize - block_offset))
write_size = left_to_write;
else
write_size = nand->erasesize - block_offset;
-
+ printf("/rWriting at 0x%llx -- ",offset); /*Thanks for hugerat's code*/
rval = nand_write (nand, offset, &write_size, p_buffer);
if (rval != 0) {
printf ("NAND write to offset %llx failed %d/n",
@@ -531,8 +562,18 @@
}
left_to_write -= write_size;
+ printf("%d%% is complete.",100-(left_to_write/(*length/100)));/*Thanks for hugerat's code*/
offset += write_size;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code*/
+ if(nand->rw_oob==1) {
+ p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
+ } else {
+ p_buffer += write_size;
+ }
+#else
p_buffer += write_size;
+#endif
}
return 0;
diff -uaNr u-boot-2009.08/include/linux/mtd/mtd.h u-boot-2009.08_tekkaman/include/linux/mtd/mtd.h
--- u-boot-2009.08/include/linux/mtd/mtd.h 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/include/linux/mtd/mtd.h 2009-10-28 21:19:23.000000000 +0800
@@ -129,6 +129,12 @@
*/
u_int32_t writesize;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ /*Thanks for hugerat's code*/
+ u_char rw_oob;
+ u_char skipfirstblk;
+#endif
+
u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */
u_int32_t oobavail; /* Available OOB bytes per block */
对USB的支持
1. 定义如下即可:
#define CONFIG_CMD_USB
#define CONFIG_CMD_FAT
#define CONFIG_USB_OHCI
#define CONFIG_USB_STORAGE
//#define CONFIG_KEYBOARD
//#define CONFIG_USB_KEYBOARD
#define CONFIG_DOS_PARTITION
#define CONFIG_SYS_DEVICE_DEREGISTER
#define CONFIG_SUPPORT_VFAT
#define LITTLEENDIAN
2. 开启的命令
usb start //开启 U 盘
fatls usb 0 //列出 U 盘(usb 0)内容
fatload usb 0 0x30010000 u-boot.bin //将 U 盘中的 u-boot.bin 考到 ram 的
将 u-boot.bin 烧写到 Nand Flash 的 0 地址
nand erase 0 0x30000 //
nand write 0x30010000 0 0x30000 //