.
.
.
.
.
每次尝试手动升级最新的 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详细解析【转】