事情是这样的:

我分别用两个硬盘装了Ubuntu系统,其中有一个硬盘A的Ubuntu是默认启动项,另一个硬盘B中的Ubuntu系统可以在启动时进行选择。

现在我直接把硬盘A取走了,再开机,于是乎,启动不了了。。。。

开机之后直接进入grub>界面。。。

先说正题

我的想法是,能不能就在grub下实现启动(理论上肯定是可以的!),不借助所谓的Live CD或者USB环境。

下面是具体步骤:

Grub启动

  1. 列出所有分区

    grub> ls
    

    这将列出所有可用的设备和分区,例如:

    (hd0) (hd0,gpt1) (hd0,gpt2)
    

    也可能不是这样,但类似。

  2. 查找/boot目录: 检查每个分区,找到包含 /boot 目录的分区:

    grub> ls (hd0,gpt1)/
    grub> ls (hd0,gpt2)/
    

    看看 /boot 目录在哪个分区下,比如是在(hd0,gpt2)下面,查看(hd0,gpt1)下面发现只有efi文件夹,这个是之后修复efi时需要挂载的

    进入 /boot 后,应该看到类似以下的文件列表:

    vmlinuz initrd.img
    

    也可能是:vmlinuz-linux和initramfs-linux.img之类的文件

  3. 获取启动设备UUID: 在GRUB命令行中,可以使用 ls -l 命令来查看设备的UUID。例如:

    grub> ls -l (hd0,gpt2)
    

    这将列出分区的详细信息,包括UUID,这个UUID就可以作为设备名的标识

  4. 挂载启动: 加载内核并指定根文件系统:

    grub> linux (hd0,gpt2)/boot/vmlinuz root=UUID=your-uuid-here
    grub> initrd (hd0,gpt2)/boot/initrd.img
    grub> boot
    

    注意vmlinuz可能会有区别,vmlinuz或者vmlinuz-linux;initrd.img也可能有区别,但肯定是init前缀加上img后缀。

修复Grub

注意需要确认磁盘的设备名,因为已经启动了Ubuntu,可以通过 lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL 来查看:

lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL

得到的结果类似下面这样:

NAME        FSTYPE     SIZE MOUNTPOINT                   LABEL
loop0       squashfs  63.5M /snap/core20/2015            
loop1       squashfs     4K /snap/bare/5                 
loop2       squashfs  74.1M /snap/core22/1033            
loop3       squashfs 349.7M /snap/gnome-3-38-2004/143    
loop4       squashfs    64M /snap/core20/2318            
loop5       squashfs   497M /snap/gnome-42-2204/141      
loop6       squashfs  91.7M /snap/gtk-common-themes/1535 
loop7       squashfs  40.9M /snap/snapd/20092            
loop8       squashfs  12.3M /snap/snap-store/959         
loop9       squashfs  38.8M /snap/snapd/21759            
loop10      squashfs  74.2M /snap/core22/1380            
loop11      squashfs  54.2M /snap/snap-store/558         
loop12      squashfs 485.5M /snap/gnome-42-2204/126      
loop13      squashfs 349.7M /snap/gnome-3-38-2004/140    
nvme0n1              931.5G                              
├─nvme0n1p1 vfat       193M             
└─nvme0n1p2 ext4     931.3G /    

其中的vfat理论上讲就是efi所在的位置,如果不确定,可以在一开始grub>命令的时候ls查看。

  1. 创建挂载点(如果不存在)
sudo mkdir -p /boot/efi
  1. 挂载EFI分区
sudo mount /dev/nvme0n1p1 /boot/efi
  1. 验证挂载
df -h | grep /boot/efi

应该看到以下的输出:

/dev/nvme0n1p1    200M  100M  100M  50% /boot/efi
  1. 安装GRUB到指定的设备
sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB /dev/nvme0n1
  1. 生成GRUB配置文件
sudo update-grub
  1. 重启系统
sudo reboot

答疑解惑

GRUB是什么东西,能干嘛?

GRUB(GNU GRand Unified Bootloader)是一个通用的引导加载程序,用于启动操作系统。它可以引导多种操作系统,包括Linux、Windows和BSD。GRUB的主要功能和特点包括:

  1. 多重引导:允许用户从多个操作系统中选择要启动的系统。
  2. 配置文件:使用一个配置文件(通常是grub.cfg),用户可以在该文件中定义引导菜单、内核参数等。
  3. 命令行界面:提供一个命令行界面,用户可以在引导过程中输入命令,以便进行手动引导或修复操作系统。
  4. 模块化设计:可以通过加载模块来扩展功能,如支持不同文件系统和设备。

initramfs-linux.img是什么东西?

initramfs(initial RAM filesystem)是一个临时的根文件系统,用于在系统启动时加载必要的驱动和模块。initramfs-linux.img文件通常包含以下内容:

  1. 内核模块:用于支持启动时所需的硬件。
  2. 启动脚本:用于初始化系统并挂载实际的根文件系统。
  3. 用户空间工具:如busybox,用于提供基本的命令行工具。

在不同的Linux发行版上,这个文件的命名可能会有所不同。例如:

  • 在Ubuntu上,通常命名为initrd.img-<kernel-version>,例如initrd.img-5.4.0-42-generic
  • 在Arch Linux上,通常命名为initramfs-linux.img

vmlinuz-linux是什么?

vmlinuz是Linux内核的压缩版本,通常用于引导系统。文件名中的vmlinuz表示“压缩的虚拟内核”(compressed virtual kernel)。不同的Linux发行版可能使用不同的命名方式:

  1. vmlinuz:这是大多数发行版使用的通用名称,如Ubuntu和Debian。
  2. vmlinuz-linux:在一些发行版中可能会使用更具体的名称,以区分不同的内核版本或配置,如Arch Linux。

总结

  • GRUB:引导加载程序,用于选择和启动操作系统,支持多重引导和命令行界面。
  • initramfs-linux.img:初始RAM文件系统,包含启动时所需的内核模块和脚本,用于加载实际的根文件系统。在不同的发行版上可能有不同的命名,如Ubuntu的initrd.img-<kernel-version>
  • vmlinuz-linux:压缩的Linux内核,用于引导系统。通常在不同的发行版上有不同的命名,如Ubuntu的vmlinuz或Arch Linux的vmlinuz-linux