はじめに
こんにちは.だいみょーじんです.
この記事は,第43回自作OSもくもく会で発表した内容をまとめ,自作OSアドベントカレンダー2025の18日目の記事として公開したものです.
対象読者は,ゼロからのOS自作入門を読んだことがある人です.
MikanOSとは
uchan_nosさんの著作,ゼロからのOS自作入門は,OS自作初心者を対象にOSを開発する過程をゼロから解説し,コードを書き写すことで段階的にOS開発を体験できる書籍です.
この書籍で開発される教育用OSがMikanOSです.
OS自作初心者は「ゼロからのOS自作入門」を読み,MikanOSを段階的に開発していくことで,OS自作を体験できるわけです.
私もこの書籍を読んでMikanOSを開発しましたが,環境構築やビルド手順が少々面倒だったので,自動化してみました!
自動化スクリプトはこちらからご覧ください.
MikanOSのビルド手順
「ゼロからのOS自作入門」で説明されているMikanOSの大まかなビルド手順は以下のとおりです.
- mikanos-buildをosbookとしてクローン
- ansibleで必要なツールをインストール
- mikanosをクローン
- EDKⅡのディレクトリにMikanOSブートローダのディレクトリをリンク
-
edksetup.shを読み込むことでEDKⅡのビルドに必要な環境変数を設定 - 自動生成された
Conf/target.txtを編集 - ブートローダをビルド
-
osbook/devenv/buildenv.shを読み込むことでMikanOSのビルドに必要な環境変数を設定 - MikanOSをビルド
- MikanOSのイメージファイル
disk.imgが完成
この一連の手順を自動化しましょう.
ブートローダのビルド
MikanOSのビルド手順のうち,ブートローダのビルドに関わるのはこの部分です.
-
edksetup.shを読み込むことでEDKⅡのビルドに必要な環境変数を設定 - 自動生成された
Conf/target.txtを編集 - ブートローダをビルド
この部分をbuild_boot_loader.shで自動化しましょう.
#!/bin/bash
source edksetup.sh
cd Conf
sed -i "s/^ACTIVE_PLATFORM[\t ]*=[\t ]*.*$/ACTIVE_PLATFORM = MikanLoaderPkg\/MikanLoaderPkg.dsc/" target.txt
sed -i "s/^TARGET[\t ]*=[\t ]*.*$/TARGET = DEBUG/" target.txt
sed -i "s/^TARGET_ARCH[\t ]*=[\t ]*.*$/TARGET_ARCH = X64/" target.txt
sed -i "s/^TOOL_CHAIN_TAG[\t ]*=[\t ]*.*$/TOOL_CHAIN_TAG = CLANG38/" target.txt
build
sedコマンドでブートローダをビルドする際の設定ファイルであるtarget.txtのACTIVE_PLATFORM,TARGET,TARGET_ARCH,TOOL_CHAIN_TAGの各設定項目を記入します.
そして最後にbuildコマンドでブートローダをビルドします.
MikanOS本体のビルド
MikanOSのビルド手順のうち,MikanOS本体のビルドに関わるのはこの部分です.
-
osbook/devenv/buildenv.shを読み込むことでMikanOSのビルドに必要な環境変数を設定 - MikanOSをビルド
- MikanOSのイメージファイル
disk.imgが完成
この部分をbuild_mikanos.shで自動化しましょう.
#!/bin/bash
source /root/osbook/devenv/buildenv.sh
./build.sh
osbook/devenv/buildenv.shでビルドに必要な環境変数を設定し,build.shでMikanOSをビルドします.
最後にMakefileを記述し,makeコマンド一発でMikanOSのイメージファイルと,それをマウントしたディレクトリを生成できるようにします.
REPOSITORY=$(shell git config --get remote.origin.url)
PRODUCT=$(shell echo $(REPOSITORY) | awk -F '[./]' '{print $$(NF-1)}')
IMAGE=$(shell echo $(PRODUCT) | awk '{print tolower($$0)}')
CONTAINER=$(IMAGE)
VNC_PORT=5900
MOUNT=disk
TARGET=$(MOUNT).img
$(MOUNT): $(TARGET)
if mountpoint -q $@; then sudo umount -l $@; fi
if [ -e $@ ] ; then rm -rf $@; fi
mkdir $@
sudo mount -o loop $^ $@
$(TARGET):
./build.sh $(IMAGE) $(CONTAINER) $(VNC_PORT) $(TARGET)
これでビルド自体は自動化できたわけですが,ビルド以前の環境構築の部分も自動化したくなってきます.
環境構築の自動化
MikanOSのビルド手順のうち,環境構築に関わるのはこの部分です.
- mikanos-buildをosbookとしてクローン
- ansibleで必要なツールをインストール
- mikanosをクローン
これを自動化するためのDockerを使いましょう.
全体的な流れはこんな感じです.
-
Dockerfileに従ってMikanOSをビルドするための環境を構築 - Dockerコンテナ上で
build_boot_loader.shを実行してブートローダをビルド - Dockerコンテナ上で
build_mikanos.shを実行してMikanOS本体をビルド - DockerコンテナからビルドされたMikanOSのイメージファイル
disk.imgを取得
この手順をbuild.shに記述します.
#!/bin/bash
image=$1
container=$2
vnc_port=$3
target=$4
# Build a docker image.
if [ -z "$(docker images --format {{.Repository}} $image)" ]; then
docker build --build-arg vnc_port=$vnc_port -t $image . # ビルド環境を構築
fi
# Create a docker conatiner.
if [ -z "$(docker ps -a --format {{.Names}} --filter name=^$container\$)" ]; then
docker create -i -t -p $vnc_port:$vnc_port --privileged --name $container $image /bin/bash
docker start $container
docker exec --workdir /root/edk2 $container ./build_boot_loader.sh # ブートローダをビルド
docker exec --workdir /root/mikanos $container ./build_mikanos.sh # MikanOS本体をビルド
docker stop $container
fi
# Download MikanOS image file.
docker cp $container:/root/mikanos/$4 $4 # ビルドされたMikanOSイメージファイルを取得
次に,環境構築の手順をDockerfileに記述します.
FROM ubuntu:20.04
# Don't ask stdin anything to install software automatically.
ENV DEBIAN_FRONTEND=noninteractive
# Install softwares.
RUN apt-get update && apt-get upgrade -y && apt-get install -y ansible # MikanOSのビルドに必要なものを一括インストールする用
RUN apt-get update && apt-get upgrade -y && apt-get install -y dosfstools # FAT32イメージファイル作成用
RUN apt-get update && apt-get upgrade -y && apt-get install -y git
RUN apt-get update && apt-get upgrade -y && apt-get install -y vim
# Build MikanOS.
WORKDIR /root
COPY osbook.patch /root/osbook.patch
RUN git clone https://github.com/uchan-nos/mikanos-build.git osbook # MikanOSビルドツールをクローン
WORKDIR /root/osbook
RUN git checkout 8d4882122ec548ef680b6b5a2ae841a0fd4d07a1 # 将来の変更によるミスマッチを防ぐため固定コミットにチェックアウト
RUN git apply ../osbook.patch # Dockerのrootアカウントではsudoが必要なくなるので,sudoを消すパッチを当てる
WORKDIR /root/osbook/devenv
RUN ansible-playbook -i ansible_inventory ansible_provision.yml # MikanOSのビルドに必要なものを一括インストール
WORKDIR /root
RUN git clone https://github.com/uchan-nos/mikanos.git # MikanOS本体をクローン
WORKDIR /root/mikanos
RUN git checkout b5f7740c04002e67a95af16a5c6e073b664bf3f5 # 将来の変更によるミスマッチを防ぐため固定コミットにチェックアウト
WORKDIR /root/edk2
RUN ln -s /root/mikanos/MikanLoaderPkg . # EDKⅡのディレクトリにMikanOSのブートローダのディレクトリをリンク
# ブートローダをビルドするシェルスクリプトを配置
COPY build_boot_loader.sh /root/edk2/build_boot_loader.sh
# MikanOS本体をビルドするシェルスクリプトを配置
COPY build_mikanos.sh /root/mikanos/build_mikanos.sh
WORKDIR /root
# Set
ENV APPS_DIR apps
ENV RESOURCE_DIR resource
# Expose VNC port.
ARG vnc_port
EXPOSE $vnc_port
これでビルド環境の構築からMikanOSのビルドまでを自動化できました.
Docker上でMikanOSを実行
MikanOSのビルドを自動化できたので,今度はQEMUにおけるMikanOSの実行も自動化したくなります.
こんな風に,Docker上でQEMUを動かし,ホスト上のVNC viewerを介して人間とやり取りすれば良さそうです.
既にosbook/devenv/run_image.shにQEMUでMikanOSを走らせるコマンドが書かれていますが,このコマンドはVNC接続していないので,VNC接続するように-vnc :0というオプションを追記するパッチを当てます.
こうするとQEMUは5900番ポートでVNC接続を待機するようになります.
さらに,上に記載したDockerfileのEXPOSEコマンドにより,Dockerコンテナの5900番ポートに穴を開ければ,Dockerコンテナ上で動くQEMUとホスト上で動くVNC viewerが通信できるようになります.
最後に,MakefileにDockerコンテナ上のQEMUでMikanOSを動かすコマンドを書いておきます.
.PHONY: run
run: build
docker stop $(CONTAINER)
docker start $(CONTAINER)
docker exec --workdir /root/mikanos $(CONTAINER) ./build.sh run
make runしてQEMUで立ち上がったのを確認し,VNC viewerでlocalhost:5900にアクセスするとMikanOSを操作できます.
ここまでで,ワンコマンドでMikanOSをビルドしたり,動かしたりできるようになりました.
GitHub Actionsによるビルド
次はゼロコマンドでビルド済みのMikanOSのイメージを取得できるようにしましょう.
.github/workflows/build.ymlでmake buildを実行してビルド済みMikanOSイメージをマウントしたdiskディレクトリを作成し,それを生成物としてアップロードします.
name: build
on:
push:
branches:
- main
- issue1
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@main
- name: Build MikanOS
run: make build
- name: Upload MikanOS
uses: actions/upload-artifact@main
with:
name: MikanOS
path: disk
これでこちらからビルド済みのMikanOSをダウンロードできるようになりました.
実質ゼロコマンドでMikanOSを入手できます!
まとめ
- MikanOSのビルドを自動化
- Dockerを使うことで,1コマンドで環境構築からビルドまでできるように
- VNC通信によりDocker上のQEMUで動くMikanOSを操作
- GitHub Actionsを使うことで,GitHubからビルド済みのMikanOSをダウンロードできるように




