ゼロから始めるOS自作入門のmikanOSを起動する環境をAzureで整える

# はじめに
[「ゼロから始めるOS自作入門」](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AEOS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%86%85%E7%94%B0-%E5%85%AC%E5%A4%AA/dp/4839975868)という本で、ゼロからOSを作るにあたってAzure VM上でQEMUを動かす必要がありました。
[AndroidエミュレータをAzure VM上で動かした時](https://qiita.com/maplejava/items/a2b3a9e1b6563a300db1)もそうですが、仮想マシンの上でさらにエミュレータを動かすときは設定に工夫が必要ですので、その時の方法を以下にまとめます。

# 環境構築の方向性決め

環境構築の方法は色々あるが、私の場合だと以下の選択肢がある。
1. Azure上のベアメタルな環境（Azure Baremetal Infrastructure）で環境構築
→できたら最強だが高い
2. AzureVM上（Ubuntu）で環境構築
→GUIがないとQEMUを起動してもグラフィカルにOSの動作を確認できないと思っていたが、AzureVMにGNOME（ノーム）を入れることは可能そう。
3. AzureVM上のWindows10にWSLでUbuntuをいれて環境構築
→UbuntuにGNONEいれればGUI使えることを思いついたのでこの案より2の方が良いと思う。
4. ベアメタルなWindows11にWSLでUbuntuをいれて環境構築
→書籍でもサポートされている範囲。普段使いPCがもろ汚れるのが嫌。
5. ベアメタルなMacに気合で環境構築（以下の記事）。
→色々逆に勉強になりそうだが、ただでさえ本が難しいのに大変そう。

https://zenn.dev/karaage0703/articles/1bdb8930182c6c

今回は2で進める。

# 構築するVMのスペック決め

- image

[公式サイト](https://github.com/uchan-nos/mikanos-build)によると以下の通り。

> このリポジトリは uchan が開発している教育用 OS [MikanOS](https://github.com/uchan-nos/mikanos) をビルドする手順およびツールを収録しています。 Ubuntu 18.04 で動作を確認しています。
> 

よし、Ubuntu18.04にしよう。

> mikanos-build 最新版は Ubuntu 22.04 をサポートしています。ただし、導入される lld-14 を使うとリンクアドレスがズレることにより OS やアプリが誤動作することが分かっています。
…
lld-7 を使いたい場合は Ubuntu 18.04 か 20.04 をお使いください。Ubuntu 18.04 や 20.04 向けには次のコマンドを実行して古い mikanos-build を利用してください。
> 

Ubuntu22.04が最新だから22.04の方が良い？
でも誤動作するとか書いてあるから18.04にしよう。

imageの最後につく「Gen 1」や「Gen 2」というのはAzureVMの世代数を表しており、以下のような違いがあるらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/2df0e410-463e-1280-97c5-9ee6857c6233.png)


ChatGPTより。

>1. **BIOSの方式**: Generation 1 VMは従来のBIOSに基づいています。一方、Generation 2 VMはより最新のUEFI(Unified Extensible Firmware Interface)に基づいています。UEFIは新しいタイプのファームウェアで、従来のBIOSに取って代わることを目指して開発されました。UEFIは、起動プロセスをより柔軟にし、セキュアブートといったセキュリティ機能をサポートするなど、従来のBIOSよりも多くの機能を持っています。
>2. **OSディスクのサイズ**: Generation 1 VMは、OSディスクの最大サイズが2TBまでです。一方、Generation 2 VMはOSディスクの最大サイズが4TBまでとなります。
>3. **セキュアブート**: Generation 2 VMはセキュアブートをサポートしています。セキュアブートはUEFI仕様の一部で、コンピュータが信頼されたソフトウェアのみを起動することを保証します。これはマルウェアやルートキットによる攻撃を防ぐための重要な機能です。
>4. **仮想マシンの起動順序**: Generation 2 VMは仮想マシンの起動順序を変更する機能をサポートしています。
>一般的には、新規のVMデプロイメントについては、利用可能な場合は可能な限りGeneration 2 VMを使用することが推奨されます。ただし、特定の既存のアプリケーションやワークロードについては、互換性の問題からGeneration 1 VMを使用する必要がある場合もあります。

https://learn.microsoft.com/ja-jp/azure/virtual-machines/generation-2

迷うところだが、検証の内容的に機能が少ない方がやりやすそうなので、**Gen 1**にする。

- Security Type

Security Type項目をTrusted launchにするとSecure bootを選べるようになるが、OSを自由にbootしたいので、これを選んではいけないと思う。Security TypeはStandardにしておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/67872579-6d81-ad16-7c26-35d355f97750.png)


https://learn.microsoft.com/ja-jp/azure/virtual-machines/trusted-launch-portal?tabs=portal,portal2,portal3

- Size

デスクトップ（GUI）を使うので少し大きめにしておく。
[Android Emulatorを起動しようとしたとき](https://qiita.com/maplejava/items/a2b3a9e1b6563a300db1)にメモリ不足になったので、今回も”Standard_D8s_v3”にしようと思う（8コア、メモリ32GB）。

- Administarator account

今回リモデを目指すのでSSH public key認証ではなくPassword認証にしておいた方が良いと思う。

- Inbound port rules
NSGの設定。今回Bastionを使用するのでなんでもいいと思う。

# UbuntuにRDPできるようにする

QEMUを実行した結果をグラフィカルに確認したいので、AzureVM（Ubuntu）にGNONEをいれる。

https://kogelog.com/2020/05/12/20200512-01/

- GNONE：LinuxにGUIをもたらすフリーソフトウェア。
- TigerVNC：VNCという別のコンピュータのGUIを現在使用しているコンピュータのディスプレイに表示する技術で、TigerVNCはそれを実現するソフトウェア。
- xrdp：WindowsのRDPに必要なサーバソフトウェア。

Bastionを使ってUbuntuにRDPする。

Connection Settingsからプロトコルを選択可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/46d4c687-9499-dbf2-36be-b1bc806fb44c.png)


接続してUbuntuでyoutubeが見れた！
Memoryを32GBにしたからか動作速度も問題ない。他の記事では遅いという意見もあったので。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/fd0ca0c5-e2e1-4d40-43ad-a60e60d1dc9e.png)


# OS自作のための環境づくり

https://github.com/uchan-nos/mikanos-build

上記手順にてAnsibleで環境構築がされるようになっている。

```
sudo apt install git
cd $HOME
git clone https://github.com/uchan-nos/mikanos-build.git osbook
```

今回Ubuntu18.04を使用しているので最新版のmikanosは使用しないので以下のようにする。

```
cd osbook
git checkout 8d4882122ec548ef680b6b5a2ae841a0fd4d07a1
```

Ansibleによる環境構築

```
sudo apt install ansible
cd $HOME/osbook/devenv
ansible-playbook -K -i ansible_inventory ansible_provision.yml
```

出力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/1c0822fd-b7f3-a48e-1a8f-30bd5ced6301.png)

結果確認

```
iasl -v
ls $HOME/edk2
```

MikanOS のソースコードの入手

```
cd $HOME/osbook
git clone https://github.com/uchan-nos/mikanos.git
```

実行したディレクトリ配下にmikanosディレクトリができる。

書籍では/path/toディレクトリ配下にmikanosがあるが、$HOME/osbookディレクトリ配下にmikanosディレクトリを作成した。

ブートローダーのビルド

```
cd $HOME/edk2
ln -s $HOME/osbook/mikanos/MikanLoaderPkg ./
```

正しくリンクがはれていることの確認

```
ls MikanLoaderPkg/Main.c
```

EDK Ⅱのビルドに必要な環境変数の自動設定

```
source edksetup.sh
```

```
vi Conf/target.txt
```

以下の通り編集する

| ACTIVE_PLATFORM | MikanLoaderPkg/MikanLoaderPkg.dsc |
| --- | --- |
| TARGET | DEBUG |
| TARGET_ARCH | X64 |
| TOOL_CHAIN_TAG | CLANG38 |

```
build
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/1fb15312-6e42-1b06-2f80-6a0cb322db30.png)



以下のファイルが出力されていれば成功

```
ls Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi
```

完成品の実行に必要な環境変数の読み込み

```
source $HOME/osbook/devenv/buildenv.sh
```

完成品の実行

```
cd $HOME/osbook/mikanos
$ ./build.sh run
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/63ffdb73-314f-bb48-e790-3a127e4b9eb8.png)


lsコマンドもある…！たのしみ！！色々なコマンドを作りたい！！

# その後のエラー
しばらくログインしてなかったからか該当のホストがRDPでログインできなくなってた（SSHでは可能）。一回できても少ししたらセッションが切られてログインできない事象が発生した。

Azure上のヘルプに以下の記事があった。

https://learn.microsoft.com/en-us/azure/virtual-machines/linux/use-remote-desktop?tabs=azure-cli

WindowsのVMにbastionでRDPしてから当該Linux VMにRDPするといけた。bastion経由でLinux VMにRDPがサポートされなくなった？bastion周りのMSLearnやブログを少し漁ったがわからず。

以下の画面が表示される。前bastion経由でRDPできていた時は表示されなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/0716e3ea-db60-b424-7131-f1d2b53dae82.png)


# （補足）GDBコマンドの実行
本を進めていくとGDBコマンドを実行する機会が出てくるが、GDBはAzure VMにおけるUbnutu 18.04イメージに同梱されているので、コマンドライン上で以下のコマンドを打てば起動可能である。

```text
ncbpco130@AZ-foo-pc30:~$ gdb kernel/kernel.elf 
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from kernel/kernel.elf...done.
```