#はじめに
cmdline.txtの中身のroot=/dev/mmcblk0p3を/dev/sda3に書き換えてください。この記事の内容はこの説明で全てです。
この説明でわかる方はこれで解決できると思います。以下は詳細です。
Raspberry Pi 4(以下ラズパイ)にSSDをUSB接続して、SSDにCentOSを入れてブートしようとしたら起動できずハマりました。ググった範囲では似たケースはあったものの、全く同じ症状に関する記事等はないようでした。わかってみれば大したことではなかったのですが、同じハマり方をした人の参考のために記事にします。
#環境
- Raspberry Pi 4 (Amazonで[これ](https://www.amazon.co.jp/gp/product/B08GS76DLN"Raspberry Pi 4B Server 8GB エキスパートセット")を購入しました)
- SSD: 東芝 mSATA 128 GB SSD thnsnj128gmcu (2014年秋冬モデルdynabook KIRA V63から抜いた物)
USB-mSATAアダプタ: KingSpec MSATA SSDケース (2017年12月に購入) - Raspberry Pi OSをmicroSDに焼いてあって、問題なく起動できる。
- 事前にRaspberry Pi OSのraspi-configでUSB起動を有効化している (ラズパイダさんの記事を参考にさせていただきました)。
- Raspberry Pi以外のPCで、Raspberry Pi Imagerを使ってCentOSのOSイメージをSSDに焼いてある(こちらのサイトを参考にさせていただきました)。
- CentOSを焼いたSSDをラズパイにUSB接続
- CentOSのバージョンは7。8でもおそらく同じ (8をラズパイに入れた記事があります)。
なお、SSDではなくCentOSをmicroSDに焼いて、それをラズパイに挿して起動した場合は問題なく起動するようで、成功例が複数(1, 2, 3, 4)報告されています。今回の現象は、PCから直接SSDに焼いた場合特有に起こる問題のようです。
#症状
boot時に以下のようにend Kernel panic -……とメッセージが出て止まる。(xxxは数字)
end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(xxx,xxx)
これは、SSDと同時にRaspberry Pi OSが入ったmicroSDを挿しっぱなしにしていた場合のみ起こりました。microSDを抜いて、SSDのみがラズパイに接続されている状態で起動しなおすと、Kernel panicは出なくなりました。しかしながら、今度は
vcc-sd: disabling
というメッセージが出て一旦止まり、数分経過した後に
random: crng init done
というメッセージが出て、それ以降はいくら待っても進まなくなりました。
#対処法
結論から言うと、SSDの1つめのパーティションにあるcmdline.txt
というファイルを編集すると起動できるようになりました。
以下手順です。
-
一旦ラズパイからSSDを外し、microSDを挿入してRaspberry Pi OSを起動する。
-
SSDをつなぐ。
300 MB ボリューム
と_/
という名前のアイコンが、以下のスクショのようにデスクトップに出現しています。
-
lsblk
コマンドを実行すると、現在接続されているデバイスとマウントポイントが見えます。
(ユーザー名)@(ホスト名):~ $ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 119.2G 0 disk
├─sda1 8:1 0 286M 0 part /media/(ユーザー名)/(UUID)
├─sda2 8:2 0 488M 0 part
└─sda3 8:3 0 118.5G 0 part /media/(ユーザー名)/__
mmcblk0 179:0 0 119.1G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 118.9G 0 part /
(ユーザー名)と(ホスト名)はデフォルトではpiとraspberrypiです。(UUID)の部分はデバイスのUULD(Universally Unique Identifier) で、環境依存です。
sda
は1番目のSCSI/SATA/USBに接続したHDD (今回はSSDですが) を意味し、配下のsda1
, sda2
, sda3
がSSD内にある3つのパーティションの1つめ、2つめ、3つめにそれぞれ対応しています。またlsblk
の実行結果の7列目の情報から、sda1
とsda3
が/media/(ユーザー名)/
のディレクトリにマウントされていることが確認できます(自動的にここにマウントされるようです)。
ちなみにmmcblk0はRaspberry Pi OSの入っているmicroSDカードのことで、mmcblk0p1
,mmcblk0p2
はmultimedia card block 0 partition 1または2を意味します。
- sda1のパーティションにあるcmdline.txtを編集します。
lsblk
で確認したように、sda1は/media/(ユーザー名)/(UUID)にマウントされているので、そのディレクトリ直下にあるcmdline.txt
をNanoで開きます。
$ sudo nano /media/(ユーザー名)/(UUID)/cmdline.txt
以下はNanoで開いた例。
console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait
- cmdline.txtのファイル内で
root=/dev/mmcblk0p3
となっている部分を、下記のようにroot=/dev/sda3
に書き換えます。
console=ttyAMA0,115200 console=tty1 root=/dev/sda3 rootfstype=ext4 elevator=deadline rootwait
- 上書き保存します。これでRaspberry Pi OSでの作業は終わりです。Raspberry Pi OSを再起動します。
$ sudo reboot
- CentOSが立ち上がるはずです。ユーザー名
root
, 初期パスワードcentos
でログインできます。
なお、cmdline.txtだけではなくfstabの書き換えもしている記事もありましたが、今回試した限りではcmdline.txtのみ編集しただけで起動できました。ちなみにfstabの編集にはUUIDを確認する必要がありますが、コンソールでblkid
のコマンドを実行して、確認できます (xxxxは環境依存の16進数の値)。
$ blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="xxxx" TYPE="vfat" PARTUUID="xxxx-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="xxxx" TYPE="ext4" PARTUUID="xxxx-02"
/dev/sda1: SEC_TYPE="msdos" UUID="xxxx" TYPE="vfat" PARTUUID="xxxx-01"
/dev/sda2: LABEL="_swap" UUID="xxxx" TYPE="swap" PARTUUID="xxxx-02"
/dev/sda3: LABEL="_/" UUID="xxxx" TYPE="ext4" PARTUUID="xxxx-03"
/dev/sda1
と/dev/sda3
のところに表示されているUUIDと、先にlsblk
で確認した/media/(ユーザー名)/
のディレクトリの(UUID)
と__
がそれぞれに対応しています。
#考察
今回の問題は、端的にいうとmicroSDに書き込むことを前提に作られたOSイメージを、何も考えずにSSDに焼いてしまったために起きたものです。具体的には、ラズパイのブートの仕組みに起因します。ラズパイでは、ブートファイルは通常SDカードの1つ目のパーティションに保存されています。ラズパイの電源が投入されると、様々なプロセッサを起動するためにブートパーティション/フォルダからブートローダー等の様々なファイルがロードされ、その後Linuxカーネルが起動されます。
Linuxカーネルは、起動の際に複数のパラメータから成るコマンドを受け付けます。ラズパイでは、このコマンドはブートパーティションに存在するcmdline.txtというテキストファイルで定義されます。cmdline.txtではroot (bootではなくroot) のパスが指定されています。このとき、前述の通り通常はここがmmcblk0p3となっているのに、SSDで起動する場合は実際のrootはsda3に存在するため、Linuxカーネルは存在しないパーティションを見にいってしまいます。そのため起動がうまくいかない、ということになると考えられます。
上ではラズパイの公式ドキュメントを典拠として挙げましたが、それ以外にもいくつかのサイトが非常に参考になりました。(この記事を書くために公式ドキュメントを読んだら全部書いてありました)(私は公式ドキュメントを読め)
エラーメッセージの理由と、cmdline.txtを編集するべきであると気づかせてくれた記事。
また、Raspberry Pi 4でCentOS7を外付けSSDで動かした記事がありますが、
この記事では詳細がとても詳しく述べられていて、とても参考になりました。この記事では一旦microSDにCentOSを書き込んだ後、SSDに自分でパーティションを切って、microSDからSSDにパーティションごとにコピーするという手順を踏まれています。この当時はおそらくこのような手順を踏まなければいけなかったのだと思われますが、2021年5月現在はもろもろの進歩 (Raspberry Pi Imagerで直接SSDに焼ける) によってより簡単にできるようになりました。この記事ではcmdline.txtの編集についても述べられています。
さらに、CentOS 8でほぼ同じことをしている記事を、解決した後になってから見つけました。
僅かな手順の差 (現在のほうがRaspberry Pi OSのバージョンが上がっていることに起因する)がありますが、結局やっていることは同じでした。しかしながら、当該記事は淡々と手順を述べているものであったため、トラブルシューティング的な位置付けで、私と同じハマり方をしている方向けに書く意義があると思い、この記事を書きました。
#まとめ
- cmdline.txtを書き換えることがポイント
- 私は公式ドキュメントをちゃんと読め
以上です。