はじめに
(明日国際会議で発表しないといけないので,記事を書いている場合ではなさそうですが)
以前 BIOS 環境で NVMe から BitVisor と OS を起動しようとしたとき起きた問題と,その回避策( not 解決策 ) を書こうと思います.
以前にあった話を思い出しながら書いているので,もしかしたら細かい部分で間違っている部分があるかもしれません.
以前,同じ内容を BitVisor の Slack 内で話題に挙げたので,Slack を見ている方は知っている内容かもしれません.
環境 & 現象
BitVisor を以下の条件で起動しようとすると, MBR read error
や load_bootsector error
と言われて落ちてしまいました.
- ブートディスクが M.2 接続の NVMe (SAMSUNG SSD 950 Pro M.2)
- BitVisor とゲスト OS が NVMe デバイスにインストールされている
- NVMe を GPT でパーティショニング
- BIOS ブートで Grub --> BitVisor -*-> Grub --> Linux の順に起動 (* でエラー)
エラーの詳細
調べてみると,どうも BIOS コールの int 13h ah=02h がエラーコード 20h (controller failure) を返しているようでした.
回避策 ( not 解決策 )
M.2 な NVMe だと CHS でアクセスできないのかな? と思い,試しに int13h ah=42h (LBA 指定でディスクを読む) をやってみたところ,一応,起動に成功しました.
実際に加えた変更は以下の通りです.
--- a/core/loadbootsector.c Fri Jun 30 14:50:24 2017 +0900
+++ b/core/loadbootsector.c Fri Jun 30 15:49:44 2017 +0900
@@ -133,13 +133,19 @@
int i;
u64 lba;
struct mbr *p;
-
+ u8 err_code;
+
if (tmpbufsize < 512)
return false;
printf ("Loading MBR.\n");
- if (callrealmode_disk_readmbr (bios_boot_drive, tmpbufaddr)) {
- printf ("MBR read error.\n");
- return false;
+ err_code = callrealmode_disk_readmbr (bios_boot_drive, tmpbufaddr);
+ if (err_code) {
+ printf ("MBR read error %x.\n", err_code);
+ err_code = callrealmode_disk_readlba (bios_boot_drive, tmpbufaddr, 0, 1);
+ if (err_code) {
+ printf ("MBR read (LBA) error %x.\n", err_code);
+ return false;
+ }
}
if (config.vmm.boot_active) {
printf ("Loading VBR.\n");
残っている問題
起動はしましたが,若干動作が怪しいです.
2回目の grub でゲスト OS を選択してからの Linux カーネルの起動中のメッセージが出力されるまでにかなり時間がかかります.
BitVisor を挟まなければ特に時間がかからない部分なんですが...
NVMe と BIOS の組み合わせについて
そもそも,BitVisor 云々とは関係なく,BIOS 環境で OS を NVMe から起動するのは NVMe の仕様的に非推奨だったりします.
なので,起動するだけでもラッキーなのかもしれません...
終わりに
BIOS + NVMe + BitVisor で起きた問題とその回避策について書きました.
詳細な調査は行っていないので,M.2 NVMe だけで起きる問題なのかそうでないのかや,それ以外のストレージデバイスで起きるのかどうかなどはよくわかりません.
BIOS + NVMe という奇特な環境で BitVisor を使わないといけない諸事情がある人の役に立つと幸いです (そういう人がどれくらいいるのか謎ですが...).
(明日の国際会議での発表が終わったら僕はぐったりしてそうなので,誰かに記事を書いてほしいですね)