手続き型音楽の日常

関数型音楽に乗り換えたい

内臓HDDのUbuntuをUSBメモリのGrub2から叩く。

非常に初歩的なことですが、かなり調べて納得がいったようないってないようなところまで行きついたので、メモっておきます。

今回は 起動できればいい というスタンスで行くので、詳しいことは全くわかりません。これから勉強します。

環境

今回試したのは、以下の環境。

目標は簡単なことです。 USBのGrub2 から SATAのHDDのUbuntuを起動する だけです。普通はしないけど。

なんでこんなまどろっこしいことがしたいかというと、Ubuntuを内臓HDDにインストールしたまではよかったんですけど、UEFIが入っているはずのGrub2を認識してくれないのです。もしかしてUEFIモード対応のBIOSだったのかこれ?

順序

あくまで理論的な話。

Grub2が起動すると、規定ではOSを選ぶメニューが表示されます。

f:id:yuzutan_hnk:20170217014440j:plain:w300

このとき、メニューで「c」キーを押すとシェル画面に遷移します。この画面ではbashライクな初歩的なコマンドにより、ドライブの中身を確認したりOSをブートさせたりできます。

f:id:yuzutan_hnk:20170217014441j:plain:w300

この機能を使って、実際にUSBのGrub2のメニューには出てこない、内臓HDDのUbuntuを起動させます。

手順

まずは確認

まずは、ディスクの名前を確認します。これは ls コマンドで一覧を取得できます。

f:id:yuzutan_hnk:20170217014442j:plain:w300

grub> ls
(memdisk) (hd0) (hd0,msdos1) (hd1) (hd1,gpt4) (hd1,gpt3) (hd1,gpt2) (hd1,gpt1) (hd2) (hd2,msdos1)

現在起動に使っているUSBは (hd0) として認識されています。試しに、 (hd0) の情報を表示してみます。

f:id:yuzutan_hnk:20170217014443j:plain:w300

なんか、大量にエラーが出ていますが、今回は 起動ができればいい ので無視します。一応、最後の一文がそれっぽい結果になっています。

grub> ls (hd0)
Device hd0: No known filesystem detected - Sector size 512B - Total size 7834624KiB

確かに容量が8GBに近いですので、起動USBと考えて間違いないでしょう。

次に、起動するUbuntuの入ったHDDを確認します。

たぶん見るからに (hd1) っぽいです。なぜかというと、grub上(というかLinuxでは全般に)では、 MBRパテーションテーブルは msdos として表示 されますし、 GPTパテーションテーブルは gpt として表示 されるからです。起動したいのはGPTのHDDです。

f:id:yuzutan_hnk:20170217014443j:plain:w300

grub> ls (hd1)
Device hd1: No known filesystem detected - Sector size 512B - Total size 976762584KiB

案の定ですね。これが1TBのHDDです。

では、今度はUbuntuを起動させるため、Linuxカーネルの配置を確認します。パテーションの1つめはESPなので、2つめのファイル一覧を取得します。

f:id:yuzutan_hnk:20170217014444j:plain:w300

grub> ls (hd1,gpt2)/
lost+found/ boot/ hdata/ etc/ media/ var/ bin/ dev/ home/ lib/ lib64/ mnt/ opt/ proc/ root/ rules.d/ run/ sbin/ snap/ srv/ sys/ tmp/ usr/ vmlinuz initrd.img cdrom/ initrd.img.old vmlinuz.old

Ubuntuのルートですね。さて、これでUbuntuを起動させられるだけの情報は整いました。

え?カーネルのフルネームを確認できていないって?そうそう、なんだか知りませんが、 システムのルートにシンボリックリンクが張ってあるのでそれを使えば問題ない そうです。

起動する

では、実際に起動します。次のコマンドを打って、終わり。

grub> set root=(hd1,gpt2)
grub> linuxefi /vmlinuz root=/dev/sda2
grub> initrdefi /initrd.img
grub> boot

f:id:yuzutan_hnk:20170217014445j:plain:w300

linuxefi コマンドで、起動するLinuxカーネルを指定します。今回はシステムルートにある vmlinuz というシンボリックリンクを使って指定しています。これがない場合は、 boot/ 以下にある本体をフルネームで指定します。

同時にシステムのルートを指定します。 root=/dev/sda2 の部分です。多くのサイトの解説では、今回のような (hd1,gpt2) をルートとしたい場合、 /dev/sdb2 とするのが一般的だそうです。たしかに (hd0) があるので、それを sda とすると、 (hd1)sdb になります。理屈はわかります。

しかし、 それでは起動しませんでした 。憶測ですが、もしかしたら起動時にカーネルからデバイスの再スキャンが行われて、カーネルが認識した順番がGrubの認識した順番と違う、という現象が起こっているのかもしれません。全く分からない。

次に initrd コマンドですが、どうもモジュール等を含むデータをメモリに読み込むためのコマンドのようです。よくわかりませんが、これも initrd.img というシステムルートにあるシンボリックリンクを使います。ない場合は、 boot/ 以下にある本体をフルネームで指定します。

最後に boot コマンドでブートさせます。

f:id:yuzutan_hnk:20170217014446j:plain:w300

ちなみに、UEFI環境でない場合は、efiがついていないコマンドでブートします。UEFIでも使えるので、実質どちらでもいいのでは…?

grub> set root=(hd1,gpt2)
grub> linux /vmlinuz root=/dev/sda2
grub> initrd /initrd.img
grub> boot

最後に

f:id:yuzutan_hnk:20170217014447j:plain:w300

無事に起動できました。grubのシェルを直で触るなんて初めてで、いろいろ試行錯誤して、起動できたときは本当に感動しました。大歓喜でした。

今回は本当に 起動できればいい というスタンスなので、あまり深入りはしませんが、これで調べるべき対象が一つ増えた気がします。

やっぱりLinuxは楽しい(まだ何もわかっていないのに)。