免重装将Linux迁移至新的SSD

Posted by wyj on January 15, 2023

这篇文章是免重装将Linux迁移至SSD的续集。时间过得真快啊,居然都快三年了,我还对那次迁移的经历记忆犹新呢!这次我的硬盘倒是没被dd,就是SSD只有128G的容量,我需要经常加以清理,并且把很多东西搬到机械硬盘上,才能勉强维持SSD还留有几个G的剩余空间。我这个学期开始时就不小心把SSD空间用尽了:我明明已经早有防范,把该死的又丑又难用的MATLAB装到机械硬盘上了,这个sb软件居然还是贼心不死,妄图用它的日志文件填满我的SSD,我一共就跑了这垃圾软件一个下午,它就排泄出来十几个GB的日志文件,消化功能是真好!

因此我打算换一块SSD,新的SSD有足足一个T的容量,可以说是取之不尽用之不竭的。而且我就可以把虚拟机(的disk image)们搬到SSD里了,这样虚拟机的速度会提升许多。本来我以为这会是和上一次迁移完全相同的,然而试图上手操作的时候,我才发现家里压根就没有能够把SSD通过USB线连到电脑上的硬盘盒$\dots$

这就麻烦多了,我被迫使用一套不同的方案来完成。这次我的大致思路是:先在机械硬盘上创建一个我旧SSD的镜像;然后把SSD拆下来换成新的,此时我的电脑就没有操作系统了,因此我需要事先制作一个Ubuntu的PE启动盘;通过U盘启动,挂载我的机械硬盘、以及新的SSD,完成新SSD的分区,把机械硬盘上旧SSD镜像中的数据拷到新SSD之中;然后安装grub,启动新SSD上的系统,完成整个迁移。

制作Ubuntu的PE启动盘

这居然如此傻瓜化,我完全没有花任何功夫就找到了教程,然后没有花任何功夫就按照教程完成了制作。Ubuntu安装时就已经自带“启动盘创建器”(usb-creator-gtk)这个应用了,我所做的全部事就是:插上U盘;打开“启动盘创建器”(它会自动识别并选中我刚插上的U盘),选择我事先准备好的Ubuntu ISO,点击“制作启动盘”按钮,然后PE就做好了!一共就用了几秒钟,实在是简单到让人难以置信。

话说为啥Ubuntu ISO是我“事先准备好”的呢?因为我有装完虚拟机之后保留ISO文件不删除的好习惯,而我去年就已经专门装过虚拟机来体验Ubuntu 22.04了,因此我有现成的Ubuntu ISO。

创建SSD的镜像

这也是再简单不过的事了,完全不用搜教程,每个用Linux的人应该都能轻松完成吧$\dots$假设SSD是/dev/sda,我要存放镜像文件的硬盘挂载在/mnt,就

sudo dd if=/dev/sda of=/mnt/ssd.img

这比cp要快多了,几分钟就跑完了。

但这还没完,光是创建个镜像可不够,我需要在PE系统里读取镜像里的内容,才能拷到新的SSD上。这我就真不知道该如何操作了,自己瞎折腾了半天也不知道该如何挂载disk image。但Google是万能的,教程

sudo losetup --partscan --find --show /mnt/ssd.img

创建新SSD的分区

旧SSD的镜像已经完成了,可以把它拔下来,换上新的SSD,从U盘启动了。我之所以选择Ubuntu的PE,一是我已经有了iso,制作起来比较方便;二是我比较熟悉Ubuntu的操作;三是Ubuntu ISO中自带的软件非常丰富,进行创建分区、复制文件、修改文件、安装grub的操作非常方便(还有等待复制的过程中,可以用自带的扫雷和空当接龙打发时间)。

这个Ubuntu PE已经自带gparted了,但这还不够:因为需要创建一个EFI的分区,这个分区需要格式化成FAT32的文件系统,我需要把旧系统的/boot/efi拷贝到这里来。因此需要额外安装读写FAT32文件系统的工具:

sudo apt install dosfstools mtools

使用gparted完成分区操作。在新的SSD上创建一个GPT格式的分区表;按照上次迁移时参考的教程来完成这次的分区,但是要改成/boot/efi单独分区,给个1G(其实100M就够了),格式化成FAT32,把flags从msftdata改成bootesp。再放一个分区/,格式化成ext4(我有点想借此机会尝试btrfs之类的新奇玩意儿,但想了想还是算了,暂时不想折腾)。

分区/格式化好之后,就可以拷贝文件了。先按照前面说的,用losetup挂载旧SSD的镜像,然后用sudo cp -rf -a一个目录一个目录地从镜像中拷贝过去。注意/media,/mnt,/cdrom,/dev,/proc,/sys这些特殊目录是不要拷贝的,只要创建空目录就行了。

安装了读写FAT32文件系统的工具之后,就可以再把旧系统的/boot/efi中内容,也cp到这个新的/boot/efi分区之中了。

安装grub,小修小补

等全部cp执行完之后,新系统就基本上准备好了。但还需要改一些东西:首先是/etc/fstab,需要把里面的//boot/efi的UUID,改成刚刚创建的对应新分区的UUID。使用sudo blkid即可看到这些新分区的UUID。

然后需要安装grub。首先要把/boot/efi分区挂载到/分区中的对应目录上去;假设/分区所在的盘是/dev/sdb,挂载在/mnt,执行

sudo grub-install --target=x86_64-efi --root-directory=/mnt --recheck --debug /dev/sdb

如果看到输出了Installation finished. No error reported.,就说明grub基本上安装“成功”了。但按照上次迁移的经验,还需要再多做一个修改:把/boot/grub/grub.cfg中旧的/分区的UUID,全部替换成新的/分区的UUID。

这样就完成了全部操作。只需要关机,拔掉启动盘,再开机,就自动进入新的SSD上安装的系统了,一切正常,一遍就完美成功了迁移。果然是一回生二回熟啊。

注意事项

不要在运行Ubuntu PE时触碰到U盘。这样会干扰接触,系统可能直接崩溃。这也是我操作过程中碰到的唯一的意外。