起因
众所周知,Linux 这么多年来一直在桌面软件这块有很大的短板,Windows/MacOS 上很多软件都没有对应的 Linux 版本,但是没有关系,这些都能通过安装虚拟机来解决。 最初我的想法是利用WinApps或者cossowary这类基于 RDP 的工具来实现在 Linux 无缝使用 Windows 下的软件,但是后来发现 NixOS 不是很适合做这种事情,因为这类工具都需要进行一些命令式 (imperative) 的操作,这和 NixOS 的声明式设计有着很大的冲突。 不过在参考这些工具的虚拟机安装方式进行安装的时候也遇到了一些小问题,于是做一下记录以免以后忘记。
注:以下所提到的一些问题都是在设备使用 virtio 模式才会遇到的,如果存储设备直接使用 SATA 模式、网卡使用 e1000e 模式的情况下不需要阅读此文。
准备
需要准备的东西有:
- Windows 镜像,我选用的是
tiny11 beta2 (no sysreq)
,ReviOS
好像也不错,据说优化做得更好,之后可能试试。当然存储容量大可以直接选官方镜像。 - virtio 驱动镜像,可以在这里找到,后缀为 iso 的就是。
- winfsp 软件,用于挂载 UNIX 文件系统。
- spice-guest-tools 软件,用于剪切板共享等功能,可选。
- 安装虚拟机相关的包,NixOS 的官方文档有点不全,我自己写的
virtualization.nix
内容如下:
{ pkgs, username, ... }:
{
virtualisation.libvirtd = {
enable = true;
qemu.runAsRoot = true;
};
programs.dconf.enable = true;
users.users.${username}.extraGroups = [ "kvm" "libvirtd" ];
environment.systemPackages = with pkgs; [
virt-manager
qemu_kvm
virtiofsd
];
# boot.extraModprobeConfig = "options kvm_intel nested=1"; # for intel cpu
boot.extraModprobeConfig = "options kvm_amd nested=1"; # for amd cpu
}
- 配置一个 samba/SMB 网络共享路径(可选,如果不设置的话可以之后在虚拟机中使用浏览器下载软件,我习惯把软件全部下载好直接进去虚拟机安装)。基本上参考 NixOS 官方 Wiki 即可,注意需要添加一下
virbr0
网卡所在的网段,可以用ip a
命令查看。此外,create mask 设置为 0744 是为了之后放在共享目录中的*.exe
文件能够直接在 Windows 虚拟机内运行。示例如下:
# Samba Server
services.samba-wsdd.enable = true; # make shares visible for windows 10 clients
networking.firewall.allowedTCPPorts = [
5357 # wsdd
];
networking.firewall.allowedUDPPorts = [
3702 # wsdd
];
# 192.168.122. is for virbr0 scope on my computer
services.samba = {
enable = true;
openFirewall = true;
securityType = "user";
extraConfig = ''
workgroup = WORKGROUP
server string = smbnix
netbios name = smbnix
security = user
#use sendfile = yes
#max protocol = smb2
# note: localhost is the ipv6 localhost ::1
hosts allow = 192.168.122. 192.168.0. 127.0.0.1 localhost
hosts deny = 0.0.0.0/0
guest account = nobody
map to guest = bad user
'';
shares = {
share = {
path = "/home/${username}/downloads";
browseable = "yes";
"read only" = "no";
"guest ok" = "yes";
"create mask" = "0744"; # +x makes *.exe runnable
"directory mask" = "0755";
"force user" = "${username}";
"force group" = "${username}";
};
};
};
虚拟机安装
准备完成之后就可以开始安装虚拟机,首先打开 virt-manager
,如果使用的是中文 Locale 的话名字叫作“虚拟系统管理器”。初次使用需要连接到 qemu:\\\system
,注意,连接到 qemu:\\\session
用户会话无法使用 virtiofs 文件夹共享,会提示 virtiofs is not yet supported in session mode
。
安装虚拟机的过程很简单就不赘述了,大体上参考 WinApps 的步骤即可。大体上需要进行配置修改的有以下几项:
- 在 XML 配置中修改
clock
部分为:
<clock offset="localtime">
<timer name="hpet" present="yes"/>
<timer name="hypervclock" present="yes"/>
</clock>
- 内存部分,启用
Enable shared memory
,降低 current allocation 至 1024 即可。 - 引导选项 (Boot Options),启用
Start virtual machine on host boot up
,让虚拟机随系统启动。 - 将 SATA Disk 1 磁盘的总线 (disk bus) 修改为 VirtIO。
- 将虚拟网络的 device model 修改为 virtio。
- 额外添加一项设备类型为 CDROM 的存储,选择之前下载好的 virtio 驱动镜像。
- 额外添加一项驱动为 virtiofs 的文件系统,源路径设置你希望共享的主机路径,目标路径可以随意设置一个名字,比如
share
。在添加好的文件系统的 XML 配置中的filesystem
节点下添加<binary path="/run/current-system/sw/bin/virtiofsd"/>
,这里的路径可以通过which virtiofsd
获得。
之后就可以启动虚拟机进行系统的安装了,安装过程中需要挂载一次 virtio 驱动镜像,跟着流程走就会触发,选择对应的 Windows 系统版本驱动即可。安装完成后进入之前挂载的 virtio 驱动(一般在 E 盘),安装 virtio-win-gt-x64.exe
(对应 x86-64 系统)。这时候网络应该就可以使用了。
如果之前做了 samba 网络共享的话,可以直接打开 \\192.168.122.1
(根据你自己的设置来),安装之前下载好的 winfsp 软件。或者如果虚拟机系统安装了浏览器也可以直接在浏览器中下载安装。完成之后在虚拟机中打开 services.msc
启用名为 VirtIO-FS Service
的服务即可,并且可以将它设置为自动启用。这时候就能看到在 Z 盘挂载的 virtiofs 文件夹了。
后续
到这里基本上虚拟机已经完全可用了,之后可能还会再设置一些 RemoteApps,尝试一下用 freerdp
在主机打开虚拟机内的软件。