自作OSをやってみた

# 自作OSをやってみた

なんとなく自作OSについて興味が湧いたので、以下の動画を参照して、自作OSの初歩に取り組んでみた際のメモ

- [45分でゼロから作る！OS自作ライブコーディング 2023-7-29 C-3]( https://www.youtube.com/watch?v=dPEsTeL2F98)

## 環境構築

上記の動画ではMac上で、RISC-Vの環境を構築しているが、自分の環境では上手くいかなったので、`Docker`上の`Ubuntu`で構築することにした。

### Dockerをインストールする

Macでインストールする場合は、Docker Desktopをインストールすると良い。

- 参考 : https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/

### Ubuntuイメージの取得

Ubuntuを利用するので、最新版のイメージを取得しておく。
既に取得済みの場合は、実行不要。

```sh
docker pull ubuntu
```

### 作業フォルダをバインディングして起動する

単にDockerでUbuntuを起動しただけだと、[作業結果が保存されない](https://qiita.com/Toyo_m/items/95a2543c07dc5b126208)ので、バインドにより、作業結果を保存＆ローカルのディレクトリとデータを共有する様にする。

```sh
docker run -it -d --name jisaku-os --mount type=bind,src=Mac上のパス,target=Ubuntu上のパス ubuntu
```

ここで `src` はMac上のローカルフォルダパス（絶対パス）、`target`はUbuntu上で同期させるフォルダのパス（絶対パス）になります。
これを実行しておくと、Mac上でコーディングした結果が、そのままUbuntu上で利用可能になります。

今回作成するUbuntuのコンテナの名前は、わかりやすさ優先で`jisku-os`としておきます。

### コンテナに入る

以下のコマンドで、作成したコンテナに入れます。
終了する場合は `exit`を実行してください。

```sh
docker exec -it jisaku-os bash
```

### 各種コマンドのインストール

各種コマンドをインストールする前に、パッケージの更新を行ってください。

```sh
apt update
```

`RISC-V`をgitでインストールするので、gitもインストールしておきます。

```sh
apt install -y git
```

`RISC-V`環境を構築します。

まず、必要なコマンド、及びライブラリをインストールします。

```sh
apt install autoconf automake autotools-dev curl python3 python3-pip python3-tomli libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libslirp-dev vim wget ftp -y
```

`RISC-V`のダウンロードを行います。

```sh
git clone https://github.com/riscv/riscv-gnu-toolchain
```

`RISC-V`のインストール先を作成します。

```sh
mkdir /opt/riscv
```

後にPATHに追加するので、`.bashrc` に以下を追記してください。

```sh
export RISCV=/opt/riscv
```

設定を反映させます。

```sh
source ~/.bashrc
```

ビルドを実行します。（2時間ぐらいかかりました）

```sh
cd riscv-gnu-toolchain
./configure --prefix=$RISCV --enable-multilib
make
```

`clang`をインストールします。
必要なコマンドのインストールや、署名情報を登録なども行っています。

```sh
apt install curl gnupg
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /etc/apt/keyrings/llvm.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/llvm.gpg] http://apt.llvm.org/jammy/ llvm-toolchain-jammy main" | tee /etc/apt/sources.list.d/llvm.list > /dev/nul
apt update
apt install clang llvm lld lldb -Y
```

`QEMU`をインストールします。

```sh
apt -y install qemu-system qemu-system-common qemu-utils
```

BIOSを取得します。
**ダウンロードしたファイルは、作業フォルダに置いてください。**

```sh
curl -LO https://github.com/qemu/qemu/raw/v8.0.4/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
```

## QEMU上のショートカットキー

自作OSをQEMUで起動したあとは、単純に`exit`などで終了できないので注意してください。
とりあえず、以下のコマンドを覚えておけば、上記の動画と同様のことはできます。
その他のコマンドは、ヘルプを参照してください。

| アクション | コマンド |
|-- |-- |
| 終了 | Ctrl+A X |
| モニターモード | Ctrl+A C |
| ヘルプ | Ctrl+A H |


## 開発資料

動画内で参照しているPDFは以下のものになります。
動画内で実装している`putchar` や `getchar`以外のシステムコールを実装する場合は、こちらの資料を参照することになります。

- RISC-Vのドキュメント
    - https://lists.riscv.org/g/tech-brs/attachment/361/0/riscv-sbi.pdf

## Mac上で環境が構築できなかった件

既にインストールされている`gcc`のバージョンなどと整合性が取れず、`clang(llvm)` コマンドのビルド時に、例外が発生して、インストールが完了しませんでした。
動画ではMacOS上で環境構築しているので、できないことはないのだと思いますが、解決しなかったので、諦めてUbuntu上で構築する方向にシフトしました。

MacOS上で環境構築できる人は、MacOSのみで完結しておいたほうが、色々と楽だとは思います。

## 自作OSを作ってみた感想

「45分で実装する自作OS」に関しては、確かに動画を見ながら、1時間ぐらいで実装はできたのですが、環境構築に倍以上時間がかかったので、一からやるには、明らかに45分じゃ足りないので、その点には注意が必要です。

とりあえず動画の内容を一通り実装すると、システムコールはこんな感じで実装しているだ、とかプロセスの切り替えは、こうやって実現しているんだ的な、基礎が学べるのでオススメです。

## 参考

- https://www.profound-dt.co.jp/qemu/qemu_chap1/
- https://zenn.dev/tetsu_koba/articles/d0a25ea5035b3e
- https://qiita.com/Toyo_m/items/95a2543c07dc5b126208
- https://qiita.com/kooohei/items/0e788a2ce8c30f9dba53
- https://qiita.com/kxkx5150/items/c6a71610c98c0c68f542