u-boot-2012-07 for tiny210, 支持USB DNW, 支持YAFFS2烧写, 彻底抛弃superboot

买tiny210开发板之前, 真不知道连u-boot也不是提供。
superboot虽好,但只提供二进制文件,且只能用SD卡烧写,太不爽了。 从QQ2440,到Tiny6410, 再到Tiny210,  
感觉硬件越来越超值,可送的软件却越来越垃圾了。

痛定思痛,决定移植u-boot, 最早是在2011-12上面搞, 当时把USB DNW做好了(借用6410 usbd-otg-hs.c/.h,  小改了几处实现),能烧写u-boot, kernel等二进制文件,
烧写yaffs2, 却启不来,... 因为项目忙,所以就搁置了

最近看到u-boot 2012-07发布,决定直接在最新版本的u-boot上去把心愿了却。
主要方法是: 对比superboot烧写后的OOB数据, IMG原始OOB数据,以及u-boot烧写后的OOB数据。

通过不断对比发现:  
1. 要用友善的mkyaffs2image-128M, 因为它里面才包含了ECC layout相关数据。
2. nand_write_skip_bad的
if (!need_skip && !(flags & WITH_DROP_FFS)) {
        rval = nand_write (nand, offset, length, buffer);
        if (rval == 0)
            return 0;

        *length = 0;
        printf ("NAND write to offset %llx failed %d\n",
            offset, rval);
        return rval;
}
这段代码要屏蔽 (这段代码在有些情况下会导致OOB没有写入
3. nand_do_write_ops函数的

    if (likely(!oob))
        memset(chip->oob_poi, 0xff, mtd->oobsize);
要把这个if判断拿掉 (经验证, 这个不是必须的
4.  OOB mode要改为MTD_OOB_PLACE。代码如下:

int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
   u_char *buffer, int flags)

{

......

#ifdef CONFIG_CMD_NAND_YAFFS
  if (flags & WITH_YAFFS_OOB) {
   int page, pages;
   size_t pagesize = nand->writesize;
   size_t pagesize_oob = pagesize + nand->oobsize;
   struct mtd_oob_ops ops;

   ops.len = pagesize;
   ops.ooblen = nand->oobsize;
   ops.mode = MTD_OOB_PLACE; //MTD_OOB_AUTO;
   ops.ooboffs = 0;

 ........


5. u-boot要关闭8bit hw ecc, 打开 CONFIG_NAND_4BIT_ECC。 这个很关键

在tiny210.h文件中

#define CONFIG_NAND_4BIT_ECC  1

/*
#define CONFIG_NAND_BL1_8BIT_ECC
#define CONFIG_8BIT_HW_ECC_SLC      1

*/

 

6. 修改nand 驱动

int board_nand_init(struct nand_chip *nand)

{

.....

if (!type->pagesize) {
  if (((nand->cellinfo >> 2) & 0x3) == 0) {
   nand_type = S3C_NAND_TYPE_SLC;
   nand->ecc.size = 512;
   nand->ecc.bytes = 4;

.......

   if ((1024 << (tmp & 0x3)) > 512) {
#if !defined(CONFIG_NAND_BL1_8BIT_ECC)   
   
 nand->ecc.read_page = s3c_nand_read_page_1bit;
    nand->ecc.write_page = s3c_nand_write_page_1bit;
    nand->ecc.read_oob = s3c_nand_read_oob_1bit;
    nand->ecc.write_oob = s3c_nand_write_oob_1bit;
    nand->ecc.layout = &s3c_nand_oob_64;
    nand->ecc.hwctl = s3c_nand_enable_hwecc;
                nand->ecc.calculate = s3c_nand_calculate_ecc;
                nand->ecc.correct = s3c_nand_correct_data;
                nand->options |= NAND_NO_SUBPAGE_WRITE;
#else
    nand->ecc.read_page = s3c_nand_read_page_8bit;
    nand->ecc.write_page = s3c_nand_write_page_8bit;
    nand->ecc.read_oob = s3c_nand_read_oob_8bit;
    nand->ecc.write_oob = s3c_nand_write_oob_8bit;
    nand->ecc.layout = &s3c_nand_oob_64_8bit;
    nand->ecc.hwctl = s3c_nand_enable_hwecc_8bit;
    nand->ecc.calculate = s3c_nand_calculate_ecc_8bit;
    nand->ecc.correct = s3c_nand_correct_data_8bit;
    nand->ecc.size = 512;
    nand->ecc.bytes = 13;
    nand->options |= NAND_NO_SUBPAGE_WRITE;
#endif

....


7. kernel也要关闭8 bit hw ecc

差不多完成以上几步后, 用u-boot烧写rootfs_android.img就与superboot完全一致了。
android系统也就可以跑了。

你可能感兴趣的:(c,android,struct,cmd,layout,buffer)