Chinaunix首页 | 论坛 | 博客
  • 博客访问: 444495
  • 博文数量: 72
  • 博客积分: 3186
  • 博客等级: 中校
  • 技术积分: 1039
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-07 16:53
文章分类

全部博文(72)

文章存档

2012年(1)

2011年(5)

2010年(10)

2009年(56)

我的朋友

分类: 嵌入式

2009-10-23 14:18:00

   经过昨晚的调试,vivi终于能够将内核引导起来了。回想最近一段时间内的源码阅读和调试过程,确实让自己收获良多。学习是需要多动手实践的,阅读、理解源代码也非常需要对其进行调试,这样才能更深入的理解。

  vivi中比较繁琐的就是对nand的操作。其中包括nandflash控制器的操作(this)、mtd层的构建、bon分区、load命令(写入flash)等。
   其中bon分驱和mtd分区的区别困扰了我很久(直到现在)。这里从其代码上实现的功能来分析总结。

1. bon分区,是由bon这个命令实现的。
举个例子: bon part 0 192k 1M:m
这个命令就表示将nand分为三个分区:0~192k, 192k~1M, 1M~end.
其中需要注意,最后一个分区里,我们加上了一个标志'm'。
那么当我们输入这行命令之后,实际对nand做了哪些工作呢?

(1). bon_partition_t parts[] 这个数组里,每个成员就记录了一个分区的信息。这些信息包括:
typedef struct {
      ulong offset; //分区起始地址
      ulong size; //分区大小
      ulong flag; //分区标志 1:MTD, 0:BON
      ulong num_bad_block; //分区坏块数
      unsigned short *bad_blocks; //分区中各坏块数的位置
} bon_partition_t;

最后,统计好各分区的这些信息之后,再把它们统一存储到nandflash的某个位置保存起来。代码里可以看到,将最后一个分区的最后一个block留出来存储这些信息。
上面,flag用1和0来表示MTD分区和BON分区。最后存入nand之后,在vivi里便再也没有用到这个标志位了。

2. vivi里再次用到“分区”这个概念就只有在load命令里了。
例如: load flash vivi x
这个命令的意思就是通过xmodem下载vivi并写入到flash的vivi分区里。这里所谓的vivi分区实际上是从params里面取得vivi的在nandflash中存储起始地址和大小(即表示这一段区域只能存放vivi代码)。然后就将vivi烧到nand的那个位置就可以了。对于kernel和root都是一样的。

mtd_partition_t
default_mtd_partitions[] = {
        {
            name:         "vivi",
            offset:       0,
            size:         0x00020000,
            flag:         0
        }, {
            name:         "param",
            offset:       0x00020000,
            size:         0x00010000,
            flag:         0
        }, {
            name:         "kernel",
            offset:       0x00030000,
            size:         0x000c0000,
            flag:         0
        }, {
            name:         "root",
            offset:       0x00100000,
            size:         0x00140000,
            flag:         MF_BONFS
        }
};
从上面这些信息可以看到,分区不过是在nand的地址范围内定义了一些区间而已。那么最后一个分区上可以看到MF_BONFS这个标志。
这个标志只用在vivi里,代码里可以看到它一直都没有存储到nand里,也就不能为kernel所用。这个标志会在load命令里被获取,其带来的影响在write_to_nand,如下:

        if (!(flag & MF_BONFS)) {//前两分区要先擦,而root会在检查坏块时擦除(is_bad_block)
                printk("Erasing... ", instr.addr, instr.addr + instr.len);
                ret = mtd->erase(mtd, &instr);
                if (ret) {
                        printk(" ... failed\n");
                        return ret;
                }
                printk(" ... done\n");
        }
        printk("Writing... ");
        retlen = 0;
        if (flag & MF_BONFS) {
                read_bon_partition(mtd);

                //write_bon_image写入时会做坏块的处理(跳过坏块)
                ret = write_bon_image(mtd, (ulong)ofs, (char *)buf, (long)len);
                retlen = len;
        } else

                //直接写入
                ret = mtd->write(mtd, ofs, len, &retlen, buf)



3. 至于mtd分区,还不理解。

ps:虽然现在内核被引导起来了,但是2.4.18的内核,而且那个zImage也不是自己做的。现在vivi向内核传递参数还是以param_struc的方式,如果是2.6的内核的话,看到许多文章都说需要tag list 方式。这个还不会。另外,vivi的烧写功能很差,xmodem速度慢且不稳定。未来可以考虑分析下uboot,将其的tftp烧写功能拿过来。
阅读(1578) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~