YAFFS2移植Linux2.6.39.2 成功(2)

根据自己的仔细分析,原来是新版的LINUX2.6.39.2文件系统发生变化,通过代码定位,

在LINUX2.6.39.2/includde/linux/fs.h上发现了一丝端倪,原来在新版的linux2.6.39.2里面,由于VFS发生变化,对于get_sb 以及get_sb_bdev这两个变量均为使用,

struct file_system_type {
 const char *name;
 int fs_flags;
 struct dentry *(*mount) (struct file_system_type *, int,
         const char *, void *);
 void (*kill_sb) (struct super_block *);

。。。。。。

},在file_system_type这个结构体中我们根本就找不到  get_sb这个变量

通过对比linux2.6.36内核里面的fs.h,

struct file_system_type {
 const char *name;
 int fs_flags;
 int (*get_sb) (struct file_system_type *, int,
         const char *, void *, struct vfsmount *);
 void (*kill_sb) (struct super_block *);
 struct module *owner;

............

}

发现在结构体file_system_type是有get_sb这个变量定义的,

而在yaffs_vfs.c里面有两处是需要这个变量的,

第一处:

static struct file_system_type yaffs_fs_type = {
 .owner = THIS_MODULE,
 .name = "yaffs",
 .get_sb = yaffs_read_super,
 .kill_sb = kill_block_super,
 .fs_flags = FS_REQUIRES_DEV,
};

第二处:

static struct file_system_type yaffs2_fs_type = {
 .owner = THIS_MODULE,
 .name = "yaffs2",
 .get_sb = yaffs2_read_super,
 .kill_sb = kill_block_super,
 .fs_flags = FS_REQUIRES_DEV,
};  所以,我们需要更改yaffs_vfs.c里面的get_sb这个变量满足LINUX2.6.39.2的要求,通过比对,不难发现,其实LINUX2.6.39.2的fs.h里面的

struct dentry *(*mount) (struct file_system_type *, int,
         const char *, void *);这个函数与

int (*get_sb) (struct file_system_type *, int,
         const char *, void *, struct vfsmount *);很相似,

于是 直接修改yaffs_vfs.c的

static struct file_system_type yaffs_fs_type

以及static struct file_system_type yaffs2_fs_type

两个结构体的get_sb变量,分别为:

.mount = yaffs_read_super,

.mount = yaffs2_read_super, 同理,对比,发现,用mount_bdev函数变量代替get_sb_bdev函数变量

return mount_bdev(fs, flags, dev_name, data,
      yaffs_internal_read_super_mtd);

return mount_bdev(fs, flags, dev_name, data,
      yaffs2_internal_read_super_mtd);

第三步:

由于mount这个结构体函数少了struct vfsmount 这个参数,因此,我们还需要更改yaffs_vfs.c的两个位置,

通过阅读源代码不难发现

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
      int silent)
{
 return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
}
/*
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
static int yaffs_read_super(struct file_system_type *fs,
       int flags, const char *dev_name,
       void *data, struct vfsmount *mnt)
{

 return get_sb_bdev(fs, flags, dev_name, data,
      yaffs_internal_read_super_mtd, mnt);
}
#else
static struct super_block *yaffs_read_super(struct file_system_type *fs,
         int flags, const char *dev_name,
         void *data)
{

 return get_sb_bdev(fs, flags, dev_name, data,
      yaffs_internal_read_super_mtd);
}
#endif
*/

static struct super_block *yaffs_read_super(struct file_system_type *fs,
         int flags, const char *dev_name,
         void *data)
{

  return mount_bdev(fs, flags, dev_name, data,
      yaffs_internal_read_super_mtd);
}

static struct file_system_type yaffs_fs_type = {
 .owner = THIS_MODULE,
 .name = "yaffs",
 //.get_sb = yaffs_read_super,
 .mount = yaffs_read_super,
 .kill_sb = kill_block_super,
 .fs_flags = FS_REQUIRES_DEV,
};
#else
static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
         int silent)
{
 return yaffs_internal_read_super(1, sb, data, silent);
}

static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
        FS_REQUIRES_DEV);
#endif


在这段代码中,我发现,当LINXU内核版本大于2.6.17时与大于2.5.0而小于2.6.17时,采用的yaffs_read_super函数不一样,参数个数不同,而且类型也有所不同,一个是整形,一个是结构体,于是修改代码,红色为删掉不要的,蓝色为更改的,同理,第二处YAFFS2修改方法原理同上:直接贴出

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
       int silent)
{
 return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
}
/*
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
static int yaffs2_read_super(struct file_system_type *fs,
        int flags, const char *dev_name, void *data,
        struct vfsmount *mnt)
{
 return get_sb_bdev(fs, flags, dev_name, data,
      yaffs2_internal_read_super_mtd, mnt);
}
#else
static struct super_block *yaffs2_read_super(struct file_system_type *fs,
          int flags, const char *dev_name,
          void *data)
{

 return get_sb_bdev(fs, flags, dev_name, data,
      yaffs2_internal_read_super_mtd);
}
#endif
*/
static struct super_block *yaffs2_read_super(struct file_system_type *fs,
          int flags, const char *dev_name,
          void *data)
{

 return mount_bdev(fs, flags, dev_name, data,
      yaffs2_internal_read_super_mtd);
}
static struct file_system_type yaffs2_fs_type = {
 .owner = THIS_MODULE,
 .name = "yaffs2",
 //.get_sb = yaffs2_read_super,
 .mount = yaffs2_read_super,
 .kill_sb = kill_block_super,
 .fs_flags = FS_REQUIRES_DEV,
};
#else
static struct super_block *yaffs2_read_super(struct super_block *sb,
          void *data, int silent)
{
 return yaffs_internal_read_super(2, sb, data, silent);
}

static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
        FS_REQUIRES_DEV);
#endif     好了,经过这3步修改之后,编译通过,当然,还是会有告警信息打印,很正常,因为原来的get_sb_bdev函数是一个 INT型,而mount_bdev函数是一个 STRUCT结构体型,导致RETURN 指针类型不符的告警,无大碍。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjzsg.html