• 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详细解析【转】

  • 相关阅读:
    GLSL预定义变量
    GLSL 内建函数
    GLSL语言基础
    svn:revert to this version 和 revert changes from this version的区别
    win7下搭建opengles2.0编程环境
    iconv字符编码转换
    矩阵-DirectX与OpenGL的不同
    NHibernate分页
    Web网站压力测试工具
    winform系统自动登录实现
  • 原文地址:https://www.cnblogs.com/0xcafebabe/p/12325113.html
Copyright © 2020-2023  润新知