在Deepin 20系统中升级到了Linux 5.10内核,但是Virtualbox不能正常使用,当前VirtualBox 6.1.16及以下版本应该还没有支持Linux 5.10内核或以上版本(参考:虚拟机VirtualBox 6.1.16发布下载:支持Linux 5.9内核),由于有一些软件必需要在虚拟机中运行,所以就不等Virtualbox的补丁了,直接动手解决问题。
解决办法 请前往以下链接: https://www.virtualbox.org/attachment/ticket/20055/linux-5.10-r0drv-memobj-fix-r0.patch 这是一个补丁,我们需要做的就是修改src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c,这个补丁修复了编译内核模块及在Linux 5.10上运行的问题,代码中的红色表示删除掉,绿色为添加的,修改后运行sudo /sbin/vboxconfig就可以了。 1]、以下是修改memobj-r0drv-linux.c的方法: 该文件的位置在usr/share/virtualbox/src/vboxhost/vboxdrv/r0drv/linux/memobj-r0drv-linux.c,建议先备份好文件,然后运行sudo dedit /usr/share/virtualbox/src/vboxhost/vboxdrv/r0drv/linux/memobj-r0drv-linux.c,打开该文件后进行修改并保存修改过的文件即可。 注:经过修改后通常都不报错了,能正常的运行。 2]、memobj-r0drv-linux.c文件图示:
3]、文件代码如下,供参考: * Whether we use alloc_vm_area (3.2+) for executable memory. * This is a must for 5.8+, but we enable it all the way back to 3.2.x for * better W^R compliance (fExecutable flag). */ #if RTLNX_VER_RANGE(3,2,0, 5,10,0) || defined(DOXYGEN_RUNNING) # define IPRT_USE_ALLOC_VM_AREA_FOR_EXEC #endif #if RTLNX_VER_MIN(5,10,0) || defined(DOXYGEN_RUNNING) # define IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC #endif /* * 2.6.29+ kernels don't work with remap_pfn_range() anymore because } #ifdef IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC /** * User data passed to the apply_to_page_range() callback. */ typedef struct LNXAPPLYPGRANGE { /** Pointer to the memory object. */ PRTR0MEMOBJLNX pMemLnx; /** The page protection flags to apply. */ pgprot_t fPg; } LNXAPPLYPGRANGE; /** Pointer to the user data. */ typedef LNXAPPLYPGRANGE *PLNXAPPLYPGRANGE; /** Pointer to the const user data. */ typedef const LNXAPPLYPGRANGE *PCLNXAPPLYPGRANGE; /** * Callback called in apply_to_page_range(). * * @returns Linux status code. * @param pPte Pointer to the page table entry for the given address. * @param uAddr The address to apply the new protection to. * @param pvUser The opaque user data. */ static DECLCALLBACK(int) rtR0MemObjLinuxApplyPageRange(pte_t *pPte, unsigned long uAddr, void *pvUser) { PCLNXAPPLYPGRANGE pArgs = (PCLNXAPPLYPGRANGE)pvUser; PRTR0MEMOBJLNX pMemLnx = pArgs->pMemLnx; uint32_t idxPg = (uAddr - (unsigned long)pMemLnx->Core.pv) >> PAGE_SHIFT; set_pte(pPte, mk_pte(pMemLnx->apPages[idxPg], pArgs->fPg)); return 0; } #endif /** * Maps the allocation into ring-0. * * This will update the RTR0MEMOBJLNX::Core.pv and RTR0MEMOBJ::fMappedToRing0 members. else # endif { # if defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) if (fExecutable) pgprot_val(fPg) |= _PAGE_NX; /* Uses RTR0MemObjProtect to clear NX when memory ready, W^X fashion. */ # endif # ifdef VM_MAP pMemLnx->Core.pv = vmap(&pMemLnx->apPages[0], pMemLnx->cPages, VM_MAP, fPg); # else preempt_enable(); return VINF_SUCCESS; } # elif defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem; if ( pMemLnx->fExecutable && pMemLnx->fMappedToRing0) { LNXAPPLYPGRANGE Args; Args.pMemLnx = pMemLnx; Args.fPg = rtR0MemObjLinuxConvertProt(fProt, true /*fKernel*/); int rcLnx = apply_to_page_range(current->active_mm, (unsigned long)pMemLnx->Core.pv + offSub, cbSub, rtR0MemObjLinuxApplyPageRange, (void *)&Args); if (rcLnx) return VERR_NOT_SUPPORTED; return VINF_SUCCESS; } # endif NOREF(pMem);
注意 如果你使用的VirtualBox版本是6.1.16或以下,请按上面的要求修改文件,如果使用的是更高版本,那么VirtualBox必然已修复了对Linux 5.10兼容的问题,请不需要修改了。
相关主题 |