From 86d6976d96bc6b5ead167d87e36d9dbab7161287 Mon Sep 17 00:00:00 2001 From: bin456789 Date: Tue, 28 Apr 2026 07:33:07 +0800 Subject: [PATCH] =?UTF-8?q?core:=20=E6=B7=BB=E5=8A=A0=20pci-hyperv=20/=20v?= =?UTF-8?q?pci.sys=20=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 Azure 安装 debian / windows 10 ltsc 时不到 nvme 硬盘 --- reinstall.sh | 66 ++++++++++++++++++------- trans.sh | 134 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 178 insertions(+), 22 deletions(-) diff --git a/reinstall.sh b/reinstall.sh index f4c7983..fabe9c2 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -3411,6 +3411,32 @@ EOF fi } + cp_debian_kali_driver() { + # debian 13 的 linux-image.deb 有 /usr/lib 没有 /lib + # debian 13 的 scsi-modules.udeb 没有 /usr/lib 有 /lib + local src_drivers_dir=$1/lib/modules/$kver/kernel/drivers + if ! [ -d "$src_drivers_dir" ]; then + local src_drivers_dir=$1/usr/lib/modules/$kver/kernel/drivers + fi + local extra_drivers=$2 + # 各个版本的 debian/kali installer initrd 都有 /lib + local dst_drivers_dir=$initrd_dir/lib/modules/$kver/kernel/drivers + + ( + cd $src_drivers_dir + for driver in $extra_drivers; do + # debian 模块没有压缩 + # kali 模块有压缩 + # 因此要有 * + if ! find $dst_drivers_dir -name "$driver.ko*" | grep -q .; then + echo "adding driver: $driver" + file=$(find . -name "$driver.ko*" | grep .) + cp -fv --parents "$file" "$dst_drivers_dir" + fi + done + ) + } + # 不用在 windows 判断是哪种硬盘控制器,因为 256M 运行 windows 只可能是 xp,而脚本本来就不支持 xp # 在 debian installer 中判断能否用云内核 create_can_use_cloud_kernel_sh can_use_cloud_kernel.sh @@ -3471,6 +3497,24 @@ EOF cp -f $tmp/websocketd/usr/bin/websocketd usr/bin/ fi + # 提前下载 pci-hyperv + # udeb 没有这个模块 curl https://deb.debian.org/debian/dists/stable/main/Contents-udeb-amd64.gz | zcat | grep pci-hyperv + # 缺少这个模块 azure 会找不到 nvme 硬盘 + # kali 的 pci-hyperv/pci-hyperv-intf 已嵌入到内核,不需要下载 + + # 用到 pci-hyperv 才需要下载,因为 + # 1. azure 普通网卡、scsi 硬盘不需要这个模块 + # 2. 没有这个模块会缺少加速网卡,但还有 hyperv 合成网卡,可以正常上网 + if { is_in_windows && wmic PATH Win32_PnPEntity where "DeviceID like 'VMBUS\\\\{44C4F61D-4444-4400-9D52-802E27EDE19F}\\\\%'" | grep -q . || + [ -d /sys/module/pci_hyperv ]; } && + # 可能在 host 或 controller 文件夹 + ! ls lib/modules/$kver/kernel/drivers/pci/*/pci-hyperv.ko* >/dev/null 2>&1 && + ! grep -Fq /pci-hyperv.ko lib/modules/$kver/modules.builtin; then + mkdir_clear $tmp/linux-image-$kver + download_and_extract_deb deb linux-image-$kver $tmp/linux-image-$kver + cp_debian_kali_driver $tmp/linux-image-$kver pci-hyperv + fi + # >256M 或者当前系统是 windows if [ $ram_size -gt 256 ] || is_in_windows; then sed -i '/^pata-modules/d' $net_retriever @@ -3505,27 +3549,11 @@ EOF # xen 还需要以下两个? # kernel/drivers/xen/xen-scsiback.ko # kernel/drivers/block/xen-blkback/xen-blkback.ko - # 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen + # udeb 没有这个模块 curl https://deb.debian.org/debian/dists/stable/main/Contents-udeb-amd64.gz | zcat | grep xen if [ -n "$extra_drivers" ]; then mkdir_clear $tmp/scsi download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi - relative_drivers_dir=lib/modules/$kver/kernel/drivers - - udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir - dist_drivers_dir=$initrd_dir/$relative_drivers_dir - ( - cd $udeb_drivers_dir - for driver in $extra_drivers; do - # debian 模块没有压缩 - # kali 模块有压缩 - # 因此要有 * - if ! find $dist_drivers_dir -name "$driver.ko*" | grep -q .; then - echo "adding driver: $driver" - file=$(find . -name "$driver.ko*" | grep .) - cp -fv --parents "$file" "$dist_drivers_dir" - fi - done - ) + cp_debian_kali_driver $tmp/scsi "$extra_drivers" fi fi @@ -3580,6 +3608,7 @@ get_net_drivers() { # 不用在 windows 判断是哪种硬盘/网络驱动,因为 256M 运行 windows 只可能是 xp,而脚本本来就不支持 xp # 而且安装过程也有二次判断 +# trans.sh 有同名方法 get_drivers() { # 有以下结果组合出现 # sd_mod @@ -3590,6 +3619,7 @@ get_drivers() { # xen_blkfront # ahci # nvme + # pci_hyperv # mptspi # mptsas # vmw_pvscsi diff --git a/trans.sh b/trans.sh index b256caa..afe4cd2 100644 --- a/trans.sh +++ b/trans.sh @@ -465,7 +465,7 @@ EOF } umount_all() { - dirs="/mnt /os /iso /wim /installer /nbd /nbd-boot /nbd-efi /nbd-test /root /nix" + dirs="/mnt /os /iso /wim /wim-tmp /installer /nbd /nbd-boot /nbd-efi /nbd-test /root /nix" regex=$(echo "$dirs" | sed 's, ,|,g') if mounts=$(mount | grep -Ew "on $regex" | awk '{print $3}' | tac); then for mount in $mounts; do @@ -5760,6 +5760,23 @@ is_list_has() { echo "$list" | grep -qFx "$item" } +# reinstall.sh 有同名方法 +get_drivers() { + ( + cd "$(readlink -f $1)" + while ! [ "$(pwd)" = / ]; do + if [ -d driver ]; then + if [ -d driver/module ]; then + basename "$(readlink -f driver/module)" + else + basename "$(readlink -f driver)" + fi + fi + cd .. + done + ) +} + get_windows_type_from_windows_drive() { local os_dir=$1 @@ -5950,14 +5967,21 @@ install_windows() { installation_type=$(get_selected_image_prop "Installation Type") fi + mount_iso_install_wim_to() { + local dir=$1 + + mkdir -p "$dir" + # shellcheck disable=SC2046 + wimmount "$iso_install_wim" "$image_index" "$dir" \ + $($is_swm && echo "--ref=$(dirname "$iso_install_wim")/$swm_ref") + } + # 挂载 install.wim,检查 # 1. 是否自带 sac 组件 # 2. 是否自带 nvme 驱动 # 3. 是否支持 sha256 # 4. Installation Type - # shellcheck disable=SC2046 - wimmount "$iso_install_wim" "$image_index" /wim/ \ - $($is_swm && echo --ref=$(dirname "$iso_install_wim")/$swm_ref) + mount_iso_install_wim_to /wim # 获取版本号 get_windows_version_from_windows_drive /wim @@ -6254,6 +6278,26 @@ install_windows() { add_driver_vmd fi + # 主网卡,有 IP 地址 + # root@localhost:~# get_drivers /sys/class/net/eth0 + # hv_netvsc + + # 加速网卡,无 IP 地址 + # root@localhost:~# get_drivers /sys/class/net/enP30832s1 + # mana + # pci_hyperv + + # vpci + # 对应 linux 的 pci_hyperv + # win10 ltsc 2021 boot.wim 没有 vpci.sys,导致找不到 azure nvme 硬盘 + # 要从 install.wim 提取 + # PE 下不用上网,因此不需要检测网卡是否用 pci_hyperv + if [ -d /sys/module/pci_hyperv ] && + get_drivers "/sys/block/$xda" | grep -qx pci_hyperv && + ! find_file_ignore_case /wim/Windows/System32/drivers/vpci.sys >/dev/null 2>&1; then + add_driver_vpci + fi + # 厂商驱动 case "$vendor" in aws) @@ -6936,6 +6980,88 @@ EOF cp_drivers $drv/azure } + # vpci + add_driver_vpci() { + info "Add drivers: vpci" + + mount_iso_install_wim_to /wim-tmp + + # 检查 install.wim 镜像是否有 vpci 驱动 + if vpci_sys=$(find_file_ignore_case /wim-tmp/Windows/System32/drivers/vpci.sys) && + wvpci_inf=$(find_file_ignore_case /wim-tmp/Windows/INF/wvpci.inf); then + + # 注册表文件 + from_system_hive="$(find_file_ignore_case /wim-tmp/Windows/System32/config/SYSTEM)" + from_software_hive="$(find_file_ignore_case /wim-tmp/Windows/System32/config/SOFTWARE)" + to_system_hive="$(find_file_ignore_case /wim/Windows/System32/config/SYSTEM)" + to_software_hive="$(find_file_ignore_case /wim/Windows/System32/config/SOFTWARE)" + + # TODO: alpine 3.24 发布后删除 + # hivex-perl 要从 edge/community 仓库下载 + alpine_mirror=$(grep '^http.*/main$' /etc/apk/repositories | sed 's,/[^/]*/main$,,' | head -1) + apk add --repository "$alpine_mirror/edge/community" \ + --force-non-repository \ + --virtual edge \ + hivex-perl + + # 获取当前生效的 wvpci.inf 文件 + # 得到 wvpci.inf_amd64_86afbe8940682d27 这样的文件名 + wvpci_inf_filename_with_hash=$(hivexget "$from_system_hive" 'DriverDatabase\DriverInfFiles\wvpci.inf' Active) + + # .inf .sys + cp -fv "$vpci_sys" "$(get_path_in_correct_case /wim/Windows/System32/drivers/)" + cp -fv "$wvpci_inf" "$(get_path_in_correct_case /wim/Windows/INF/)" + cp -rfv "$(get_path_in_correct_case "/wim-tmp/Windows/System32/DriverStore/FileRepository/$wvpci_inf_filename_with_hash/")" \ + "$(get_path_in_correct_case /wim/Windows/System32/DriverStore/FileRepository/)" + + # .cat + apk add binutils + for file in "$(get_path_in_correct_case '/wim-tmp/Windows/System32/CatRoot/{F750E6C3-38EE-11D1-85E5-00C04FC295EE}/')"*; do + if strings -e l "$file" | grep -Fiq vpci.sys; then + cp -fv "$file" "$(get_path_in_correct_case '/wim/Windows/System32/CatRoot/{F750E6C3-38EE-11D1-85E5-00C04FC295EE}/')" + fi + done + apk del binutils + + mkdir -p "$drv/vpci" + + # SOFTWARE + reg=$drv/vpci/software.reg + # shellcheck disable=SC2043 + for key in \ + "Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vpci.sys"; do + hivexregedit --export "$from_software_hive" "$key" >>"$reg" + done + hivexregedit --merge "$to_software_hive" "$reg" + + # SYSTEM + # 理论上要从 HKEY_LOCAL_MACHINE\SYSTEM\Select 的 Current/Default 获取 ControlSet 序号 + reg=$drv/vpci/system.reg + for key in \ + "ControlSet001\Services\EventLog\System\vpci" \ + "ControlSet001\Services\vpci" \ + "DriverDatabase\DeviceIds\VMBUS\{44C4F61D-4444-4400-9D52-802E27EDE19F}" \ + "DriverDatabase\DriverInfFiles\wvpci.inf" \ + "DriverDatabase\DriverPackages\\$wvpci_inf_filename_with_hash"; do + hivexregedit --export "$from_system_hive" "$key" >>"$reg" + done + # 这个注册表位置用 Tag 记录着驱动加载的顺序 + # HKEY_LOCAL_MACHINE\System\ControlSet001\Control\GroupOrderList 的 System Bus Extender + # 因此要删除 vpci 的 tag,避免 tag 跟其他驱动重复,而导致错误 + cat <>"$reg" +[\ControlSet001\Services\vpci] +"Tag"=- +EOF + hivexregedit --merge "$to_system_hive" "$reg" + + apk del edge + else + error_and_exit "vpci driver not found." + fi + + wimunmount /wim-tmp + } + add_driver_vmd() { # RST v20 不支持 11代 PCI\VEN_8086&DEV_9A0B support_v19=false