nas-j3455kvm安装win10及集成显卡直通

缘起

之前的基于j3455搞的nas,物理机是win10系统,虚拟机ubuntu是基于hyper-v架构虚拟出来的。

然而运行一段时间后发现,win10系统总是会莫名其妙的重启,少则2天,多则一周必然会出现自动重启的问题。

网上查了些资料,有人说是显卡驱动的问题,我换了从15年到17年所有的驱动,无一例外,都会出现黑屏问题。

于是,狠下心来,反向部署了一套方案,用ubuntu来做物理机系统,kvm架构虚拟出win10来用,这样说不定还更稳定些。

折腾过程

1、新的系统以及虚拟化架构搭建

物理机我选择了ubuntu server 18.04.2,毕竟是长期支持版本,也更加稳定些。虚拟化架构我采用了qemu + kvm,虚拟机管理工具我选择了libvirt,于是,整体的架构如下:

物理硬件
ubuntu_server
kvm+qumu_libvirt
win10

ubuntu系统的安装这里就不说了,按照安装流程一步步走一下就行了。

关于虚拟化环境的搭建,主要的步骤如下:

1、开启bios里的intel虚拟化开关vt-d(j3455是支持硬件虚拟化的)

2、安装libvirt以及quemu等工具链 使用如下命令安装下虚拟化工具:

sudo apt-get install --no-install-recommends qemu-kvm qemu-utils libvirt-bin virtinst cpu-checker

然后输入kvm-ok即可验证环境是否是ok的

2、创建虚拟机并安装系统

使用virt-install安装系统,我的命令如下:

virt-install \
--name win10 \
--memory 4048 \
--vcpus sockets=1,cores=2,threads=2 \
--cdrom=/share_disk/e/cn_windows_10_multi-edition_version_1709_updated_sept_2017_x64_dvd_100090804.iso \
--os-variant=win8.1 \
--disk /home/loong/kvm/win10.qcow2,bus=virtio,size=50 \
--disk /share_disk/e/virtio-win_amd64_1.vfd,device=floppy \
--network bridge=br0,model=virtio \
--graphics vnc,password=Passw0rd,port=5910 \
--hvm \
--virt-type kvm

注意:
1、j3455由于不支持win7系统,如果虚拟机安装win10以下系统的话,显卡驱动会安装不上

2、win10系统不自带virt的io虚拟化驱动,需要自行下载virtio-win_amd64_1.vfd,这个可以在开源网站上找到

3、由于我们需要一个局域网的地址给到虚拟机,因此需要创建一个和物理机桥接的网卡,比如这里是br0

4、在命令行里安装虚拟机,由于没有显示界面,需要映射下vnc的端口,比如这里映射到本机

使用如下命令映射服务器的ip到本地

ssh -L 5910:127.0.0.1:5910 server_ip

然后使用vnc命令链接5910端口,即可看到系统安装界面,以后的系统启动后的显示也可以这样看到(当然也可以开启windows的远程桌面,这样更加方便)

vnc://127.0.0.1:5910

如上步骤,vnc链接到系统安装过程后,就是常规的系统安装操作了,安装完成后自动重启系统后进入桌面。

3、j3455显卡直通配置

由于j3455在intel cpu系列中属于非常低端的系列,平台也没有安装其他的显卡,直通显卡就显得非常的麻烦了,通用的pci直通显卡到虚拟机没有那么好操作。
好在j3455是intel超低功耗cpu中第一个支持vt-d虚拟化技术的,这样的话显卡直通成为可能。

经过网上N多教程的查找,发现对于intel的处理器的显卡直通,主要有2个方案:

3.1 使用类似pci的方式直通集成显卡

worthdoingbadly找到了一篇关于使用intel核显进行直通的文章,使用作者提供的脚本,实测能够正常卸载宿主机的显卡,然后我们可以通过libvirt的pci配置,增加到虚拟机中。

1、在机器开机bios中,开启intel vt-d硬件加速技术

这个网上查下就好,bios中都有关于vt-d的设置

2、在gurb开机选项中,增加iommu的配置,这个是用来控制硬件直通的

sudo vi /boot/grub/grub.conf
#在默认选项中增加 intel_iommu=on 选项, 保存后退出

# 生成新的开启启动项
sudo update-grub

# 重启机器sudo reboot

3、卸载已经加载的核显驱动

    # 下载执行脚本
    wget https://worthdoingbadly.com/assets/blog/gpupassthrough/prepareIntelGPUPassthrough.sh    
    # 执行核显卸载脚本
    sudo bash prepareIntelGPUPassthrough.sh

4、在libvirt中配置虚拟机使用核显

1) 找到核显的pci设备id

virsh nodedev-list | grep pci

可以从输入中找到显卡的设备相关id,主要有两个id字段,4位16进制的字符串

2) 然后使用sudo virsh edit win10进行虚拟机的编辑,这里的win10是我虚拟机的名称。

在devices节点下增加如下的配置,其中slot和funciton是从上面的pci设备信息中获取到的

<hostdev mode='subsystem' type='pci' managed='yes'><source>
    <address domain='0x0000' bus='0x00' slot='0x1a'         function='0x7'/></source></hostdev>

使用vi的wq方式保存退出即可生效。

5、开启虚拟机验证是否有intel的核显

sudo virsh start win10

可以进入windows系统后,安装标准的intel核显驱动,如果没问题的话,就可以正常使用windows核显了,性能像物理机一样。

3.1.1 pci直通的坑

1、j3455的核显驱动不支持win7系统,否则会出现能够安装驱动,但是重启后黄色问号不能用,错误码43

其实上面第一种方案已经可以正常直通显卡了,但是由于我第一次安装的是win7虚拟机系统,导致显卡驱动一直有问题。

如果安装win10系统,则可以正常安装使用核显的。

2、显卡卸载安装到虚拟机后,宿主的显示器黑屏

这个问题还没有处理,作为nas服务器使用暂时不影响使用,等以后再查查是什么问题吧

3.2 使用intel最新的gvt技术

这种方案intel在github上有详细的操作步骤,这里就不累述了,文档见intel_gvtd,其中关键点有下面几个:

1、需要使用最新的内核,ubuntu系统自带的4.15.x内核是不带这个功能的,可以按照教程步骤编译最新stable内核

echo ""|make oldconfig

make -j8 && sudo make INSTALL_MOD_STRIP=1 modules_install && sudo make install

这里内核安装有个小坑,需要strip一下不必要的内核模块,否则内核镜像过大导致不能正常启动,见minial-kernel

2、qumu这一套,最好也使用最新版本的,否则会不配置导致问题

这个可以使用下面的脚本进行一键编译安装,非常方便。

https://github.com/doomedraven/Tools/blob/master/Virtualization/kvm-qemu.sh

3、性能问题

这种方案,是把宿主的显卡虚拟化成N个虚拟的GPU,在虚拟机中使用虚拟的显卡,性能非常的差,实测基本卡的不能用,且会出现显卡的贴图错误。

drm/i915: Resetting chip after gpu hang这个错误dmsg里非常多,此时虚拟机就没反应了,因为显卡挂了。

因此这种方案被废弃,不建议使用。

4、至于这种方案在libvirt的配置,有如下两种,实测第一种可以。

方案1

 xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'<hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'>
      <source>
        <address uuid='a297db4a-f4c2-11e6-90f6-d3b88d6c9525'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </hostdev>

  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.ramfb=on'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.driver=vfio-pci-nohotplug'/>
  </qemu:commandline>

方案2:

    <qemu:arg value='-device'/>
    <qemu:arg value='vfio-pci,sysfsdev=/sys/class/mdev_bus/0000:00:02.0/a297db4a-f4c2-11e6-90f6-d3b88d6c9525,rombar=0'/>
    <qemu:arg value='-nographic'/>
  </qemu:commandline>

4、j3455直通后的hdmi/vga视频输出

最近有在这篇博文下讨论关于直通后的物理hdmi接口视频输出的问题,经过一番折腾实现了这个功能,因此在此处记录下。

4.1 关于原理

由于本次直通的是j3455的核显,在直通后主板上的hdmi接口就失效了,可能跟驱动有很大的关系,因为和独显不一样。

如果要hdmi接口输出,就得配置一些intel核显的参数才行,本次主要就设置这些东西(intel的显卡相关的东西都非常的坑)

感兴趣的可以参考下qemu项目的这篇文章 https://github.com/qemu/qemu/blob/master/docs/igd-assign.txt,我们这次就是使用了 legacy模式的操作的。

4.2 hdmi物理输出折腾过程

4.2.1 dump intel核显的bios

为什么要dump显卡bios呢?因为我们要在虚拟机里操作这个核显设备,直通时这个bios做了类似把显卡输出传递到hdmi接口这样的低级别的硬件操作,因此要做这个。

1、制作一个u盘的ubuntu18.04的安装镜像

这个网上教程非常多,不赘述了

2、设置bios里的csm支持 开机按快捷键(不同主板不一样,可以看开机屏幕提示)进入bios,在boot栏目中,选择csm支持,选择enable,然后下面的子项都选择legacy onlyf10保存后退出

3、u盘启动,进入ubuntu18.04的live模式(试一试)

4、打开ubuntu live系统的命令行工具,输入如下命令行进行dump

    sudo chmod 777 /sys/bus/pci/devices/0000:00/0000:00:02.0/rom
    sudo echo 1 > /sys/bus/pci/devices/0000:00/0000:00:02.0/rom
    sudo cat /sys/bus/pci/devices/0000:00/0000:00:02.0/rom > ~/vbios.rom
    sudo echo 0 > /sys/bus/pci/devices/0000:00/0000:00:02.0/rom

5、记得把家目录的vbios.rom 拷贝到u盘里在重启电脑,不然重启就没了

6、正常启动电脑,使用rom-parser设置下vgarom编号

./rom-parser ~/vbios.rom

# 8086这一步选择N,我们不修改这个

# 第二部选择Y,然后输入5a85,这个是和主板上显卡的编号,其他gpu的话自行查找,和下面vfio步骤里一样的

7、拷贝到系统认可的rom存放位置/usr/share/qemu/,这个是ubuntu上的apparmor安全限制,其他系统可能不需要。

sudo cp ~/vbios.rom /usr/share/qemu/

4.2.2 设置一些vfio的设置项

1、设置grub,禁止使用显卡

sudo vi /etc/default/grub
# 设置启动参数,增加iommu和efifb,如果有其他参数,我们往后追加就好,记得每个参数加空格

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on video=efifb:off,vesafb:off"

# vi保存退出

# 更新grub启动项

sudo update-grub

2、设置vfio module

sudo vi /etc/modules

# 增加如下几行
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

3、设置显卡的黑名单

这一步的作用是设置黑名单,让系统启动时不加载显卡驱动,因为我们后面要把显卡给虚拟机的。

sudo vi /etc/modprobe.d/blacklist.conf

# 增加如下几行
blacklist snd_hda_intel
blacklist snd_soc_skl
blacklist snd_hda_codec_hdmi
blacklist i915

# 如果echo不了,可以使用vi编辑
# 如果是其他gpu的话,可以lspci -n -s查看

sudo echo "options vfio-pci ids=8086:5a85,8086:5a98" > /etc/modprobe.d/vfio.conf

# 更新启动项参数

sudo update-initramfs -u
# 如果这一步提示少驱动,可以去qemu的仓库下载下

4、设置额外参数

# 如果echo不了,可以使用vi编辑

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf
echo "options kvm ignore_msrs=1" > /etc/modprobe.d/kvm.conf

5、重启电脑

4.2.3 设置libvirt虚拟机

使用virsh edit win10编辑虚拟机配置,有如下几个地方需要修改

1、修改直通显卡hostdev的配置(devices节点下面的),增加romfile的配置

 <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
      </source>
            <rom file='/usr/share/qemu/vbios.rom'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </hostdev>

注意:想要进入上文说的legacy模式(物理输出视频),必须设置显卡设备在虚拟机的02地址上,其他地址上不能物理输出视频。

2、增加igd的一些qemu参数

由于intel默认支持的是通过远程连接使用虚拟机的方式(按照前面接近一年的使用,这种方式非常稳定),我们需要额外的qemu设置才行,libvirt还不支持这种使用(可能是因为不稳定吧)。

1)在libvirt xml的第一行增加qemu的参数声明

# <domain type='kvm'>改成下面一行

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

2)增加qemu参数,在最后一行</domain>的上一行

  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.x-igd-gms=1'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.x-vga=on'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
  </qemu:commandline>

4.2.4 运行虚拟机查看是否成功

virsh start win10

如果不出意外的话,显示器上应该有视频输出了(我测试的hdmi接口),可以再直通键盘和鼠标进去操作。

4.3 hdmi视频输出直通的坑

上面也说了,libvirt以及intel默认支持的,都是物理hdmi接口不输出视频,远程访问的形式,也是我上一章的配置做的,总体上非常稳定。

但是我们这种legacy的使用方式,相当于从底层显卡bios,到视频物理hdmi输出,都从虚拟机饶了一圈,总体上很不稳定。

我经过测试,虚拟机内win10不同版本的系统、intel显卡驱动,都会影响直通的效果。

中途各种驱动版本上遇到绿屏错误,卡死错误,memory manage蓝屏崩溃等等问题,目前是进入系统前都可以,输入登录密码进入桌面时,必然是蓝屏崩溃,还没有解决。

5、总结

上面的折腾过程,看似没几步,其实是花了有好几个星期折腾的成果,过程中真的是非常的煎熬,哪哪都不能用。。。

最终的方案,就是第一种卸载后pci方式的挂载,效果非常好且运行非常的稳定,建议大家如果折腾的话采用这一种方案。

其余的,关于kvm虚拟化,可能就是折腾下图形化的管理界面以及虚拟机动态的内存伸缩控制了吧。这两个不是强需求,因为没有那么多的虚拟机需要管理,暂时就不折腾了,等有时间再搞吧。


补充关于j3455直通hdmi显示的问题,感觉这块intel做的太辣鸡了,里边的坑实在是太多,我也不会进一步的折腾了,需求不强烈,且真的坑大~~~

看看下面这一大坨的参考资料,就知道这块的折腾是有多费劲,so Intel f**k you!!!

参考资源

https://worthdoingbadly.com/gpupassthrough/

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/virtualization/chap-virtualization-pci_passthrough

https://serverfault.com/questions/633183/how-do-i-enable-kvm-device-passthrough-in-linux

https://tommy.net.cn/2017/01/06/install-windows-under-ubuntu-and-kvm/

https://scottlinux.com/2016/08/28/gpu-passthrough-with-kvm-and-debian-linux/

https://github.com/intel/gvt-linux/wiki/GVTd_Setup_Guide

https://askubuntu.com/questions/971126/17-10-netplan-config-with-bridge

https://blog.bepbep.co/posts/gvt/

https://unix.stackexchange.com/questions/270390/how-to-reduce-the-size-of-the-initrd-when-compiling-your-kernel

https://www.zcfy.cc/article/how-to-install-and-configure-kvm-on-ubuntu-18-04-lts-server

https://github.com/doomedraven/Tools/blob/master/Virtualization/kvm-qemu.sh

https://www.bilibili.com/read/cv3038211/

https://forums.unraid.net/topic/60107-solved-635-passing-through-intel-igd-with-win10-abnormally-high-mem-usage/

https://unix.stackexchange.com/questions/235414/libvirt-how-to-pass-qemu-command-line-args/317988

https://askubuntu.com/questions/985854/gpu-passthrough-problem-on-adding-dumped-rom

https://forum.proxmox.com/threads/guide-intel-intergrated-graphic-passthrough.30451/

https://wp.gxnas.com/4245.html

https://avdv.github.io/libvirt/formatdomain.html

https://askubuntu.com/questions/832524/possible-missing-frmware-lib-firmware-i915

https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915

https://forum.proxmox.com/threads/kaby-lake-igd-passthrough-on-proxmox-5-1-with-win10-vm.38125/

https://github.com/qemu/qemu/blob/master/docs/igd-assign.txt

https://www.redhat.com/archives/vfio-users/2018-April/msg00008.html

https://www.redhat.com/archives/vfio-users/2017-October/msg00007.html

https://forum.level1techs.com/t/gpu-passthrough-vfio-blue-screen/132808/3


已有11位网友发表了看法:

1Lpxl 2020-03-04 18:43:40 回复
请问这方法用在proxmox ve 下直通显卡给win10虚拟机能正常安装上显卡驱动吗?
1L访客 2020-03-07 15:39:27 回复
@pxl 应该也是可以的,原理类似的
2L访客 2020-06-05 18:54:13 回复
大佬,我按您的教程,在J4105上面安装成功了Win10,在Win10操作系统中已经看到了这个UHD600的显卡,驱动正常运行,显示可以看到2个(一个是VNC,一个是UHD600),但HDMI无输出(宿主机开机时是有输出的)。没有VGA线来看看VGA是否输出。
不知道您的是HDMI输出还是VGA输出呢?看到显卡但没有输出是因为那里弄错了呢?求救!
2L访客 2020-06-06 14:52:52 回复
@访客 这种用法,物理的hdmi或者vga是肯定没有输出的,原因如下:
1、这种使用方法,是把物理机的显卡(即UHD600)虚拟化给了虚拟机win10,相当于物理机就没有显卡了,所以物理机不会有任何显示器输出的,相当于一个没有显卡的linux
2、此时虚拟机win10有了物理显卡,可以进行各种高性能的显卡运算,但是是没办法输出到物理设备,需要用其他电脑远程连接或者vnc连接使用才能看到win10的画面
2L访客 2020-06-07 14:01:34 回复
@访客 不是吧。看了好多教程,好像他们是可以有HDMI或者VGA输出的哦?不然直通的意义就不大了。
物理机(宿主机)没有输出我理解,它没有显卡了,但Guest机器(win10)获得这个显卡了,理论上不是可以直接win10的界面输出到HDMI或者VGA吗?
参考:https://www.bilibili.com/read/cv3038211/
2Lroot 2020-06-07 23:26:03 回复
@访客 这块我没有研究了,因为我的使用场景是:直通了核显的win10虚拟机,只要挂载后台就好,我使用远程桌面偶尔连接上去就可以
兄弟要是有啥研究进展也可以同步我一下不?
我看了你说的帖子,看起来是pci直通的,还设置了vga rom,关键点应该在vga rom的设置上
2Lroot 2020-06-07 23:55:02 回复
@访客 https://passthroughpo.st/explaining-csm-efifboff-setting-boot-gpu-manually/ 在配置里加个romfile试试呢
3L访客 2020-06-08 02:13:20 回复
添加过ROMFILE,我是从PVE的论坛找了一个J4105的,加上去不会报错,但不知道有没有装载成功。不过画面依然没有出来。怀疑有几个点没做对:
1、ROMFILE虽然下载的是J4105的,但不知道跟我的主板型号是否一致,可能还是需要自己去dump一个自己主板的。
2、教程中说PVE中要设置bios和machine分别为:seabios和i440fx,但在KVM的配置中不知道哪里对应着。
3、教程中说qemu的启动参数要添加:args: -device vfio-pci,host=00:02.0,addr=0x02,x-igd-gms=1,romfile=HD600.bin,我只能添加了romfile,但x-igd-gms=1不知道哪里对应添加。
对KVM不是太熟悉,可能需要花时间去翻manual才行。
3L访客 2020-06-08 12:29:39 回复
@访客 留个邮箱吧,我最近也看看,如果我有进展邮件你,我的邮箱he110w0r1d1413@gmail.com
3L访客 2020-06-09 17:32:49 回复
@访客 给您发邮件了,不知道收到没,有没有跑到垃圾箱里去了。:)
3L访客 2020-06-11 01:12:50 回复
@访客 收到了,最近我也在尝试了

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。