序
割とあるトラブルのようだが、適当な解説が見当たらないので、 初心者にもわかりやすいように触れておく。
なお、私が遭遇したタイミングは
- ディスクを別の(同じ構成で起動可能な)システムに移植
- BIOSをアップデート
であった。
そもそもgrub_callocとはなにか
Grubのメモリ確保用関数で、mm.cで定義されている。
なぜこいつがよくnot foundになるのかはよくわからない。
/*
* Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
* integer overflow.
*/
void *
grub_calloc (grub_size_t nmemb, grub_size_t size)
{
void *ret;
grub_size_t sz = 0;
if (grub_mul (nmemb, size, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
ret = grub_memalign (0, sz);
if (!ret)
return NULL;
grub_memset (ret, 0, sz);
return ret;
}対応を簡単に言うと
Grubを再インストールする。
実手順
x86_64なEFIシステムを前提として解説する。
まず、ターゲットシステム上で他のLinuxシステムを起動する。 これは、インストールに使ったライブディスクでもいいし、USBディスクにインストールされたLinuxシステムでも良い。
起動したらまずルートファイルシステムをマウントする。 まずはシステム上でルートを獲得する。
$ sudo bash -l
#
ルートファイルシステムがLUKSで暗号化されている場合、これを解除する必要がある。 まずはディスクを確認しよう。
# parted -l
ルートファイルシステムを含むパーティションを確認したら、それをマップする。
nvme0n1p2は適宜読み替えること。
# cryptsetup luksOpen /dev/nvme0n1p2 rescueroot
マップできたらこれをマウントする。
/dev/mapper/rescuerootはLUKSを使っていないのであれば、/dev/nvme0n1p2のようになるだろう。
# mount /dev/mapper/rescueroot /mnt
続いてEFI bootディレクトリをマウントする。
通常、ルートファイルシステムを持つディスクの第一パーティションである。
これもparted -lを用いて確認すること。
また、私のシステムだとEFIディレクトリは/boot/efiになっている。
これはManjaroの仕様だが、そうでないかもしれない。/bootの下にはあるはずなので、ターゲットシステムと同じ環境であるならばmount | grep bootして確認すると良い。これで/boot/efiであればターゲットシステムも/boot/efiである(つまりレスキューシステムから見ると/mnt/boot/efiである)はずだ。
そうでない場合、ls /mnt/bootして内容を確認する。
もし/mnt/boot自体がEFIディレクトリなのであれば、現時点で/mnt/bootは空であるはずだ。そうでない場合、/mnt/boot/efiのような空ディレクトリが存在するだろう。そこにマウントする。
# mount /dev/nvme0n1p1 /mnt/boot/efi
/dev, /sys, /procを再帰的にバインドマウントする。
面倒を避けるためすべてバインドするが、/dev及び/sys/firmware/efiが必須である。
# mount --rbind /dev /mnt/dev
# mount --rbind /proc /mnt/proc
# monut --rbind /sys /mnt/sys
レスキューするシステムにログイン(chroot)する。
# chroot /mnt
普段rootでもZshを使っているならば、Zshログインすることもできる。 (もちろん、しなくても良い)
# zsh -l
Grubを再インストールする。基本は次のコマンドである。
/dev/nmve0n1はターゲットシステムのルートファイルシステム及びEFIファイルシステム(ESP)があるディスク全体を指定するものであり、読み替えること。
# grub-install /dev/nvme0n1 --recheck --verbose
EFIファイルシステムがデフォルト(/boot/efi)でない場合、指定する必要がある。
# grub-install /dev/nvme0n1 --efi-directory=/boot/EFI --recheck --verbose
なお、EFIファイルシステムにはEFIディレクトリがあるが、そのEFIディレクトリではなくEFIファイルシステムのルートを指定する。