鱼与熊掌兼得
我最近买了一台 IBM ThinkPad 笔记本电脑,预装了 1GB 内存和 Windows XP。由于我多年来只使用 Linux,我立刻想到要把它变成一个双启动系统(实际上是一个多启动系统,因为我通常会在我的电脑上安装多个 Linux 副本)。
正如我所说,我主要只使用 Linux,但我也保留了一份 Windows 副本,因为其他人可能需要使用我的电脑,而他们不会使用 Linux。此外,作为一名计算机专家,我喜欢了解使用计算机的所有方式,而不仅仅是最好的一种,而且由于仍然有很多人使用 Windows,我想了解他们的观点。
所以,我现在可以重启并在 Linux 和 Windows 之间以及 Windows 和 Linux 之间切换。然而,我认为并行运行这两个系统会很有用,而不是从一个系统切换到另一个系统。其中一个原因是安装在我的笔记本电脑上的 Windows XP 家庭版是由 IBM 专门为这款笔记本电脑定制的,并且有一些 IBM 开发的工具使事情变得更方便。另一个原因是我想测试一个客户端-服务器网络,其中 Windows 作为客户端,Linux 作为服务器。我相信您也可以想到其他这样做的理由。
经过一些研究和测试,我决定使用 QEMU。现在我可以在 Windows 上运行安装在其他分区上的任何 Linux 发行版。我也可以从 Linux 系统访问 Windows。我可以从 Linux 系统访问互联网,也可以从 Windows 访问任何 Linux 服务。此外,我可以从网络访问某些 Linux 服务。这就像在同一台机器上同时运行两个系统。
使用 QEMU 在 Windows 内部运行 Linux 并不困难;然而,要做好它需要一些我没有立即发现的技巧。
在 Windows 中安装 QEMU 很简单。我下载了 qemu-0.9.0-windows.zip 并将其解压到 D:\QEMU 中。我没有忘记阅读 README-en.txt(始终阅读 README)。然后,我复制了批处理文件(脚本)qemu-win.bat 并将其重命名为 start-linux.bat。为了更轻松地访问它,我在桌面上为它创建了一个快捷方式(链接),方法是右键单击并选择发送到→桌面。然后,我修改了 start-linux.bat 的最后一行,使其看起来像这样
qemu.exe -L . -m 128 -hda \\.\PhysicalDrive0 -soundhw all -localtime
修改包括替换参数-hda linux.img为参数-hda \\.\PhysicalDrive0。现在,当我通过运行此脚本启动 QEMU 时,它不再使用文件 linux.img 作为虚拟硬盘,而是使用我的真实硬盘并从中启动。然后,我看到了安装在我的硬盘 MBR 中的漂亮的 GRUB 菜单,我选择并启动了我的一个 Linux 系统。这不是很棒吗?
注意不要在 Windows 内部再次启动 Windows。根据文档,在多台机器中使用相同的磁盘映像可能会损坏它。
我通常在 Windows 内部启动的系统是 Fedora Core 6。参数 -m 128 告诉 QEMU 为模拟系统使用最多 128MB 的 RAM。使用 128MB 的 RAM,Fedora 无法在图形模式下运行,并回退到文本模式。但是,使用 256MB 的 RAM,它可以工作。如果您的机器像我一样有 1GB 的 RAM,您可以慷慨地给 Linux 512MB。
图形界面对我来说很重要,但我对命令行 Linux 也非常满意。为了在文本模式下运行 Fedora,即使它有 256MB 的 RAM,我也会将 3 参数传递给内核,这告诉它在运行级别 3 中启动。最初,我是手动执行此操作的,步骤如下
在 GRUB 菜单中选择 Fedora。
按 E 编辑它。
选择内核行。
按 E 编辑它。
在内核行的末尾追加 3,然后按 Enter 返回。
按 B 启动修改后的 Fedora 条目。
后来,我在菜单中添加了另一个条目,内核行末尾附加了 3 参数,以便更快地启动它,它看起来像这样
title Fedora Core TextMode (2.6.18-1.2798.fc6) root (hd0,7) kernel /boot/vmlinuz-2.6.18-1.2798.fc6 ro root=/dev/hda8 rhgb quiet 3 initrd /boot/initrd-2.6.18-1.2798.fc6.img
有时我在 Linux 启动时会看到几个错误消息和失败(例如,当我尝试 Scientific Linux 时),但我忽略了它们。原因是模拟机器的硬件(由 QEMU 模拟)与真实机器的硬件有些不同。当硬盘从一台机器取出并放入另一台机器时,也会发生同样的事情。Linux 自动检测机器的设备并报告某些设备丢失和添加了新设备(例如,网卡)。我只是保留了“已移除”设备的配置,并让 Linux 自动配置它找到的新设备。
为了使模拟系统运行得更快,我安装了 kqemu。我从 QEMU 下载页面下载了 kqemu-1.3.0pre11.tar.gz,并将其解压到 D:\QEMU\ 内部。然后,我用鼠标右键单击 kqemu.inf 并选择安装。接下来,我在 start-linux.bat 中添加了命令net start kqemu并在 qemu.exe 中添加了参数-kernel-kqemu。现在,start-linux.bat 的最后两行看起来像这样
net start kqemu qemu.exe -L . -m 256 -kernel-kqemu -hda \\.\PhysicalDrive0 ↪-soundhw all -localtime
注意:Scientific Linux 4.4 完全不能与参数 -kernel-kqemu 一起使用,问题似乎是内核与 BIOS 文件(名为 bios.bin,我认为它代表模拟系统的 BIOS 配置)不兼容。当我用 Puppy Linux 的 BIOS 替换它时,它就可以工作了。奇怪的是,原始 BIOS 是 128KB,而 Puppy 的 BIOS 是 64KB,而且也更旧。
网络的默认 QEMU 参数是-net nic -net user。这意味着它将在 Windows 端模拟一个虚拟接口,并为模拟的 Linux 系统创建一个网络接口 eth0。这两个接口之间有一个虚拟连接,允许它们相互通信。Windows 虚拟接口的 IP 是 10.0.2.2/24,QEMU 还创建了一个连接到它的虚拟 DHCP 服务器。为了从 QEMU DHCPD 获取 Linux 的 IP,我以 root 身份登录并给出命令dhclient。然后,Linux 接口获得 IP 10.0.2.15/24,网关 10.0.2.2 和 DNS 10.0.2.3。之后,可以从 Linux 毫无问题地访问 Windows 和互联网。

图 2. 网络图
要检查网络配置,请尝试以下命令ip address ls, ip route ls和cat /etc/resolv.conf在 Linux 中。以下是这些命令的示例输出
[root@fedora6 ~]# ip address ls 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 3: sit0: <NOARP> mtu 1480 qdisc noop link/sit 0.0.0.0 brd 0.0.0.0 [root@fedora6 ~]# ip route ls 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 default via 10.0.2.2 dev eth0 [root@fedora6 ~]# cat /etc/resolv.conf ; generated by /sbin/dhclient-script nameserver 10.0.2.3
要测试网络连接,请尝试以下命令ping 10.0.2.2和wget http://www.google.com/.
如果您尝试 ping www.google.com(或任何其他 IP),它将不起作用。但是,网络连接是正常的并且正在工作,您可以使用其他工具(如 wget 或 lftp)来验证它。这仅仅意味着 ping 由于某种原因不起作用。这对我来说非常具有误导性,因为检查网络连接的常用方法是 ping 外面的某些东西。
因为我可以从 Linux 将 Windows ping 为 10.0.2.2,所以我也可以访问 Windows 上运行的任何服务(守护进程)。特别是,我可以访问任何文件共享服务。通常,我在 Windows 上运行 Apache 作为 Web 服务器。可以使用 EasyPHP 轻松安装它。然后,我使用 wget 检索可以通过 Web 服务器访问的任何文件。
我使用的另一个服务是 FTP。我使用 FileZilla FTP 服务器安装和配置它。从 Linux,我可以使用 lftp(您也可以使用任何其他 ftp 客户端)访问由 FTP 服务共享的文件夹(目录)。这比使用 Web 服务器更好,因为我可以双向传输文件——从 Windows 到 Linux 以及从 Linux 到 Windows。
我甚至使用 svnserve 在 Windows 中运行 Subversion 服务。从 Linux,我可以访问 Windows 中的 Subversion 存储库。可以将其视为在 Windows 和 Linux 之间传输文件的一种方式,因为您可以从 Windows 和 Linux 访问 svn 存储库,尽管这不是一种非常直接的文件传输方式。
我尝试使用 fat32 分区在 Linux 和 Windows 之间传输文件,这两个系统都可以访问该分区。从理论上讲,没有理由不应该工作,实际上它确实工作;但是,它不能很好地工作。问题是,从 Linux 对 fat32 所做的修改在 Windows 重新启动之前不会被“看到”,而从 Windows 所做的修改在 QEMU 重新启动之前不会被 Linux “看到”,这使得这种解决方案不切实际且无法使用。
为了访问 Web 服务器和 Linux 的安全 shell,我将这些参数添加到 qemu.exe 命令中
-redir tcp:88:10.0.2.15:80 -redir tcp:22::22
第一个 -redir 参数使 QEMU 回答对端口 88 的任何请求。实际上,它不会自己回答,而是将其重定向到服务器 10.0.2.15,端口 80,这是 Linux Web 服务器。我选择端口 88(与 80 不同)是为了以防我需要在 Windows 中运行任何其他 Web 服务(例如 EasyPHP),这样它们就不会相互冲突。为了测试它是否工作,请在浏览器中打开 http://127.0.0.1:88/。确保在 Linux 服务器启动后配置了 Linux 网络接口(使用 dhclient)。
第二个 -redir 参数使 QEMU 将任何到端口 22(安全 shell)的连接重定向到 Linux 的端口 22。如果服务器 IP 丢失,则默认值为 10.0.2.15,这对应于模拟 DHCPD 给模拟系统(Linux)的 IP。为了从 Windows 访问 Linux 服务器的 shell,我使用 PuTTY 连接到 127.0.0.1 端口 22。通过 PuTTY 访问 Linux shell 比通过 QEMU 控制台访问它方便得多,因为我可以同时打开多个终端,并且可以在 Linux 和 Windows 之间复制/粘贴。我还可以放大 PuTTY 终端并调整字体和颜色。也可以使用 pscp 通过 SSH 在 Windows 和 Linux 之间复制文件。
如果您想使这些 Linux 服务(httpd 和 sshd)也可供网络访问(以便可以从本地网络上的其他计算机访问它们),请为它们打开 Windows 防火墙:控制面板→Windows 防火墙→例外→添加程序。然后浏览,选择 D:\QEMU\qemu.exe,然后按确定。接下来,打开控制面板→Windows 防火墙→例外→添加端口,并添加端口 88 和 22。在添加或编辑程序或端口时,还要选中“更改范围...”框。
我还想访问其他 Linux 服务,例如 Samba 和 FTP。为我想访问的每个端口添加另一个 -redir 参数不方便,而且无论如何都不是一个优雅的解决方案。我希望能够不受任何限制地从 Windows 访问 Linux。这似乎并不容易,因为 Windows 可以看到的只是 qemu.exe 进程,它不知道内部发生了什么。那么,Windows 如何才能直接与在 QEMU 内部运行的 Linux 通信呢?这可以通过使用 OpenVPN 创建一个 tap 虚拟以太网适配器来实现。
我下载了 openvpn-2.0.9-install.exe 并安装了它。在安装过程中,我只选中了组件 TAP-Win32 Virtual Ethernet Adapter、Add OpenVPN to Path 和 Add Shortcuts to Start Menu,因为我不需要其他的。我将目标文件夹更改为 D:\QEMU\OpenVPN,因为我更喜欢将相关工具分组在一起。我收到了一些警告,说此软件尚未通过 Windows 测试,但我还是继续了,相信开源测试比 Windows 测试更强大。
安装完成后,我选择了菜单开始→OpenVPN→添加新的 TAP-Win32 虚拟以太网适配器以创建一个新的 tap 接口。再次,我收到了相同的警告,但还是继续了。现在,在网络连接中,我找到了一个新的网络连接,名为本地连接 1。我右键单击它并将其重命名为 tap1。
然后,我修改了 start-linux.bat,方法是将这些参数添加到 QEMU
-net nic,vlan=0 -net tap,vlan=0,ifname=tap1 -net nic,vlan=1 -net user,vlan=1
参数 -net nic 告诉 QEMU 为模拟系统创建一个新的网络接口。由于此参数已使用两次,Linux 将在一台具有两个网络接口 eth0 和 eth1 的机器中运行。参数 -net user 在另一侧(Windows 侧)创建一个虚拟接口。它是先前默认创建的网络接口(具有与之关联的内置 DHCP 服务器),即使我们没有指定任何 -net 参数。参数 -net tap 告诉 QEMU 使用我们先前创建的虚拟以太网适配器 tap1,并将其连接到虚拟网络。与 -net 参数一起使用的 vlan 选项告诉 QEMU 如何将这些虚拟接口相互连接。所有具有相同 vlan 编号的接口都连接到相同的虚拟集线器/交换机。因此,在由 QEMU 模拟的虚拟网络中,我们有两个交换机。
linux-start.bat 的最后两行现在看起来像这样
net start kqemu qemu.exe -L . -m 256 -kernel-kqemu -hda \\.\PhysicalDrive0 ↪-localtime -redir tcp:88:10.0.2.15:80 -redir tcp:22::22 ↪-net nic,vlan=0 -net tap,vlan=0,ifname=tap1 ↪-net nic,vlan=1 -net user,vlan=1
注意,QEMU 参数-soundhw all现在不见了。我删除了它,因为其中一个声音设备与网络设备冲突,因此它们无法正确识别为 eth0 和 eth1。如果您不能没有声音设备,至少将其附加在行的末尾;参数的顺序确实很重要。
-net 参数声明的顺序也很重要。我注意到,如果在 -net tap 之前声明 -net user,则 eth0 和 eth1 会相互切换,并且在 Fedora 初始化脚本期间也无法初始化 eth0。如果您遇到任何类似的问题,请记住这一点。
启动 QEMU 后,我们有一个(虚拟)物理网络(图 4)。

图 4. 物理网络
要检查网络的“物理”连接,请按 Ctrl-Alt-2 切换到 QEMU 监视器。然后,在 (qemu) 提示符下,给出命令info network。最后,按 Ctrl-Alt-1 返回 Linux 控制台。以下是该命令的输出
VLAN 0 devices: tap: ifname=tap1 ne2000 pci macaddr=52:54:00:12:34:56 VLAN 1 devices: user redirector ne2000 pci macaddr=52:54:00:12:34:57
现在,我们只需要正确配置网络设置,例如 IP、网关和 DNS。
Windows 端的用户重定向器接口由 QEMU 自动配置,IP 为 10.0.2.2/24,我们无法访问它,因此我们无法修改它。如果您在网络连接中检查,您会发现虚拟接口 tap1 现在似乎已连接。要配置它,请右键单击它并选择属性,然后选择 Internet 协议 (TCP/IP) 并再次选择属性。在配置窗口中,设置固定 IP 地址 192.168.10.10 和子网掩码 255.255.255.0。这就像一个普通的网络接口配置。
要检查网络配置是否正常,请运行ipconfig在命令提示符下,您将看到 tap1 的此输出
Ethernet adapter tap1: Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 192.168.10.2 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . :
当 QEMU 运行时,会显示此输出;否则,tap1 的信息将类似于媒体已断开连接.
现在,我们完成了 Windows 端的网络配置。这只需完成一次。剩下的就是在 Linux 端配置网络接口。
首先,以 root 身份登录。要检查您是否已经有两个网络接口,请运行ip addr,它应该列出 eth0 和 eth1。您可以像这样自动配置 eth0dhclient eth0,就像我们之前所做的那样,它将从 QEMU 的内置 DHCP 服务器获取 IP。然后,您可以继续手动配置 eth1。
但是,我更喜欢尽可能使用脚本,并且我想确保 eth0 始终获得 IP 10.0.2.15/24,无论如何,因为这对于先前显示的 -redir 参数很重要。因此,我通过运行此脚本(每次系统重新启动时都必须重新运行)在 Linux 端进行网络配置
bash# cat /usr/local/config/net-config-qemu.sh #!/bin/bash ### configure the network when Linux is being ### emulated from Windows by QEMU ### network settings IP0=10.0.2.15/24 ## eth0 IP1=192.168.10.10/24 ## eth1 GW=10.0.2.2 ## gateway DNS=10.0.2.3 ### configure eth0 ip link set dev eth0 up ip address flush dev eth0 ip address add $IP0 dev eth0 ### configure eth1 ip link set dev eth1 up ip address flush dev eth1 ip address add $IP1 dev eth1 ### set the gateway ip route add to default via $GW ### set the DNS server echo "nameserver $DNS" > /etc/resolv.conf
要检查网络配置是否正常,请运行ip addr, ip route和cat /etc/resolv.conf。以下是这些命令的输出
[root@fedora6 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff inet 192.168.10.10/24 scope global eth1 3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 52:54:00:12:34:57 brd ff:ff:ff:ff:ff:ff inet 10.0.2.15/24 scope global eth0 4: sit0: <NOARP> mtu 1480 qdisc noop link/sit 0.0.0.0 brd 0.0.0.0 [root@fedora6 ~]# [root@fedora6 ~]# ip route 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 192.168.10.0/24 dev eth1 proto kernel scope link src 192.168.10.10 default via 10.0.2.2 dev eth0 [root@fedora6 ~]# [root@fedora6 ~]# cat /etc/resolv.conf nameserver 10.0.2.3 [root@fedora6 ~]#
现在,剩下的就是确保网络按预期工作。第一个检查是从 Linux ping 10.0.2.2。如果它不起作用,则可能是您需要切换 eth0 和 eth1。有时,MAC 为 52:54:00:12:34:56 的网络接口被 Linux 识别为 eth0,另一个被识别为 eth1,有时它被识别为 eth1,另一个被识别为 eth0。这取决于 Linux 发行版(Fedora、Slackware 或其他任何发行版)。因此,eth0 和 eth1 可能从配置脚本中获得了错误的 IP 地址,在这种情况下,ping 将不起作用。要解决此问题,请修改分配给脚本 /usr/local/config/net-config-qemu.sh 中 eth0 和 eth1 的 IP 地址,然后再次运行它。
现在,与 10.0.2.2 的 ping 工作正常,请尝试从 Linux ping 192.168.10.2 (tap1)。一般来说,它不起作用。这很奇怪,因为从 Windows 的命令提示符 ping 192.168.10.10 确实有效。问题在于 Windows 防火墙。要解决此问题,请打开控制面板,双击 Windows 防火墙,选择高级选项卡,选择 tap1 并单击设置,然后选择 ICMP 选项卡,在此处,选中允许传入回显请求。之后,与 192.168.10.2 的 ping 应该可以工作了。
不要尝试从 Windows 的命令提示符 ping 10.0.2.15,因为它不可能工作。你想知道为什么吗?我也是。
接下来要尝试的是使用 IP 192.168.10.10 从 Windows 访问某些 Linux 服务。尝试在浏览器中打开 http://192.168.10.10,您将看到 Linux Web 服务器提供的页面。还可以尝试通过 PuTTY 登录到 192.168.10.10,端口 22,您将访问 Linux shell。
最后,我们有了 Windows 和 Linux 之间一流的双向网络连接,可以用来从 Windows 访问任何 Linux 服务。
资源
QEMU 开源处理器模拟器: fabrice.bellard.free.fr/qemu
Windows 上的 QEMU: www.h7.dion.ne.jp/~qemu-win
OpenVPN 下载: openvpn.net/download.html
使用 Tap: www.h7.dion.ne.jp/~qemu-win/TapWin32-en.html
如何使用网络: www.h7.dion.ne.jp/~qemu-win/HowToNetwork-en.html
qemu-0.9.0-windows.zip: www.h6.dion.ne.jp/~kazuw/qemu-win/qemu-0.9.0-windows.zip
QEMU 下载: fabrice.bellard.free.fr/qemu/download.html
EasyPHP 下载: www.easyphp.org/telechargements.php3
FileZilla 下载: sourceforge.net/project/showfiles.php?group_id=21558
Subversion 下载: subversion.tigris.org/servlets/ProjectDocumentList?folderID=260&expandFolder=74
PuTTY 下载: www.chiark.greenend.org.uk/~sgtatham/putty/download.html
Dashamir Hoxha 多年来一直是 Linux 专家,但偶尔他也必须使用 Windows。他在服务器管理和网络配置方面拥有丰富的经验。