上一篇文章,我们从0制作jffs2文件系统,因为我们的内核本身就支持iffs2文件系统,但是它不支持yaffs文件系统。今天我们就来修改内核代码,让内核支持yaffs文件系统的格式。


1.首先我们获取yaffs源码

我是通过git获得,当然源码获得的途径很多,需要源码的可以加我最底下的联系方式。
在Linux系统中,输入:
git clone git://www.aleph1.co.uk/yaffs2
获取到源码,将源码放到的/work/system/yaffs目录下,然后解压。

当你拿到任何一个源码,不管是什么源码,里面都会有类似README这样的文档,我们第一个需要看的文档就是这个文档,文档里会教我们接下来该如何做,那么我看过文档后,就知道该如何做了:


2.首先给内核打补丁:
进入到yaffs源码目录:
cd /work/system/yaffs/yaffs2
使用下面的命令进行打补丁:
./patch-ker.sh c m /work/system/linux-3.4.2 (注意后面是我的内核源码的目录)
打完补丁后,就会在内核的/fs/yaffs2目录下加入了我们yaffs的源码


3.配置内核支持YAFFS:
输入:
make menuconfig
依次选择:

File systems  ---> 
     Miscellaneous filesystems  ---> 
        <*>   yaffs2 file system support 

然后保存配置。重新编译内核:
make uImage
编译没有通过,如下:

遇到错误不要怕,一个一个解决,我们先把fs/yaffs2里面的源码都加到我们windows系统里的linux内核的source insight源码里,去看yaffs源码。下面我们一个一个解决错误。

首先是这个错误:fs/yaffs2/yaffs_vfs.c:2514: error: ‘struct mtd_info’ has no member named ‘sync’
错误显示mtd这个结构体没有sync这个成员:

    if (mtd->sync)
        mtd->sync(mtd);

去看这个结构体中看发现有这个成员:void (*_sync) (struct mtd_info *mtd);,只不过前面加了一个下划线,我们把下划线加上:

    if (mtd->_sync)
        mtd->_sync(mtd);

然后重新编译内核,还是有一大堆错误,但是刚才那个错误已经没有了,现在的错误为:
fs/yaffs2/yaffs_vfs.c:2702: error: ‘struct mtd_info’ has no member named ‘erase’

通过刚才那个错误,我们知道,这些成员前面都应该有下划线,而我们的错误里的成员,都没有加下划线,下面我们把下划线都加上。
然后重新编译,又发现了一些没有定义的成员,还是没有加下划线,我们一一给加上,然后重新编译:

好了,现在的错误就不是那个下划线的问题了。

现在的第一个错误:fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function ‘d_alloc_root’
没有定义d_alloc_root这个函数,可能是新内核里把这个函数给去掉了或者改了,通过搜索关键字s_root得知是改成这个函数了:d_make_root(inode),我们把它换了:

root = d_make_root(inode);

重新编译内核:

显示的错误为:fs/yaffs2/yaffs_mtdif.c:42: error: ‘struct mtd_info’ has no member named ‘erase’
还是那个结构体成员的下滑线的问题,加上下划线。然后重新编译内核,发现显示的错误还是那个结构体下划线的问题,这个我就直接改,不放图了。改完后再重新编译,出现的关于那个结构体的错误,一一改掉就行。最后编译终于成功了!!!


4制作yaffs文件系统系统映像
之前我们已经做好了文件系统,现在来制作yaffs文件系统映像:
mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2


5.烧写YAFFS文件系统映像
在uboot中:
nfs 30000000 192.168.1.101:/work/nfs_root/fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 $filesize


6.烧写新内核启动
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
nfs 32000000 192.168.1.101:/work/nfs_root/uImage_yaffs
bootm 32000000
发现启动不了。

要么是uboot有问题,要么是yffas文件系统有问题。通过重新烧写老的uboot,发现可以正常启动,所以现在的问题应该是新的uboot的问题,看来是之前移植的uboot没有移植好。那么我们只能看一下uboot源码了。

我们移植的新UBOOT有BUG:
drivers\mtd\nand\Nand_util.c

    if (!need_skip && !(flags & WITH_DROP_FFS)) {
改为
    if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {

然后重新烧写uboot,文件系统,内核,启动一切正常,完毕!!!

7.制作内核补丁
最后我们将移植好的内核,生成补丁,方便以后的使用:
cp .config config_ok
make distclean
mv linux-3.4.2 linux-3.4.2_100ask
tar xjf linux-3.4.2.tar.bz2
diff -urN linux-3.4.2 linux-3.4.2_100ask > linux-3.4.2_100ask.patch

8.如何打补丁:
patch -p1 < ../linux-3.4.2_100ask.patch
cp config_ok .config
make uImage

9.重烧整个系统
我们的uboot,内核,文件系统,都做好了,下面重新烧写整个系统,走一下流程:

使用jtag工具烧u-boot_new.bin
或使用uboot来更新自己: tftp 30000000 u-boot_new.bin; nand erase.part u-boot; nand write 30000000 u-boot
启动uboot,用它来烧写内核(内核变小后,就烧写到NAND里面了,现在启动的地址是30000000,以前是32000000)、FS
tftp 30000000 uImage_new; nand erase.part kernel; nand write 30000000 kernel
tftp 30000000 fs_mini_mdev_new.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000 $filesize
或者使用nfs,相关命令上面都有。

设置参数
set ‘nand read 30000000 kernel;bootm 30000000’
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
set machid 16a
save

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。