Skip to content

你会用 NAS 给 PC 装系统吗?

Posted on:April 28, 2020 at 02:00 PM
0

新组装的 PC 需要装系统,但是手边又没有合适的 U 盘做启动介质,不如试试在家里搭一套安装系统的网络服务吧。利用 PXE 网络启动,可以无需 U 盘就能把 Win10 和 Ubuntu 20.04 装好。首先整个项目的文件打包可以点击这里下载。

概述

这是一套涉及到多个服务组件相互配合的系统,但整体配置还不算复杂。先来看看整个项目的结构吧。

├── dnsmasq
│   └── dnsmasq.conf
├── tftproot
│   └── ipxe.efi
├── httproot
│   ├── menu.ipxe
│   └── images
│       ├── win
│       │   ├── install.bat
│       │   ├── pe
│       │   │   ├── Boot
│       │   │   │   ├── BCD
│       │   │   │   └── boot.sdi
│       │   │   └── sources
│       │   │       └── boot.wim
│       │   └── winpeshl.ini
│       └── ubuntu
│           ├── mnt
│           └── ubuntu-20.04-desktop-amd64.iso
└── smbroot
    ├── win10_1903
    └── win10_1909

整个项目大体分为 4 个组件,分别是 DHCP 服务器、TFTP 文件服务器、HTTP 服务器、SMB 文件共享服务和 iPXE 网卡启动 ROM。

PXE 是预启动执行环境(Preboot eXecution Environment),可以通过网卡启动 PC,而不需要依赖本地硬盘里的数据,对于装系统来说再合适不过了。

PXE 启动并安装系统的原理如下:

  1. PC 在 BIOS 中选择从网卡启动
  2. PC 网卡发出 DHCP 请求
  3. DHCP 服务器应答 PXE 启动配置文件路径
  4. PC 网卡下载对应的 PXE 启动配置文件,并启动执行环境
  5. PXE 在执行环境中加载系统安装文件,启动正常的系统安装过程

下面让我们一步一步的看看应该怎么配置。

DHCP

第一步需要配置 DHCP 服务器,一般我们用的 openwrt 会使用 dnsmasq 做 DHCP 服务器。就以 dnsmasq 的配置文件为例。

dhcp-match=set:iPXE,175
dhcp-boot=tag:!iPXE,ipxe.efi,DiskStation,10.10.10.201
dhcp-boot=tag:iPXE,http://10.10.10.201:12345/menu.ipxe

一行一行的来看。

第 1 行是对包含 175 tag 的请求,打上 iPXE 的标志。这里涉及一个新概念 iPXE。iPXE 是新一代的网卡 PXE ROM,拥有更多的功能。与老版 PXE ROM 相比,在使用中最明显的区别就是,iPXE 可以通过 http 下载启动配置,而老版 PXE 只能通过 tftp 下载,http 比 tftp 在传输性能上要高出很多。如果你是这几年新买的网卡,基本都是原生带有 iPXE ROM 的了。而 DHCP 请求中带有 175 tag 也就标志着这块网卡是支持 iPXE 的。

第 2 行先判断了只有不带 iPXE 标志的请求才会执行,!是否定的意思。这一行是指示老版 PXE 通过 tftp 去 10.10.10.201 这台服务器上下载 ipxe.efi 这个文件来执行,DiskStation 是这台服务器的名字。执行了 ipxe.efi 之后,旧网卡就也支持 iPXE 特性了。

第 3 行是判断带有 iPXE 标志的请求,回去对应的 http 地址下载我们准备好的启动配置文件。

总体来看这个配置文件就是让支持 iPXE 的网卡直接通过 http 去下载配置文件,不支持的网卡先刷上支持的 ROM,再以支持 iPXE 的网卡的身份重新请求一次 DHCP。

TFTP 服务器

从上面 DHCP 的请求过程可以看出来,我们需要在 TFTP 服务器上放一个 ipxe.efi 文件,这个文件可以从 ipxe.org 下载到。由于后续请求都会由 iPXE ROM 通过 http 发起,所以 TFTP 服务器也只需要这一个文件就够了。

群晖的系统自带 TFTP 服务器,可以在 控制面板 - 文件服务 中开启。

synolog tftp

HTTP 服务器

iPXE ROM 可以通过 http 协议下载文件,大大提升了文件加载速度。对于千兆内网来说,2.5G 的 ubuntu 20.04 安装镜像,也只需要 1 分半钟左右就能下载完成了。

所以我们会把安装中用到的大部分文件都放在 http 服务器上。目录结构可以参考最上面 httproot 的部分。http 服务器我是在 Docker 里跑了一个 Caddy 的。其实你用群晖自带的 Web Station 应该也可以。

menu.ipxe 是 iPXE 启动后会显示的一个菜单,可以选择安装 Windows 10 或者 Ubuntu 20.04,根据选择的结果再去加载对应操作系统的安装文件。以下是它的内容。

#!ipxe

:start
menu Choose to Install

item --key w windows      Install Windows 10
item --key u ubuntu       Install Ubuntu 20.04
item --gap --             --------------------------------------
item --key t shell        Drop to iPXE shell
item reboot               Reboot
item --key q exit         Exit iPXE and try next boot device in BIOS

choose --timeout 10000 --default exit selected
set menu-timeout 0
goto ${selected}

:shell
shell
goto start

:reboot
reboot

:exit
exit

:windows
kernel wimboot
initrd images/win/install.bat                     install.bat
initrd images/win/winpeshl.ini                    winpeshl.ini
initrd images/win/pe/Boot/BCD                     BCD
initrd images/win/pe/Boot/boot.sdi                boot.sdi
initrd images/win/pe/sources/boot.wim             boot.wim
boot

:ubuntu
kernel images/ubuntu/mnt/casper/vmlinuz               vmlinuz
initrd images/ubuntu/mnt/casper/initrd                initrd
imgargs vmlinuz initrd=initrd ip=dhcp boot=casper url=http://10.10.10.201:12345/images/ubuntu/ubuntu-20.04-desktop-amd64.iso
boot

配置文件语法类似 shell 脚本。先声明一个 menu,再根据用户的选择跳转到不同的位置去执行。

这个配置文件作为一个示例,如果你想安装别的系统只需要参考文档做对应的修改就好了。

Windows 10

上面的 menu.ipxe:windows 下面对应了 Windows 10 的安装。Windows 10 的安装用到了一个 boot loader 叫 wimboot,它可以帮你从 iPXE 中引导一个 WinPE 系统。WinPE 相关的文件可以从 Windows Assessment and Deployment Toolkit (ADK) 中获得,或者直接用我打包好的 httproot/images/win/pe 中的就行。winpeshl.ini 会告诉 WinPE 启动后先去执行 install.bat,而 install.bat 会尝试 ping 并 mount SMB 共享中的 Windows 10 安装文件。

install.bat 内容如下

wpeinit

SMBSERVER=10.10.10.201
SMBPATH=smbpath
SMBUSER=smbuser
SMBPASS=smbpass

ping "%SMBSERVER%" -n 3

net use w: \\%SMBSERVER%\%SMBPATH% /user:%SMBUSER% %SMBPASS%

:ask
@echo Which version do you want to install?
@echo 1. Win10 1909
@echo 2. Win10 1903

@echo off

set INPUT=
set /P INPUT=Type the number:

if /I "%INPUT%" EQU "1" (
	goto :Win10_1909
)else if /I "%INPUT%" EQU "2" (
	goto :Win10_1903
)else (
 	@echo Invalid Input %INPUT%
	goto :ask
)

:Win10_1903
w:\\win10_1903\setup.exe
exit

:Win10_1909
w:\\win10_1909\setup.exe
exit

开头 4 个变量的意义:

变量名意义
SMBSERVERSMB 共享服务器 IP
SMBPATHSMB 共享目录名
SMBUSERSMB 共享登陆用户名(有只读权限即可)
SMBPASSSMB 共享登陆密码

这个脚本中包含了 win10_1903win10_1909 两个版本,对应了 smbroot 中的两个目录,你可以选择自己喜欢的版本安装。这两个目录的内容即是对应的安装 iso 镜像里的内容。

对应的操作均可以在群晖的 NAS 中完成,SMB 共享服务可以在 控制面板 - 文件服务 中开启,对应共享文件夹的权限也可以在 共享文件夹 中设置。

群晖的 File Station 应用可以直接挂载 iso 镜像,挂载之后把镜像内的内容都复制到对应的 SMB 共享文件夹里就行了。

synology mount iso

Ubuntu 20.04

Ubuntu 20.04 的安装对应 menu.ipxe:ubuntu 之下的内容。Ubuntu 的安装非常简单,只涉及 http 服务器上的内容就够了。

将下载好的 iso 放在 images/ubuntu 目录里,然后将它挂载到 images/ubuntu/mnt 目录上。iPXE 会下载 casper/vmlinuz 作为 kernel,casper/initrd 作为 initrd 来启动 Live Desktop,并在启动后下载 ubuntu-20.04-desktop-amd64.iso 来准备安装文件。

只用路由器也能装系统了?

以上所说的所有服务,其实在 OpenWrt 上都有对应的功能。所以如果你的软路由存储空间够大的话,按照上述配置,只用一个路由器也可以给 PC 装系统了。

参考

  1. ipxe
  2. robinsmidsrod gist
  3. askubuntu question