diff --git a/__pycache__/backend.cpython-36.pyc b/__pycache__/backend.cpython-36.pyc index b9e7183..9535b7c 100644 Binary files a/__pycache__/backend.cpython-36.pyc and b/__pycache__/backend.cpython-36.pyc differ diff --git a/backend.py b/backend.py index 45984b1..7124096 100644 --- a/backend.py +++ b/backend.py @@ -537,12 +537,25 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str, try: contents = os.listdir(efi_check_path) log_info(f" 当前 EFI 目录内容: {contents}") + + # 检查是否已有其他启动项 + existing_entries = [d for d in contents if d not in ['BOOT', 'boot']] + if existing_entries: + log_info(f" 发现已有启动项: {existing_entries}") + log_info(f" 建议:在BIOS中选择这些启动项之一,或继续使用新安装的GRUB") except Exception as e: log_warning(f" 无法列出 EFI 目录: {e}") else: log_warning(f"✗ EFI 目录不存在: {efi_check_path}") - # 第一次尝试:正常安装 + # 检测是否在Live环境中(通过检查/sys/firmware/efi/efivars是否存在且可访问) + is_live_env = not os.path.exists("/sys/firmware/efi/efivars") or \ + not os.listdir("/sys/firmware/efi/efivars") + + if is_live_env: + log_info(f"检测到 Live 环境(无法访问 EFI 变量),将使用 --removable 模式安装") + + # 第一次尝试:标准安装(带NVRAM注册) log_info(f"尝试 1/3: 标准 UEFI 安装(带 NVRAM)...") success, stdout, stderr = run_command( chroot_cmd_prefix + ["grub-install", "--target=x86_64-efi", @@ -553,20 +566,12 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str, ) if not success: - log_warning(f"标准安装失败,错误: {stderr}") + log_warning(f"标准安装失败") + log_debug(f"错误详情: {stderr}") - if "EFI variables are not supported" in stderr or "efibootmgr" in stderr: - log_info(f"尝试 2/3: 使用 --no-nvram 选项...") - success, stdout, stderr = run_command( - chroot_cmd_prefix + ["grub-install", "--target=x86_64-efi", - "--efi-directory=/boot/efi", "--bootloader-id=GRUB", - "--no-nvram", "--verbose"], - "安装UEFI GRUB(不带NVRAM)", - timeout=60 - ) - - if not success: - log_info(f"尝试 3/3: 使用 --removable 选项...") + # Live环境或NVRAM失败时,优先使用 --removable(创建 /EFI/Boot/bootx64.efi) + if "EFI variables are not supported" in stderr or "efibootmgr" in stderr or is_live_env: + log_info(f"尝试 2/3: Live环境模式(--removable,安装到 /EFI/Boot/bootx64.efi)...") success, stdout, stderr = run_command( chroot_cmd_prefix + ["grub-install", "--target=x86_64-efi", "--efi-directory=/boot/efi", @@ -574,25 +579,51 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str, "安装UEFI GRUB(可移动模式)", timeout=60 ) + + if success: + log_info(f"✓ 可移动模式安装成功!") + log_info(f" GRUB 已安装到 /EFI/Boot/bootx64.efi") + log_info(f" 这是UEFI通用回退路径,应该在大多数BIOS中自动识别") + + # 如果 removable 也失败,尝试 --no-nvram(标准路径但不注册NVRAM) + if not success: + log_info(f"尝试 3/3: 使用 --no-nvram 选项(标准路径但不注册启动项)...") + success, stdout, stderr = run_command( + chroot_cmd_prefix + ["grub-install", "--target=x86_64-efi", + "--efi-directory=/boot/efi", "--bootloader-id=GRUB", + "--no-nvram", "--verbose"], + "安装UEFI GRUB(不带NVRAM)", + timeout=60 + ) # 检查安装结果 if success: log_info(f"✓ GRUB EFI 文件安装成功") # 检查生成的文件 - efi_grub_path = os.path.join(mount_point, "boot/efi/EFI/GRUB") - efi_boot_path = os.path.join(mount_point, "boot/efi/EFI/Boot") + efi_paths_to_check = [ + os.path.join(mount_point, "boot/efi/EFI/GRUB"), + os.path.join(mount_point, "boot/efi/EFI/Boot"), + os.path.join(mount_point, "boot/efi/efi/GRUB"), # 某些系统使用小写 + os.path.join(mount_point, "boot/efi/efi/boot"), + ] - for path in [efi_grub_path, efi_boot_path]: + found_efi_file = False + for path in efi_paths_to_check: if os.path.exists(path): log_info(f" 检查目录: {path}") try: files = os.listdir(path) for f in files: - full = os.path.join(path, f) - size = os.path.getsize(full) - log_info(f" - {f} ({size} bytes)") + if f.endswith('.efi'): + full = os.path.join(path, f) + size = os.path.getsize(full) + log_info(f" ✓ EFI文件: {f} ({size} bytes)") + found_efi_file = True except Exception as e: log_warning(f" 无法列出: {e}") + + if not found_efi_file: + log_warning(f" 未找到任何 .efi 文件,安装可能有问题") else: log_info(f"BIOS 模式安装...") success, stdout, stderr = run_command( @@ -679,11 +710,36 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str, if is_uefi: log_step("UEFI 修复完成提示") log_info(f"GRUB EFI 文件已安装到 EFI 分区") - log_info(f"如果无法启动,请检查:") - log_info(f" 1. BIOS/UEFI 设置中是否启用了 UEFI 启动模式") - log_info(f" 2. 启动顺序中是否有 'GRUB' 或 'Linux' 选项") - log_info(f" 3. 安全启动 (Secure Boot) 是否已禁用") - log_info(f" 4. EFI 分区中的文件: /EFI/GRUB/grubx64.efi") + + # 检测安装模式并给出相应提示 + efi_boot_path = os.path.join(mount_point, "boot/efi/EFI/Boot/bootx64.efi") + efi_grub_path = os.path.join(mount_point, "boot/efi/EFI/GRUB/grubx64.efi") + + if os.path.exists(efi_boot_path): + log_info(f"") + log_info(f"【重要】使用可移动模式安装 (/EFI/Boot/bootx64.efi)") + log_info(f"启动方法:") + log_info(f" 1. 在BIOS中选择 'UEFI Hard Drive' 或 'UEFI OS' 启动") + log_info(f" 2. 如果有多块硬盘,选择正确的硬盘 (通常是第一块)") + log_info(f" 3. 确保启动模式为 UEFI(不是 Legacy/CSM)") + elif os.path.exists(efi_grub_path): + log_info(f"") + log_info(f"【重要】使用标准模式安装 (/EFI/GRUB/grubx64.efi)") + log_info(f"启动方法:") + log_info(f" 1. 在BIOS启动菜单中选择 'GRUB' 或 'Linux' 启动项") + log_info(f" 2. 如果没有该选项,需要手动添加启动项") + log_info(f" 路径: \\EFI\\GRUB\\grubx64.efi") + + log_info(f"") + log_info(f"故障排除:") + log_info(f" • 如果仍无法启动,请检查:") + log_info(f" - BIOS 是否设置为 UEFI 启动模式(非 Legacy/CSM)") + log_info(f" - 安全启动 (Secure Boot) 是否已禁用") + log_info(f" - EFI 分区格式是否为 FAT32") + log_info(f"") + log_info(f" • 如果BIOS中有旧启动项(如 BBT-TMS-OS),请尝试:") + log_info(f" - 选择该启动项可能可以启动(如果它指向正确的系统)") + log_info(f" - 或删除旧启动项,让BIOS重新检测") return True, ""