Ubuntu 18.04 编译安装 kernel 5.5.4 之后修复 vmware 网络驱动

.

.

.

.

.

每次尝试手动升级最新的 kernel 之后,vmware 都会罢工,这是在意料之内的事情,本次也不例外。

内核升级的步骤本文不再赘述,文章末尾有相关链接。楼主曾经的博文也写过,过程都差不多,可以进行参考。

本文主要记录的是 kernel 5.5.4 网络子系统的相关数据结构发生变更后如何修复 vmware 网络驱动。

vmware 的驱动源码保存在 /usr/lib/vmware/modules/source 目录下,网卡驱动的源码在 vmnet.tar 文件中。
修改驱动的大致步骤就是:
1)解压缩 vmnet.tar;
2)根据 log 中的错误,修改报错的代码;
3)备份原来的压缩包(mv vmnet.tar vmnet_bak.tar);
4)重新打包(tar cvf vmnet.tar vmnet-only);
5)启动 vmware 重新编译,若出错,根据 log 重复 2、4、5 步骤;

根据日志 /tmp/vmware-[USER]/vmware-17220.log 中显示的错误,修改相应的文件。
这次报错是由于 kernel  中的 skb_frag_t 结构体的定义发生了变化,原来的定义是这样的:

typedef struct skb_frag_struct skb_frag_t;

struct skb_frag_struct {
        struct page *page; // 对应 bv_page
        __u16 page_offset; // 对应 bv_offset
        __u16 size;        // 对应 bv_len
};

 kernel 5.5 的定义变成了这样:

typedef struct bio_vec skb_frag_t;

struct bio_vec {
        struct page     *bv_page;                                                                              
        unsigned int    bv_len;
        unsigned int    bv_offset;
};

 因此,要修改 userif.c 文件的两个地方:

>$ sudo vim vmnet-only/userif.c
// page 结构体也发生了变化,不需要取成员p了,直接传入 page 指针就行了;
// 所以把原来的宏定义注释掉,或者修改 COMPAT_LINUX_VERSION_CHECK_LT 这个宏的版本号也行;
# if 0
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
#   define compat_kmap(page) kmap(page)
#   define compat_kunmap(page) kunmap(page)
#else
#   define compat_kmap(page) kmap((page).p)
#   define compat_kunmap(page) kunmap((page).p)
#endif
#else
#   define compat_kmap(page) kmap(page)
#   define compat_kunmap(page) kunmap(page)
#endif

// 在 VNetCsumCopyDatagram() 函数中,修改 frag 的成员
// 修改前:
      if (frag->size > 0) {
     unsigned int tmpCsum;
     const void *vaddr;

     vaddr = compat_kmap(frag->page);
     tmpCsum = csum_and_copy_to_user(vaddr + frag->page_offset,
                     curr, frag->size, 0, &err);
     compat_kunmap(frag->page);

     if (err) {
        return err;
     }
     csum = csum_block_add(csum, tmpCsum, curr - buf);
     curr += frag->size;
      }
// 修改后
      if (frag->bv_len > 0) {
     unsigned int tmpCsum;
     const void *vaddr;

     vaddr = compat_kmap(frag->bv_page);
     tmpCsum = csum_and_copy_to_user(vaddr + frag->bv_offset,
                     curr, frag->bv_len, 0, &err);
     compat_kunmap(frag->bv_page);

     if (err) {
        return err;
     }
     csum = csum_block_add(csum, tmpCsum, curr - buf);
     curr += frag->bv_len;
      }

 改好了,祝你成功 :)


参考文献:
内核版本升级——ubuntu18.04
Ubuntu 编译安装 Linux 4.0.5 内核,并修复 vmware 网络内核模块编译错误
skb详细解析【转】

原文地址:https://www.cnblogs.com/0xcafebabe/p/12325113.html