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?

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

1
Last updated at Posted at 2025-12-18

はじめに

こんにちは.だいみょーじんです.
この記事は,自作OSアドベントカレンダー2025の19日目の記事として公開したものです.

liumOSとは

liumOSは,hikaliumさんの自作OSのひとつで,NVDIMM対応や,DNSサーバへの問い合わせやpingなどのネットワーク関連の機能を持っていることが特徴です.

liumOS

今回はliumOSのビルドの自動化およびDockerとQEMUによる実行の自動化を行いました.
自動化スクリプトはこちらからご覧ください.

liumOSのビルド

以下の手順でliumOSのディレクトリツリーmntおよびそれを圧縮したliumos.zipを得ます.

liumosのビルド
/somewhere $ git clone https://github.com/TaiseiIto/liumos.git
/somewhere $ cd liumos
/somewhere/liumos $ make build
/somewhere/liumos $ ls liumos.zip
liumos.zip
/somewhere/liumos $ find mnt
mnt
mnt/lowlayers.mid
mnt/Hallelujah.mid
mnt/sleep-prep.mid
mnt/EFI
mnt/EFI/BOOT
mnt/EFI/BOOT/BOOTX64.EFI
mnt/2014-000.mid
mnt/rikoten.mid
mnt/liumos.ppm
mnt/logo.ppm
mnt/liumos.png
mnt/100.mid

mntをUSBにコピーし,そのUSBから起動すれば実機でliumOSを動かせます.
大まかなビルドの流れは以下のとおりです.

  1. liumOSをビルドできる環境をDockerで構築
  2. Dockerコンテナ内でliumOSをビルド
  3. ビルドされたディレクトリツリーmntliumos.zipに圧縮
  4. mntおよびliumos.zipをDockerコンテナからホストにコピー

liumOSをビルドするコマンドはmake buildです.
では,Makefileの中身を見てみましょう.

Makefile
REPOSITORY=$(shell git config --get remote.origin.url) # リモートリポジトリのURL
PRODUCT=$(shell echo $(REPOSITORY) | awk -F '[./]' '{print $$(NF-1)}') # リポジトリ名'liumos'
IMAGE=$(shell echo $(PRODUCT) | awk '{print tolower($$0)}') # Dockerイメージ名'liumos'
CONTAINER=$(IMAGE) # Dockerコンテナ名'liumos'
VNC_PORT=5905

.PHONY: build
build:
	./build.sh $(IMAGE) $(CONTAINER) $(VNC_PORT) # liumOSをビルド

IMAGECONTAINERはそれぞれDockerのイメージ名とコンテナ名で,リポジトリ名liumosと同じになるはずです.
VNC_PORTliumOSの実行で使用しますが,ビルド時には使わないので無視してください.
そして,build.shにDockerイメージ名とDockerコンテナ名を渡しています.
では,build.shを見てみましょう.

build.sh
#!/bin/bash

image=$1 # Dockerイメージ名
container=$2 # Dockerコンテナ名
vnc_port=$3

# Build a docker image
if [ -z "$(docker images --format {{.Repository}} $image)" ]; then
	docker build --build-arg vnc_port=$vnc_port -t $image . # Dockerイメージを作成
fi

# Create a docker container.
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コンテナを作成
	docker start $container
	docker exec --workdir /root/liumos $container ./build_on_container.sh # Dockerコンテナ内でliumOSをビルド
	docker stop $container
fi

# Extract liumOS.
if [ ! -e liumos.zip ]; then
	docker cp $container:/root/liumos/liumos.zip liumos.zip # liumos.zipをホストにコピー
fi
if [ ! -d mnt ]; then
	docker cp $container:/root/liumos/mnt mnt # mntをホストにコピー
fi

liumOSをビルドできる環境をDockerイメージとして構築し,それをコンテナ化し,コンテナ内でbuild_on_container.shを実行しています.
これがコンテナ内でliumOSをビルドするスクリプトで,要するにコンテナ外のbuild.shがコンテナ内のbuild_on_container.shを呼び出してビルドを依頼する形になっています.
その後ビルドされたliumOSのディレクトリツリーmntと,それを圧縮したliumos.zipを,コンテナ内からコンテナ外にコピーします.
次に,liumOSをビルドできる環境を構築する手順を記載している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 clang-8
RUN apt-get update && apt-get upgrade -y && apt-get install -y clang-format
RUN apt-get update && apt-get upgrade -y && apt-get install -y cmake
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl
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 libc++-8-dev
RUN apt-get update && apt-get upgrade -y && apt-get install -y libc++abi-8-dev
RUN apt-get update && apt-get upgrade -y && apt-get install -y lld
RUN apt-get update && apt-get upgrade -y && apt-get install -y lld-8
RUN apt-get update && apt-get upgrade -y && apt-get install -y netcat
RUN apt-get update && apt-get upgrade -y && apt-get install -y qemu-system-x86
RUN apt-get update && apt-get upgrade -y && apt-get install -y vim
RUN apt-get update && apt-get upgrade -y && apt-get install -y wget
RUN apt-get update && apt-get upgrade -y && apt-get install -y zip

# Install Rust.
# Rust 1.65.0 is released on 3 November, 2022
RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=nightly-2022-11-03-x86_64-unknown-linux-gnu

# Build liumOS.
WORKDIR /root
RUN git clone https://github.com/hikalium/liumos.git # liumOSをクローン
WORKDIR /root/liumos
RUN git checkout dd619eb19c0c04504228494e8af65945ad31aa9b # 特定のコミットにチェックアウト
COPY build_on_container.sh build_on_container.sh # ビルドスクリプトを配置
COPY run_on_container.sh run_on_container.sh

# Expose VNC port.
ARG vnc_port
EXPOSE $vnc_port

liumOSはRustで書かれているので,Rustをはじめ,必要なソフトウェアをインストールしています.
その後,liumOSをクローンし,特定のコミットにチェックアウトし,ビルドスクリプトbuild_on_container.shをイメージ内に配置して環境構築は終わりです.
次にliumOSの自動ビルドの中核部分であるbuild_on_container.shを見てみましょう.

build_on_container.sh
#!/bin/bash

source /root/.cargo/env
# Rust 1.65.0 is released on 3 November, 2022
rustup toolchain install nightly-2022-11-03-x86_64-unknown-linux-gnu
rustup default nightly-2022-11-03-x86_64-unknown-linux-gnu
rustup component add rust-src --toolchain nightly-2022-11-03-x86_64-unknown-linux-gnu
make tools # ツールを準備
make prebuilt # ライブラリを準備
make # liumOSをビルド
make files # ディレクトリツリーmntを作成
zip -r liumos.zip mnt # ディレクトリツリーを圧縮

Rustのツールチェーンはnightly-2022-11-03-x86_64-unknown-linux-gnuにしています.
続いてliumOSのREADMEに従い,make toolsでツールを準備,make prebuiltでライブラリを準備,makeでliumOSをビルドします.
最後にmake filesでディレクトリツリーmntを作成し,liumos.zipに圧縮します.

GitHub Actionsによるビルド

1コマンドでliumOSをビルドできるようになったので,次はGitHub Actionsを使って,ゼロコマンドでビルド済みのliumOSを取得できるようにします.
build.ymlを見てみましょう.

build.yml
name: build
on:
  push:
    branches:
      - main
jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the repository
        uses: actions/checkout@main
      - name: Build liumOS
        run: make build
      - name: Upload liumOS
        uses: actions/upload-artifact@main
        with:
          name: liumOS
          path: mnt

mainブランチにpushされた時にGitHub Actionsでmake buildを実行し,生成されたディレクトリツリーmntをアップロードしています.
これでGitHubからビルド済みのliumOSをダウンロードできるようになりました.

liumOSの実行

ビルドを自動化できたので,次はDockerコンテナ内のQEMU上でliumOSの実行を自動化してみましょう.
ありがたいことに,liumOSのリポジトリでは既にmake runでQEMU上での実行をサポートしているので,それを呼び出せばよいです.
またqemu.mkを見ると,VNCで5905番ポートにパスワードaでアクセスできるっぽいです.

qemu.mk
PROJECT_ROOT:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
OVMF?=${PROJECT_ROOT}/ovmf/bios64.bin
QEMU?=qemu-system-x86_64
VNC_PASSWORD?=a # VNCパスワードはa
PORT_MONITOR?=2222
PORT_COM1?=1234
PORT_COM2?=1235
# PORT_VNC=N => port 5900 + N
PORT_OFFSET_VNC?=5 # VNCポート番号は5905
PORT_GDB?=3333

なので,MakefileにVNCポート番号を書いておいて,それをbuild.shに渡します.

Makefile
VNC_PORT=5905

.PHONY: build
build:
	./build.sh $(IMAGE) $(CONTAINER) $(VNC_PORT) # VNCポート番号をbuild.shに渡す

build.shはさらにDockerfileにVNCポート番号を渡します.

build.sh
vnc_port=$3

# Build a docker image
if [ -z "$(docker images --format {{.Repository}} $image)" ]; then
	docker build --build-arg vnc_port=$vnc_port -t $image .
fi

DockerfileはVNCポートを外部に公開します.

Dockerfile
# Expose VNC port.
ARG vnc_port
EXPOSE $vnc_port

Dockerイメージができると,今度はbuild.shでDockerコンテナ作成時にホストのVNCポートとコンテナのVNCポートを直結します.

build.sh
# Create a docker container.
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/liumos $container ./build_on_container.sh
	docker stop $container
fi

これでホスト側のVNCポートとDockerコンテナ側のVNCポートを直結できました.
次に,make runでDockerコンテナ内のQEMU上でliumOSを起動できるように,Makefilerunコマンドを記述します.

Makefile
.PHONY: run
run: build
	./run.sh $(CONTAINER)

run.shは,Dockerコンテナ内のrun_on_container.shを呼び出します.

run.sh
#!/bin/bash

container=$1

docker stop $container
docker start $container
docker exec --workdir /root/liumos $container ./run_on_container.sh

run_on_container.shは,DockerfileでDockerイメージ内にあらかじめコピーされています.

Dockerfile
COPY run_on_container.sh run_on_container.sh

run_on_container.shは,liumOSのMakefileを呼び出し,QEMU上でliumOSを起動します.

run_on_container.sh
#!/bin/bash

source /root/.cargo/env
make run GUI=n GDB=n

これでliumOSの実行を自動化できます.
以下のコマンドにより,liumOSが起動します.

liumOS起動手順
/somewhere $ git clone https://github.com/TaiseiIto/liumos.git
/somewhere $ cd liumos
/somewhere/liumos $ make run

そして,VNC viewerでlocalhost:5905にアクセスし,パスワードaでliumOSを操作できるようになります.

まとめ

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

参考文献

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?