diff --git a/run-windows11.py b/run-windows11.py index cc528b0..f63332c 100755 --- a/run-windows11.py +++ b/run-windows11.py @@ -126,14 +126,14 @@ else: ) daemonize = False install_from_iso = False -install_img = Path(env("WIN11_VM_INSTALL_IMG")) if env("WIN11_VM_INSTALL_IMG") else None +install_from_img = False download_only = False extra_args = [] def usage(stream=sys.stdout): stream.write(f"""\ -Usage: {Path(sys.argv[0]).name} [--daemon] [--download-only] [--install-from-iso | --install-from-img FILE] +Usage: {Path(sys.argv[0]).name} [--daemon] [--download-only] [--install-from-iso | --install-from-img] [--state-dir DIR] [--rdp-port PORT] [--ssh-port PORT] [-- QEMU_ARGUMENT ...] If the system disk (DIR/disk.qcow2, see --state-dir) is missing, create it from @@ -151,12 +151,11 @@ Options: --download-only Download the VirtIO tools ISO if it is missing, then exit (the Windows ISO and base QCOW2 are supplied manually) --install-from-iso Install from ISO when the system disk is missing - --install-from-img FILE - Install from a disk image made by - vm-images/build-windows-install-disk.sh instead of the ISO - (implies --install-from-iso). It is attached as an NVMe - disk, much faster than the emulated USB CD-ROM, and is - never modified (overrides WIN11_VM_INSTALL_IMG) + --install-from-img Like --install-from-iso, but install from the disk image + made by vm-images/build-windows-install-disk.sh, which + is the ISO path ending in .install.img instead of .iso. + It is attached as an NVMe disk, much faster than the + emulated USB CD-ROM, and is never modified --state-dir DIR Directory for the VM disk, seed ISO and runtime files (default: .vm/windows11; overrides WIN11_VM_STATE_DIR) --rdp-port PORT Host port forwarded to guest RDP (default: 3389; @@ -168,7 +167,7 @@ Options: Environment variables: WIN11_VM_BASE_IMAGE Windows 11 base QCOW2 image (default: beside shared images) WIN11_VM_INSTALL_ISO Windows 11 installation ISO used with --install-from-iso - WIN11_VM_INSTALL_IMG Installation disk image used instead of the ISO + (--install-from-img uses the same path ending in .install.img) WIN11_VM_TOOLS_ISO VirtIO Windows tools ISO (default: resolved by shared image helper) WIN11_VM_RDP_PORT Host RDP port (default: 3389) WIN11_VM_SSH_PORT Host SSH port (default: 2222) @@ -194,11 +193,7 @@ while args: elif arg == "--install-from-iso": install_from_iso = True elif arg == "--install-from-img": - if not args: - die(f"{arg} requires a file argument.", 2) - install_img = Path(args.pop(0)) - elif arg.startswith("--install-from-img="): - install_img = Path(arg.split("=", 1)[1]) + install_from_img = True elif arg == "--state-dir": if not args: die(f"{arg} requires a directory argument.", 2) @@ -228,7 +223,7 @@ while args: usage(sys.stderr) sys.exit(2) -if install_img: +if install_from_img: install_from_iso = True if download_only: @@ -263,10 +258,11 @@ if not disk_image.is_file(): installing_from_iso = install_from_iso image_downloader = find_image_downloader() if install_from_iso: - # The installation disk image replaces the ISO, which is then not needed. - install_iso = None if install_img else Path( + install_iso = Path( env("WIN11_VM_INSTALL_ISO") or capture([str(image_downloader), "--print-path", "windows11", "--iso"])) + if install_from_img: + install_iso = install_iso.with_suffix(".install.img") uses_shared_tools_iso = False if env("WIN11_VM_TOOLS_ISO"): tools_iso = Path(env("WIN11_VM_TOOLS_ISO")) @@ -282,12 +278,11 @@ if shutil.which(qemu_binary) is None: if installing: if shutil.which("qemu-img") is None: die("qemu-img is not installed.") - if install_img: - if not install_img.is_file(): - die(f"Windows 11 installation disk image was not found: {install_img}\n" - "Build it with vm-images/build-windows-install-disk.sh ISO OUTPUT.img") - elif installing_from_iso: + if installing_from_iso: if not install_iso.is_file(): + if install_from_img: + die(f"Windows 11 installation disk image was not found: {install_iso}\n" + "Build it with vm-images/build-windows-install-disk.sh ISO") die(f"Windows 11 ISO was not found: {install_iso}") elif not base_image.is_file(): die(f"Windows 11 base QCOW2 image was not found: {base_image}") @@ -399,12 +394,12 @@ if installing_from_iso: device = (f"ide-cd,drive={media_id},bus={ide_bus},bootindex={boot_index}" if host_arch == "amd64" else f"usb-storage,drive={media_id},bootindex={boot_index}") - if media_id == "install_media" and install_img: + if media_id == "install_media" and install_from_img: # snapshot=on: NVMe cannot report write protection, and Windows # writes to the volume it mounts, so a read-only drive makes it fail. # The writes go to a temporary overlay and the image stays unchanged. qemu_args += [ - "-drive", f"file={install_img},if=none,id={media_id},format=raw,snapshot=on", + "-drive", f"file={media_file},if=none,id={media_id},format=raw,snapshot=on", "-device", f"nvme,drive={media_id},serial=installer,bootindex={boot_index}", ] continue diff --git a/windows11-arm64-install-speed.md b/windows11-arm64-install-speed.md index 79da1c1..0072a74 100644 --- a/windows11-arm64-install-speed.md +++ b/windows11-arm64-install-speed.md @@ -8,7 +8,7 @@ - 慢的原因是**安装介质走了模拟的 USB 光驱**(`usb-storage` 挂 ISO):读安装文件平均只有约 4 MB/s。 - 把安装介质改成**FAT32 分区里的 NVMe 磁盘镜像**(`install.wim` 拆成 `.swm`)后,读速达到 54 到 92 MB/s (前 7 个采样平均约 74 MB/s),安装在约 80 秒内到 40%,复制阶段约 2 分钟结束。 -- 方案已接进 `run-windows11.py`:`--install-from-img FILE`,镜像由 `vm-images/build-windows-install-disk.sh` 生成。 +- 方案已接进 `run-windows11.py`:`--install-from-img`,镜像由 `vm-images/build-windows-install-disk.sh` 生成。 ## 环境 @@ -100,11 +100,12 @@ vm-images/build-windows-install-disk.sh [--force] ISO [OUTPUT.img] ### 启动方式 -`run-windows11.py` 的 `--install-from-img FILE`(或环境变量 `WIN11_VM_INSTALL_IMG`)用这个镜像做安装介质,隐含 `--install-from-iso`, -此时不再需要找 ISO: +`run-windows11.py` 的 `--install-from-img` 用这个镜像做安装介质,隐含 `--install-from-iso`。镜像路径是 ISO 路径 +(`WIN11_VM_INSTALL_ISO` 或自动查找到的 ISO)把 `.iso` 换成 `.install.img`,也就是 `build-windows-install-disk.sh ISO` 默认生成的位置, +此时不再读取 ISO: ```bash -./run-windows11.py --install-from-img vm-images/install-iso/Windows11_Client_arm64_en-us_26300_9457.install.img +./run-windows11.py --install-from-img ``` `install_media` 不再作为 `usb-storage` 光驱,而是: