1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MikanOSのビルドを自動化してみた

1
Last updated at Posted at 2025-12-18

はじめに

こんにちは.だいみょーじんです.
この記事は,第43回自作OSもくもく会で発表した内容をまとめ,自作OSアドベントカレンダー2025の18日目の記事として公開したものです.
対象読者は,ゼロからのOS自作入門を読んだことがある人です.

MikanOSとは

uchan_nosさんの著作,ゼロからのOS自作入門は,OS自作初心者を対象にOSを開発する過程をゼロから解説し,コードを書き写すことで段階的にOS開発を体験できる書籍です.
この書籍で開発される教育用OSがMikanOSです.
OS自作初心者は「ゼロからのOS自作入門」を読み,MikanOSを段階的に開発していくことで,OS自作を体験できるわけです.

MikanOS

私もこの書籍を読んでMikanOSを開発しましたが,環境構築やビルド手順が少々面倒だったので,自動化してみました!
自動化スクリプトはこちらからご覧ください.

MikanOSのビルド手順

「ゼロからのOS自作入門」で説明されているMikanOSの大まかなビルド手順は以下のとおりです.

  1. mikanos-buildをosbookとしてクローン
  2. ansibleで必要なツールをインストール
  3. mikanosをクローン
  4. EDKⅡのディレクトリにMikanOSブートローダのディレクトリをリンク
  5. edksetup.shを読み込むことでEDKⅡのビルドに必要な環境変数を設定
  6. 自動生成されたConf/target.txtを編集
  7. ブートローダをビルド
  8. osbook/devenv/buildenv.shを読み込むことでMikanOSのビルドに必要な環境変数を設定
  9. MikanOSをビルド
  10. MikanOSのイメージファイルdisk.imgが完成

この一連の手順を自動化しましょう.

ブートローダのビルド

MikanOSのビルド手順のうち,ブートローダのビルドに関わるのはこの部分です.

  1. edksetup.shを読み込むことでEDKⅡのビルドに必要な環境変数を設定
  2. 自動生成されたConf/target.txtを編集
  3. ブートローダをビルド

この部分をbuild_boot_loader.shで自動化しましょう.

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本体のビルドに関わるのはこの部分です.

  1. osbook/devenv/buildenv.shを読み込むことでMikanOSのビルドに必要な環境変数を設定
  2. MikanOSをビルド
  3. MikanOSのイメージファイルdisk.imgが完成

この部分をbuild_mikanos.shで自動化しましょう.

build_mikanos.sh
#!/bin/bash

source /root/osbook/devenv/buildenv.sh
./build.sh

osbook/devenv/buildenv.shでビルドに必要な環境変数を設定し,build.shでMikanOSをビルドします.
最後にMakefileを記述し,makeコマンド一発でMikanOSのイメージファイルと,それをマウントしたディレクトリを生成できるようにします.

Makefile
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のビルド手順のうち,環境構築に関わるのはこの部分です.

  1. mikanos-buildをosbookとしてクローン
  2. ansibleで必要なツールをインストール
  3. mikanosをクローン

これを自動化するためのDockerを使いましょう.
全体的な流れはこんな感じです.

build.drawio.png

  1. Dockerfileに従ってMikanOSをビルドするための環境を構築
  2. Dockerコンテナ上でbuild_boot_loader.shを実行してブートローダをビルド
  3. Dockerコンテナ上でbuild_mikanos.shを実行してMikanOS本体をビルド
  4. DockerコンテナからビルドされたMikanOSのイメージファイルdisk.imgを取得

この手順をbuild.shに記述します.

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に記述します.

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を介して人間とやり取りすれば良さそうです.

run.drawio.png

既に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を動かすコマンドを書いておきます.

Makefile
.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.png

ここまでで,ワンコマンドでMikanOSをビルドしたり,動かしたりできるようになりました.

GitHub Actionsによるビルド

次はゼロコマンドでビルド済みのMikanOSのイメージを取得できるようにしましょう.
.github/workflows/build.ymlmake buildを実行してビルド済みMikanOSイメージをマウントしたdiskディレクトリを作成し,それを生成物としてアップロードします.

build.yml
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を入手できます!

artifact.png

まとめ

  • MikanOSのビルドを自動化
  • Dockerを使うことで,1コマンドで環境構築からビルドまでできるように
  • VNC通信によりDocker上のQEMUで動くMikanOSを操作
  • GitHub Actionsを使うことで,GitHubからビルド済みのMikanOSをダウンロードできるように

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?