Tiny210 uboot 移植 No NAND device found!!!

来源:互联网 发布:淘宝如何看自己退货率 编辑:程序博客网 时间:2024/05/16 06:19

经过良久的学准备之后,终于可以真刀真枪的实干了,我得开发板是Tiny-210 V2版的,拿到之后发现友善有点坑阿,用的bootloader是superboot,不开源,不能满足要求,就想着移植uboot,于是在度娘了一下,已经有大牛们坐过了,也好,我就直接难过来可以用了。

可以看一下blog:http://blog.csdn.net/liukun321/article/details/8610868

下载编译烧写,一气呵成,不过问题出现了:



程序跑到这里移植重启,好吧,只能跟踪一下源码:

在文件 drivers/mtd/nand/nand_base.c

int nand_scan_ident(struct mtd_info *mtd, int maxchips,    const struct nand_flash_dev *table){int i, busw, nand_maf_id, nand_dev_id;struct nand_chip *chip = mtd->priv;const struct nand_flash_dev *type;/* Get buswidth to select the correct functions */busw = chip->options & NAND_BUSWIDTH_16;/* Set the default functions */nand_set_defaults(chip, busw);/* Read the flash type */type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table);if (IS_ERR(type)) {#ifndef CONFIG_SYS_NAND_QUIET_TESTprintk(KERN_WARNING "No NAND device found!!!\n");#endifchip->select_chip(mtd, -1);return PTR_ERR(type);}/* Check for a chip array */for (i = 1; i < maxchips; i++) {chip->select_chip(mtd, i);/* See comment in nand_get_flash_type for reset */chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);/* Send the command for reading device ID */chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);/* Read manufacturer and device IDs */if (nand_maf_id != chip->read_byte(mtd) ||    nand_dev_id != chip->read_byte(mtd))break;}#ifdef DEBUGif (i > 1)printk(KERN_INFO "%d NAND chips detected\n", i);#endif/* Store the number of chips and calc total size for mtd */chip->numchips = i;mtd->size = i * chip->chipsize;return 0;}
发现上面函数type值错误,于是跟踪函数 nand_get_flash_type()代码如下:

/* * Get the flash and manufacturer id and lookup if the type is supported */static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,  struct nand_chip *chip,  int busw,  int *maf_id, int *dev_id,  const struct nand_flash_dev *type){int ret, maf_idx;int tmp_id, tmp_manf;/* Select the device */chip->select_chip(mtd, 0);/* * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx) * after power-up */chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);/* Send the command for reading device ID */chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);/* Read manufacturer and device IDs */*maf_id = chip->read_byte(mtd);*dev_id = chip->read_byte(mtd);/* Try again to make sure, as some systems the bus-hold or other * interface concerns can cause random data which looks like a * possibly credible NAND flash to appear. If the two results do * not match, ignore the device completely. */chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);/* Read manufacturer and device IDs */tmp_manf = chip->read_byte(mtd);tmp_id = chip->read_byte(mtd);if (tmp_manf != *maf_id || tmp_id != *dev_id) {printk(KERN_INFO "%s: second ID read did not match "       "%02x,%02x against %02x,%02x\n", __func__,       *maf_id, *dev_id, tmp_manf, tmp_id);return ERR_PTR(-ENODEV);}if (!type)type = nand_flash_ids;for (; type->name != NULL; type++)if (*dev_id == type->id)break;if (!type->name) {/* supress warning if there is no nand */if (*maf_id != 0x00 && *maf_id != 0xff &&    *dev_id  != 0x00 && *dev_id  != 0xff)printk(KERN_INFO "%s: unknown NAND device: ""Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",__func__, *maf_id, *dev_id);return ERR_PTR(-ENODEV);}if (!mtd->name)mtd->name = type->name;chip->chipsize = (uint64_t)type->chipsize << 20;chip->onfi_version = 0;ret = nand_flash_detect_onfi(mtd, chip, &busw);if (!ret)nand_flash_detect_non_onfi(mtd, chip, type, &busw);/* Get chip options, preserve non chip based options */chip->options &= ~NAND_CHIPOPTIONS_MSK;chip->options |= type->options & NAND_CHIPOPTIONS_MSK;/* * Set chip as a default. Board drivers can override it, if necessary */chip->options |= NAND_NO_AUTOINCR;/* Try to identify manufacturer */for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {if (nand_manuf_ids[maf_idx].id == *maf_id)break;}/* * Check, if buswidth is correct. Hardware drivers should set * chip correct ! */if (busw != (chip->options & NAND_BUSWIDTH_16)) {printk(KERN_INFO "NAND device: Manufacturer ID:"       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);printk(KERN_WARNING "NAND bus width %d instead %d bit\n",       (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,       busw ? 16 : 8);return ERR_PTR(-EINVAL);}/* Calculate the address shift from the page size */chip->page_shift = ffs(mtd->writesize) - 1;/* Convert chipsize to number of pages per chip -1. */chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;chip->bbt_erase_shift = chip->phys_erase_shift =ffs(mtd->erasesize) - 1;if (chip->chipsize & 0xffffffff)chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;elsechip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 31;/* Set the bad block position */chip->badblockpos = mtd->writesize > 512 ?NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;/* Check if chip is a not a samsung device. Do not clear the * options for chips which are not having an extended id. */if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;/* Check for AND chips with 4 page planes */if (chip->options & NAND_4PAGE_ARRAY)chip->erase_cmd = multi_erase_cmd;elsechip->erase_cmd = single_erase_cmd;/* Do not replace user supplied command function ! */if (mtd->writesize > 512 && chip->cmdfunc == nand_command)chip->cmdfunc = nand_command_lp;MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"  " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,  nand_manuf_ids[maf_idx].name, type->name);return type;}
根据console打印信息:NAND bus width 8 instead 16 bit (NAND 带宽为8位而非16位),神经瞬间集中,看一下nand flash的datasheet发现原来是8位的IO位,所以分析出上面红色部分条件不满足,查找了一下 NAND_BUSWIDTH_16 

在文件 include/linux/mtd/nand.h 中:

/* Buswitdh is 16 bit */
#define NAND_BUSWIDTH_16 0x00000002

将其改为:

#define NAND_BUSWIDTH_160x00000001 

重新编译烧写,问题解决了。。。


原创粉丝点击