由于一些众所周知的原因,国内访问很多海外网站会出现访问速度缓慢甚至打不开的问题,其中不乏一些日常经常使用的例如搜索、邮箱等应用,虽然目前有很多解决方案来解决电脑、手机上面的网络加速问题,但是每个终端都要单独适配非常麻烦,因此直接在路由器端进行配置,让所有连入路由器的设备都可以无感加速,成为了一个相对『完美』的解决方案,因此我在家里的Gen8上面,用Hyper-V虚拟了一个OpenWRT的软路由来提供此类服务。
Hyper-V由于本身不开源,因此OpenWRT的官方编译版本在很早的时候就移除了针对Hyper-V的支持,因此为了让OpenWRT可以完美的运行在Hyper-V上,我们需要自行编译相关驱动组件。当然网上也有很多大神已经编译好的固件,但是大都加入了一些我自己不太使用的功能,作为一个洁癖,当然是自己编译一个了。
参考了Chiphell大神tedaz的文章非官方编译,Hyper-V的Openwrt x86和x86-64版,Chaos Calmer正式版 后,修改整理如下
准备工作 首先你需要准备一个Linux的编译环境,建议选择Ubuntu这类比较流行的Linux发行版本,并参考OpenWRT官方的OpenWRT编译系统-安装 ,安装好编译所需要的一些依赖包
以Ubuntu 64bit为例,需要执行下面的命令来安装相关的依赖
1 sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev gawk gcc-multilib flex git-core gettext libssl-dev
修改源码 首先从OpenWRT的官网Git下载OpenWRT的源码,建议下载15.05分支的,Trunk分支下的代码通常不是非常稳定。
1 git clone git://git.openwrt.org/15.05/openwrt.git
更新OpenWRT所有的feeds,以便你在后续可以提前把需要的ipk(例如luci、shadowsocks的一些依赖等)打包到固件中
1 2 3 cd openwrt ./scripts/feeds update -a ./scripts/feeds install -a
下载完成后,需要针对源码进行如下的修改。
修改/package/kernel/linux/modules/virtual.mk,在最后加入下面的内容,修改内核,添加让OpenWRT内核支持Hyper-V
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 # # Hyper-V Drives depends on x86 or x86_64. # define KernelPackage/hyperv-balloon SUBMENU:=$(VIRTUAL_MENU) DEPENDS:=@(TARGET_x86||TARGET_x86_64) TITLE:=Microsoft Hyper-V Balloon Driver KCONFIG:= \ CONFIG_HYPERV_BALLOON \ CONFIG_HYPERVISOR_GUEST=y \ CONFIG_PARAVIRT=n \ CONFIG_HYPERV=y FILES:=$(LINUX_DIR)/drivers/hv/hv_balloon.ko AUTOLOAD:=$(call AutoLoad,06,hv_balloon) endef define KernelPackage/hyperv-balloon/description Microsofot Hyper-V balloon driver. endef $(eval $(call KernelPackage,hyperv-balloon)) define KernelPackage/hyperv-net-vsc SUBMENU:=$(VIRTUAL_MENU) DEPENDS:=@(TARGET_x86||TARGET_x86_64) TITLE:=Microsoft Hyper-V Network Driver KCONFIG:= \ CONFIG_HYPERV_NET \ CONFIG_HYPERVISOR_GUEST=y \ CONFIG_PARAVIRT=n \ CONFIG_HYPERV=y FILES:=$(LINUX_DIR)/drivers/net/hyperv/hv_netvsc.ko AUTOLOAD:=$(call AutoLoad,35,hv_netvsc) endef define KernelPackage/hyperv-net-vsc/description Microsoft Hyper-V Network Driver endef $(eval $(call KernelPackage,hyperv-net-vsc)) define KernelPackage/hyperv-util SUBMENU:=$(VIRTUAL_MENU) DEPENDS:=@(TARGET_x86||TARGET_x86_64) TITLE:=Microsoft Hyper-V Utility Driver KCONFIG:= \ CONFIG_HYPERV_UTILS \ CONFIG_HYPERVISOR_GUEST=y \ CONFIG_PARAVIRT=n \ CONFIG_HYPERV=y FILES:=$(LINUX_DIR)/drivers/hv/hv_util.ko AUTOLOAD:=$(call AutoLoad,10,hv_util) endef define KernelPackage/hyperv-util/description Microsoft Hyper-V Utility Driver endef $(eval $(call KernelPackage,hyperv-util)) # # Hyper-V Storage Drive needs to be in kernel rather than module to load the root fs. # define KernelPackage/hyperv-storage SUBMENU:=$(VIRTUAL_MENU) DEPENDS:=@(TARGET_x86||TARGET_x86_64) +kmod-scsi-core TITLE:=Microsoft Hyper-V Storage Driver KCONFIG:= \ CONFIG_HYPERV_STORAGE=y \ CONFIG_HYPERVISOR_GUEST=y \ CONFIG_PARAVIRT=n \ CONFIG_HYPERV=y FILES:=$(LINUX_DIR)/drivers/scsi/hv_storvsc.ko AUTOLOAD:=$(call AutoLoad,40,hv_storvsc) endef define KernelPackage/hyperv-storage/description Microsoft Hyper-V Storage Driver endef $(eval $(call KernelPackage,hyperv-storage))</code></pre>
修改/target/linux/x86/64/config-default和/target/linux/x86/config-3.18,均添加以下内容(这里后面如果内核有跟心,就修改对应的config-内核版本号即可)
1 2 3 4 5 6 7 8 # CONFIG_HYPERV is not set # CONFIG_HYPERV_BALLOON is not set # CONFIG_HYPERV_NET is not set # CONFIG_HYPERV_STORAGE is not set # CONFIG_HYPERV_UTILS is not set # CONFIG_FB_HYPERV is not set # CONFIG_HID_HYPERV_MOUSE is not set # CONFIG_HYPERV_KEYBOARD is not set
至此,修改完成。网上还有很多人建议修改Build相关的部分,考虑到后面我们统一使用其他工具来把img转成vhd,因此这一步我们直接生成img即可,不用修改Build相关的内容。
配置编译参数 OpenWRT有GUI的配置工具,因此我们回到OpenWRT源码主目录,执行make menuconfig,选择Target System为x86,Subtarget有x86_64,以便支持多核心大内存的使用。但是如果你需要在OpenWRT上使用XWare这类只有32位的工具,那就只能编译32位的包了。 然后在Kernel modules里的Virtualization Support里勾选上4个Hyper-V相关的。 最后取消Kernel modules里的Network Devices中其他网卡即可。 当然,如果你希望提前编译类似于shadowsocks之类的工具,可以参考Shadowsocks OpenWRT 上的说明,下载相应的package并在配置编译参数时选中这个包即可,相关依赖会自动选中。
开始编译 使用命令make可以进行编译,make V=s可以让它输出调试信息,带上-j1参数表示用1个核心编译。建议你选择一台4核心以上的机器来进行编译以免等待的时间太久,由于编译过程中需要下载很多内容,因此流畅的网络(能自动翻墙是最好的)会大大加快你的编译速度。
我之前使用了E3-1230V2的CPU,用了6个核心编译,首次编译大概花了接近1小时的事件才全部编译完成。
转换格式,大功告成 编译完成后,在BIN目录下,可以找到编译完成的img文件(一般是压缩包),解压后,我们使用下面的命令来转化为Hyper-V可用的vhd格式。
1 qemu-img convert -f raw -O vpc openwrt-x86-generic-combined-ext4.img openwrt-x86-generic-combined-ext4.vhd
然后直接在Hyper-V下面使用就一切OK啦。