如何在意外删除所有内核后恢复系统?

我试图删除旧的内核,但我可能已经删除了我Ubuntu 11.04笔记本上的所有内核。是否有办法通过USB启动或将硬盘挂载到另一个系统来修复这个问题?

5个回答

启动到一个Live CD(或Live USB),挂载一些系统,chroot进入其中并安装内核。成功安装内核后,卸载文件系统。
  1. 打开终端
  2. 挂载Ubuntu分区:sudo mount /dev/sdXY /mnt
  3. 挂载一些特殊分区:

    sudo mount --bind /dev /mnt/dev
    sudo mount --bind /proc /mnt/proc
    sudo mount --bind /sys /mnt/sys
    
  4. (可选) 当您连接到网络时,使用Live环境的DNS服务器(否则可能无法解析主机名):

    cp /etc/resolv.conf /mnt/etc/resolv.conf
    
  5. 切换到/mnt目录: sudo chroot /mnt
  6. 安装Linux内核:apt-get install linux-image-generic(不需要sudo,因为在chroot之后您是root用户)
  7. 成功安装内核后,退出chroot并卸载一些文件系统:

    exit
    sudo umount /mnt/sys
    sudo umount /mnt/proc
    sudo umount /mnt/dev
    sudo umount /mnt
    
  8. 重新启动并移除CD或USB:sudo reboot

这正是我会建议的。我找不出它为什么行不通的理由。 - Oli
好的,谢谢确认。我也添加了最后的步骤,卸载/mnt。通常Ubuntu会自动处理卸载/同步文件系统,但我认为这样更干净。 - Lekensteyn
如果我们使用RAID10,我们如何恢复数据? - Mahesh Katta
1@MaheshKatta 你需要先挂载RAID。所以,不要执行第二步(挂载单个驱动器),而是要映射一个/dev/mdxxx的驱动器 - 假设它是mdadm。 - Oli
当我使用chroot进入mnt目录时,我无法访问互联网。我该如何解决这个问题? - James
5@James 编辑 /etc/resolv.conf 文件(如果它是一个符号链接则删除),并在其中添加类似 nameserver 8.8.8.8 的内容(谷歌公共 DNS 服务器)。如有需要,请进行替换。 - Lekensteyn
我和詹姆斯有同样的问题。无法通过apt-get连接到互联网。但浏览器却可以正常工作。即使使用8.8.8.8也是如此。 - Peter Raeves
3算了。看起来我必须在chroot本身中编辑文件。也许你应该在进入chroot之前添加答案中的cp /etc/resolv.conf /mnt/etc/resolv.conf。这对我来说有效。 - Peter Raeves
在作者指出之前,我无法执行apt-get install linux-image-generic命令,直到我复制了resolv.config文件。注意:在执行chroot进入/mnt之前,我必须先执行复制resolv.config文件的命令。否则会出现“没有此文件或文件夹”的异常。 - MUG4N
当我复制resolv.conf文件时,出现了一个错误cp: not writing through dangling symlink。我通过使用命令sudo cp --remove-destination <path to resolv.conf> /mnt/etc/.来解决了这个问题。 - Nick Desaulniers
另外,如果您更改了实际文件而不是符号链接,在重新启动后,您可以使用sudo dpkg-reconfigure resolvconf命令,然后重新启动以恢复resolv.conf文件。 - Nick Desaulniers
sudo chroot /mnt 不起作用。 ubuntu@ubuntu:/bin$ sudo chroot /mnt chroot: 无法运行命令 '/bin/bash':没有那个文件或目录我尝试使用另一个安装在另一个分区上的操作系统,还尝试使用Live USB。/etc/resolve.conf 的内容如下- `# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)

DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 127.0.1.1`
- alhelal
工作得太完美了!你救了我的命。谢谢!!!! - PlayHardGoPro

这个扩展过程包括了可能出现的大部分问题,包括在chroot中无法连接到互联网,不知道要安装哪个内核包(在Ubuntu 12.10之前,并不总是linux-image-generic),在一开始就不知道哪个分区甚至哪个物理驱动器包含/文件系统,以及有一个单独的/boot分区。

我没有参考其他任何程序来写这篇文章,但你会注意到一些相似之处。我确实基于这里的程序(虽然那些指令是给完全不同的情况用的,但我对其进行了广泛改编,只复制了一些命令,而非整段文字)。

您删除了所有的内核包,而Ubuntu在没有安装内核的情况下无法启动。所以解决办法是从一个活动的CD/DVD/USB中引导,通过chroot进入已安装的系统,并在其中安装一个内核。

  1. Boot from an Ubuntu live CD/DVD or live USB flash drive.

  2. Select Try Ubuntu (not Install Ubuntu).

  3. When the desktop comes up, make sure you are connected to the Internet. If you are not, connect to the Internet. One way to see if you are connected to the Internet is to open a web browser. You can even follow the rest of the instructions by bringing this Ask Ubuntu answer up in your web browser, in the live CD/DVD/USB system. I strongly recommend doing that.

  4. Open a Terminal window with Ctrl+Alt+T.

  5. In the Terminal window, run this command to list your partitions:

     sudo parted -l
    

    You'll see something like this (but it won't be exactly like this):

    Model: VMware, VMware Virtual S (scsi)
    Disk /dev/sda: 21.5GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    
    Number  Start   End     Size    Type      File system     Flags
     1      1049kB  20.4GB  20.4GB  primary   ext4            boot
     2      20.4GB  21.5GB  1072MB  extended
     5      20.4GB  21.5GB  1072MB  logical   linux-swap(v1)
    
    
    Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0
    has been opened read-only.
    Error: Can't have a partition outside the disk!
    
  6. Examine the output you got, to determine the device name of the partition that contains the / filesystem of the Ubuntu system that is installed on the hard drive (that you are repairing).

    • If you only have one ext4 partition, that's the one.

    • If you have more than one ext4 partition, it's probably the first one. However, if the first one is very small--less than a gigabyte--then that might be a separate /boot partition (remember that one too).

      Please note that whether or not boot is listed under Flags has very little to do with whether or not a partition is a separate /boot partition. My system, whose information is listed above, does not have a separate /boot partition.

    • The device name for the partition starts with the device name for the physical drive, stated immediately after Disk in the second line. Then just add the partition number to the end of that. So, the device name for the partition that contains my / filesystem is /dev/sda1. Here are the two lines where I found that information:

      Disk /dev/sda: 21.5GB
       1      1049kB  20.4GB  20.4GB  primary   ext4            boot
    • If you have more than one physical drive, you'll get more than one listing like what is shown above. But unless you have another Unix-like system installed, you probably will only have one drive that contains ext4 partitions, at least without having created them intentionally on another drive. If you do have multiple drives with ext4 partitions, then the ext4 partition that contains your / filesystem is probably on a drive that also contains a linux-swap partition.

    • It's possible that your Ubuntu system's / filesystem is on a partition of type other than ext4. When this happens, it's almost always ext3, and almost always on a quite old system. It's very uncommon for this to be the case, unless you intentionally set things up this way yourself.

    Remember the device name of the partition that contained your / filesystem (or write it down). If it's different from /dev/sda1, then you'll replace /dev/sda1 with it in the steps below.

    (If it looked like you have a separate /boot partition, remember the device name for that, too.)

  7. Mount the / filesystem to /mnt, and mount its /dev filesystem:

    sudo mount /dev/sda1 /mnt
    sudo mount --bind /dev /mnt/dev
  8. Check if the broken Ubuntu system you're repairing has a separate /boot partition which must be mounted separately. (If you are sure it does not, you can skip this.)

    To check, run:

    ls /mnt/boot
    

    If there is output (like grub memtest86+.bin memtest86+_multiboot.bin, but not necessarily exactly that), then the broken system's /boot is on the same partition as its / and you don't have to mount anything to access it.

    But if there is no output, then you will have to mount the /boot filesystem:

    sudo mount BOOT-PARTITION /mnt/boot

    Replace BOOT-PARTITION with the device name of the /boot partition (see step 6 above).

  9. chroot into the broken system, mount the remaining important virtual filesystems, and set some important environment variables:

    sudo chroot /mnt
    mount -t proc none /proc
    mount -t sysfs none /sys
    mount -t devpts none /dev/pts
    export HOME=/root
    export LC_ALL=C
    
  10. Determine if Internet access works from within the chroot by pinging some reliable host that is known to respond normally to pings:

    ping -c 5 www.google.com
    

    You should see something like this:

    PING www.l.google.com (74.125.131.147) 56(84) bytes of data.
    64 bytes from vc-in-f147.1e100.net (74.125.131.147): icmp_req=1 ttl=44 time=61.3 ms
    64 bytes from vc-in-f147.1e100.net (74.125.131.147): icmp_req=2 ttl=44 time=62.3 ms
    64 bytes from vc-in-f147.1e100.net (74.125.131.147): icmp_req=3 ttl=44 time=61.8 ms
    64 bytes from vc-in-f147.1e100.net (74.125.131.147): icmp_req=4 ttl=44 time=63.8 ms
    64 bytes from vc-in-f147.1e100.net (74.125.131.147): icmp_req=5 ttl=44 time=66.6 ms
    
    --- www.l.google.com ping statistics ---
    5 packets transmitted, 5 received, 0% packet loss, time 4006ms
    rtt min/avg/max/mdev = 61.367/63.212/66.608/1.897 ms
    
    • If it looks mostly like that, and the number before % packet loss is less than 100, then the Internet connection in the chroot is working:

      5 packets transmitted, 5 received, 0% packet loss, time 4006ms

      It's working, so you can skip step 11.

    • If it looks mostly like that, and the number before % packet loss is 100, the connection needs troubleshooting. Make sure the connection on the live CD system (for example, through a web browser, or by running the same command in a separate, non-chrooted Terminal tab/window) works. Make sure you're typing the command correctly. Use www.google.com if you haven't been.

    • If the output doesn't look like the above at all, but instead says ping: unknown host www.google.com, then networking isn't working yet in the chroot.

  11. Set up networking in the chroot. Skip this step unless you got an unknown host error in step 10 above.

    To set up networking, back up the broken system's hosts file, and copy over the live CD system's hosts and resolv.conf files. (You don't have to back up the broken system's version of resolv.conf, as that file is automatically regenerated on-the-fly.)

    Open a new Terminal tab (Ctrl+Shift+T) or, if you prefer, a new Terminal window (Ctrl+Shift+N, or just Ctrl+Alt+T). Run these commands in it:

    sudo cp /mnt/etc/hosts /mnt/etc/hosts.old
    sudo cp /etc/hosts /mnt/etc/hosts
    sudo cp /etc/resolv.conf /mnt/etc/resolv.conf
    exit
    

    (The exit command at the end closes the new tab/window.)

    Repeat step 10 above to make sure Internet access works now from within the chroot. It should.

  12. Figure out which kernel package should be installed. Usually, this will be linux-image-generic. But not always.

    If you're not sure which to install, it will depend partly on which Ubuntu release you have installed, and partly on other information. If you are not sure which Ubuntu release you have installed, find out by running this command (in the chroot, not in a separate Terminal window/tab):

    lsb_release -r
    
    • On Ubuntu 12.10 (the next Ubuntu release, currently in development), it always will be linux-image-generic. (See this, this, and this.)

    • On Ubuntu 12.04 LTS, likely possibilities are linux-image-generic and linux-image-generic-pae. (Unlike previous versions, 12.04 no longer has separate server and desktop kernels.)

      • If the installed Ubuntu system (that you are fixing) is the 64-bit version, use linux-image-generic. (linux-image-generic-pae only applies to 32-bit systems.)

        It's possible to have a 32-bit Ubuntu system installed on a 32-bit or 64-bit computer. Furthermore, you might be using a 32-bit or 64-bit live CD to fix a 32-bit installed system. So if you don't know whether the installed Ubuntu system is 32-bit or 64-bit, check by running this command (in the chroot, not in a separate Terminal window/tab):

        dpkg-architecture -qDEB_HOST_ARCH_BITS
        

        The output will be either 32 or 64.

        (Please note that uname -m is not a correct way to find this information, because even when run in the chroot, that will tell you the architecture of the running kernel, which is the live CD system's kernel and not the installed (broken) system's kernel.)

      • If the installed Ubuntu system (that you are fixing) is the 32-bit version, the best kernel to use will depend on how much RAM you have. I recommend:

        • linux-image-generic if you have less than 3 GB of RAM
        • linux-image-generic-pae if you have 3 GB of RAM or more.

        (This is how Ubuntu's installer chooses which one to set up, ever since the installer gained the ability to install PAE kernels. See the resolution to this bug. If you want to learn what PAE is, see this Wikipedia article. If you want to learn about PAE in Ubuntu, see this Ubuntu wiki page.)

        If you don't know how much RAM you have, run this command to find out:

        grep MemTotal /proc/meminfo
        

        That is listed in kilobytes. To convert to gigabytes, divide by 1,048,576 (10242).

        • 3 gigs = 3,145,728 kB
    • On Ubuntu releases before 12.04, likely possibilities are linux-image-generic, linux-image-generic-pae, and linux-image-server.

      • If you're running an Ubuntu Server system, use linux-image-server.
      • Otherwise, follow the advice above for 12.04 systems.
  13. This is the moment you've been waiting for! Install a kernel in the broken system.

    (Like before, except where explicitly indicated otherwise, these commands are run in the chroot, not in a separate Terminal window/tab.)

    apt-get update
    apt-get -y install linux-image-generic

    Replace linux-image-generic with whatever other kernel package you decided to install in step 12 above, if different.

  14. If you had to perform step 11 to set up networking in the chroot, restore the old hosts file. If you skipped step 11, skip this step too.

    To restore it, run this command:

    cp /etc/hosts.old /etc/hosts
    
  15. Unmount filesystems, exiting out of the chroot:

    umount /proc || umount -lf /proc
    umount /sys /dev/pts
    exit
    sudo umount /mnt/dev /mnt
    
  16. Shut down the live CD/DVD/USB system, removing the live CD/DVD or USB flash drive. Boot into the system installed on the hard drive, that you just repaired. You've installed a kernel package in it (and as part of the installation, the kernel it provides will be added back to the GRUB2 boot menu). If everything worked correctly, your system should boot without problems. (I think it's possible that it will take a little longer to boot than usual, this time.)

免责声明:我没有在每个可能的Ubuntu系统上测试上述过程,所以可能存在我尚未发现的错误。
将来,我建议始终保留两个内核。这样做是有好处的,因为如果其中一个由于任何原因停止工作(您可以在GRUB2启动菜单中选择另一个),您还有另一个可供选择。此外,如果您打算保留两个内核,并且意外卸载了比您打算的多一个并重新启动,您仍然有一个可供引导。

1这可能是我读过的关于如何在Linux中完成复杂任务的最好的书面解释。谢谢。 - ZincX
3非常感谢你,Eliah!在我愚蠢地删除了所有的Linux映像后,你拯救了我。唯一的小问题出现在这一步:sudo cp /etc/resolv.conf /mnt/etc/resolv.conf时,我遇到了一个"cp: not writing through dangling symlink `/mnt/etc/resolv.conf'"错误。我在一个帖子中找到了解决方法,并按照其中一个回帖者的指示,在"cp /etc/resolv.conf /mnt/etc/resolv.conf"之前执行了"rm /mnt/etc/resolv.conf"来解决悬空符号链接的问题。 - user168318
@xcal400 /etc/resolv.conf 现在由 resolvconf 管理,当使用 NetworkManager 时会自动生成,并且可以安全地使用 rm /etc/resolv.conf 进行删除,正如你所发现的那样。 - Lekensteyn
谢谢,很好。一个废话。我能否跳过从互联网下载内核映像而使用离线可用的内核包,或者使用运行的Live CD? - nmxprime
3这个应该是被接受的答案。谢谢! - Jean-Michel Garcia
这些步骤对我来说没有生成Ubuntu 14.04 Trusty的grub菜单项。我目前正在使用grub命令行进行引导。请参考这个新问题的详细信息:http://stackoverflow.com/questions/34753352/how-to-regenerate-grub-menu-entries-on-ubuntu-14-04-trusty-after-deleting-all-ke - Champ
嗯...读完这段话,我意识到我再也不应该玩弄我的内核了,而是应该下载一个新的iso文件,按下两个按钮重新安装Linux,同时对自己大喊“干得好,白痴”...总的来说,今天是个不错的一天... - PaulB
这绝对是我读过的最好、最详尽的答案之一,真的救了我一命。在搞砸了一个非常重要的虚拟机后,它帮了我大忙。如果我可以补充一点,这个方法也适用于安装在LVM卷上的系统,只需确保将正确的LVM卷挂载到“/mnt”目录下即可。 - Javier Caselli
还需要额外的步骤来修复grub。 - Joel Coehoorn
@JoelCoehoorn,你是否遇到过这样的情况?所有内核被卸载后,你按照这个步骤进行操作,看起来步骤有效,但系统无法启动。然后你重新安装了GRUB,系统又恢复正常了。如果是这样,是否有可能GRUB本身也出了问题呢?我不认为删除所有内核会导致GRUB出错。当内核安装时,GRUB会自动配置以启动新的内核。在我按照这个步骤操作时,我从未重新安装过GRUB,但它总是有效。这是我第一次听到需要重新安装GRUB的反馈,请告诉我更多细节。 - Eliah Kagan
Grub被更新了,但没有内核存在。它只设置了memtest启动选项。修复后,安装了4.4.0-53,但grub看不到它。 - Joel Coehoorn
@JoelCoehoorn 我在16.04上尝试重现了这个问题,但是即使在我删除内核后(但在重新启动之前)运行update-grub,GRUB也能看到我的内核,并且没有从chroot中再次运行update-grub。安装任何内核包都应该更新GRUB,或者当你的内核元包引入了一个新的内核包时,你必须手动执行更新。你有编辑过GRUB配置文件吗?在chroot中安装了linux-image-generic还是其他包?这是什么时候发生的?4.4.0-53已经不再是16.04最近的两个内核版本之一了。(顺便说一下,我在[chat]里,如果那样方便的话。) - Eliah Kagan
我已经上床睡觉了,否则聊天帮助就太好了 :) 不过我的问题已经解决了。在安装内核时,我不得不使用一个--reinstall开关,然后grub才能检测到它。不知怎么的,它们只安装了一部分。即使如此,系统仍然无法启动。这个系统使用了一个LVM根分区,而grub没有正确地将其放入menu.lst中。一旦我手动编辑了那个文件,一切都好起来了。 - Joel Coehoorn
适用于Ubuntu 17.10。 - Te Ri
这些指示是否仍适用于Ubuntu 18.04 Bionic Beaver LTS?顺便说一句,作为出色技术写作的例子,你的指示非常出色。(我曾经是一名技术撰稿人。) - Hedley Finger
我在使用grub时遇到了问题,它无法找到新的映像,可能是因为我需要在chroot环境中挂载efi或其他东西。但是通过恢复模式,我成功地启动了一个旧的内核,并手动更新了grub。之后重新启动就正常工作了。(Ubuntu 19.10) - SO_fix_the_vote_sorting_bug

我只是想分享一下今天升级到Willy的经历。我进行了一些清理工作,结果只剩下memtest了。通过谷歌搜索,我了解到我已经删除了内核。我的一个限制是网络速度慢,所以无法下载完整的ISO文件。因此,我使用了Ubuntu Minimal CD(仅40MB)并启动它。在检测到硬件选项后(这帮助我连接到无线网络),我选择了shell选项。我按照@Lekensteyn的指示操作,并成功了。不过有几点需要注意:在进入chroot之前,你必须复制resolv.conf,否则你的DNS将会出问题,而且由于登录用户是root,所以不需要在任何地方使用sudo。
我知道这个问题很旧,但我认为添加这个答案对那些遇到类似问题的人会有价值。

当我移除我的内核时,在Ubuntu论坛上找到了这个解决方案。我按照每一步操作,系统得以恢复。希望对你有所帮助。
Chroot可能会起作用,chroot意味着当你启动一个系统时,你改变根文件系统。例如,你从一张Live CD启动,但你将根目录“/”更改为你的Ubuntu安装位置。
假设你的Ubuntu安装在/dev/sda2上,你可以尝试以下命令:
sudo mount /dev/sda2 /mnt
sudo cp /etc/resolv.conf /mnt/etc/
sudo cp /etc/hosts /mnt/etc/
sudo mount --bind /dev/ /mnt/dev
sudo chroot /mnt
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
export HOME=/root
export LC_ALL=C
dbus-uuidgen > /var/lib/dbus/machine-id
dpkg-divert --local --rename --add /sbin/initctl
ln -s /bin/true /sbin/initctl

现在你的根目录“/”位于/dev/sda2上,请尝试安装内核。
apt-get update
apt-get install linux-image-2.6.32-26-generic
update-initramfs -cv -k all
update-grub

我在这里做了一些猜测,因为我以前从未做过这个,但应该差不多就是这样。不知道你是否会收到一些fstab错误警告(比如找不到根目录)。
现在你需要清理一些东西并卸载已挂载的分区: 代码:
rm /etc/resolv.conf
rm /etc/hosts
rm /var/lib/dbus/machine-id
rm /sbin/initctl
dpkg-divert --rename --remove /sbin/initctl
umount /proc # if this doesn't work try umount -lf /proc
umount /sys
umount /dev/pts
exit
sudo umount /mnt

你可以重新启动看看是否有效。
帖子的URL:http://art.ubuntuforums.org/showthread.php?t=1688928

为什么要替换/etc/hosts并删除/sbin/initctl?它们存在是有原因的。 - Lekensteyn
这似乎是基于LiveCDCustomization的; 对于修复已安装的系统,有些步骤是不必要的。特别是,不需要对/sbin/initctldbus-uuidgendpkg-divert做任何操作。你可能需要替换/etc/hosts以连接到互联网,但通常情况下不需要,如果确实需要,应该将原始文件恢复回来。在已安装的系统上(而不是从引导然后解压缩squashfs文件系统的Live CD),安装内核后不必运行update-initramfs甚至update-grub - Eliah Kagan
此外,由于此过程不安装任何内核元包,除非安装了元包,否则内核可能无法正确更新。此外,linux-image-2.6.32-26-generic 对大多数人来说并不是适合安装的内核。 - Eliah Kagan

昨天我从Trusty14.04中删除了旧内核(FTR:我没有删除最近的两个!),结果我的系统无法启动。GRUB显示:
Error: File not found
Error: You need to load the kernel first

不知道为什么。
然后我按照Eliah Kagan的优秀指南从光盘中安装了linux-image-generic。它确实安装了150 MB的新内核,但可悲的是这并没有解决问题。
幸运的是,我找到了这个页面。使用Boot-Repair工具,我的系统恢复正常了。