linux:kylinV10sp3:安装virtualbox 7.1.16 报错解决
##################################################################################
错误原因分析
这个编译错误是由于内核版本升级导致 access_ok()函数的接口发生了变化。错误信息明确指出:代码试图向 access_ok宏传递3个参数,但新版本的内核只接受2个参数。
在较旧的内核版本(例如你正在编译的驱动代码所基于的版本)中,access_ok()函数的原型通常是:
access_ok(int type, const void __user *addr, unsigned long size);
type:用于指定访问类型,例如 VERIFY_READ或 VERIFY_WRITE
。
addr:要检查的用户空间地址指针。
size:要检查的字节数。
然而,在较新的Linux内核中(具体变更时间点因内核版本而异),这个函数被简化为只接受两个参数
: access_ok(const void __user *addr, unsigned long size);
第一个参数 type被移除了。
====================================================================================
vi /opt/VirtualBox/src/vboxhost/vboxdrv/r0drv/linux/memuserkernel-r0drv-linux.c
====================================================================================
定位错误代码:
找到文件中的第82行附近的代码,它应该类似于:
bool fRc = access_ok(VERIFY_READ, (void *)R3Ptr, 1);
修改代码:
删除第一个参数(VERIFY_READ),将调用改为:
bool fRc = access_ok((void *)R3Ptr, 1);
根据
和
的解决方案,直接移除第一个参数即可。在某些架构或内核版本中,可能需要确保地址参数的类型是 void __user *,你的代码中已经做了强制转换,所以通常是正确的。
##################################################################################
错误分析
从错误信息可以看出,问题出现在/tmp/vbox.0/linux/VBoxNetFlt-linux.c文件的第970-987行。代码试图访问skb_frag_t结构体的size和page_offset成员,但新版本内核中这些成员名已经发生了变化
。
内核API变更详情
在新版本Linux内核中(特别是5.5以后),skb_frag_t的定义发生了变化:
旧版本内核(修改前):
typedef struct skb_frag_struct skb_frag_t;
struct skb_frag_struct {
struct page *page;
__u16 page_offset; // 现在已改名
__u16 size; // 现在已改名
};
新版本内核(修改后):
typedef struct bio_vec skb_frag_t;
struct bio_vec {
struct page *bv_page;
unsigned int bv_len; // 对应原来的size
unsigned int bv_offset; // 对应原来的page_offset
};
====================================================================================
vi /opt/VirtualBox/src/vboxhost/vboxnetflt/linux/VBoxNetFlt-linux.c
====================================================================================
定位到第180行附近的宏定义,应该能看到类似这样的代码:
#define VBOX_SKB_FRAG_LEN(_pFrag) ((_pFrag)->size)
#define VBOX_SKB_FRAG_OFFSET(_pFrag) ((_pFrag)->page_offset)
修改这两个宏定义,将成员名更新为新版本:
#define VBOX_SKB_FRAG_LEN(_pFrag) ((_pFrag)->bv_len)
#define VBOX_SKB_FRAG_OFFSET(_pFrag) ((_pFrag)->bv_offset)
浙公网安备 33010602011771号