wasmに入門したりprismaにハマったりいろいろありますが、以前から興味のあった自作OSというものに手を出してみます。
この書籍を参考にしています。
ゼロからのOS自作入門 | 内田 公太 |本 | 通販 | Amazon
機械語でHello World!
まずはバイナリの編集に使用するエディターをダウンロードします。
sudo apt install okteta
エディターがダウンロードできたら、ひたすらHello Worldを実装します。
以下に上がっていますが、本見ながら写経しました。チカレタ。。
mikanos-build/day01/bin/hello.efi at master · uchan-nos/mikanos-build · GitHub
実際はこんな感じです。痺れますね。
これをBOOTX64.efi
として保存します。
ちゃんとコーディングできていれば、sum
コマンドでチェックサムが12430となっています。
% sum ../../study/custom_os/BOOTX64.efi
12430 2
ではこれをエミュレーターで実行します。
QEMUをダウンロードしましょう。
公式にダウンロードのためのshがあったので使ってみます。
wget https://download.qemu.org/qemu-8.1.0-rc4.tar.xz
tar xvJf qemu-8.1.0-rc4.tar.xz
cd qemu-8.1.0-rc4
./configure
make
しかし./configure
のあたりでエラーになってしまいました。。
% ./configure
Using './build' as the directory for build output
python determined to be '/home/username/.anyenv/envs/pyenv/shims/python3'
python version: Python 3.8.12
mkvenv: Creating non-isolated virtual environment at 'pyvenv'
mkvenv: checking for meson>=0.63.0
mkvenv: installing meson>=0.63.0
mkvenv: checking for sphinx>=1.6.0, sphinx-rtd-theme>=0.5.0
'sphinx>=1.6.0' not found:
• Python package 'sphinx' was not found nor installed.
• mkvenv was configured to operate offline and did not check PyPI.
Sphinx not found/usable, disabling docs.
ERROR: Cannot find Ninja
なんかpython使っているっぽいです。
pipで関連パッケージをインストールしておきましょう。
pip install sphinx sphinx-rtd-theme
Ninjaというツールも必要らしい。ということでインストールしておきます。
aptだとうまくインストールできなかったのでbrewでインストールしました。
brew install ninja
ということで再チャレンジします。
% ./configure
Using './build' as the directory for build output
python determined to be '/home/username/.anyenv/envs/pyenv/shims/python3'
python version: Python 3.8.12
mkvenv: Creating non-isolated virtual environment at 'pyvenv'
mkvenv: checking for meson>=0.63.0
mkvenv: installing meson>=0.63.0
mkvenv: checking for sphinx>=1.6.0, sphinx-rtd-theme>=0.5.0
The Meson build system
Version: 1.2.1
Source dir: /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4
Build dir: /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build
Build type: native build
Project name: qemu
Project version: 8.0.94
C compiler for the host machine: cc -m64 -mcx16 (gcc 11.4.0 "cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0")
C linker for the host machine: cc -m64 -mcx16 ld.bfd 2.38
Host machine cpu family: x86_64
Host machine cpu: x86_64
Program scripts/symlink-install-tree.py found: YES (/home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/pyvenv/bin/python3 /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/scripts/symlink-install-tree.py)
Program sh found: YES (/usr/bin/sh)
Program python3 found: YES (/home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/pyvenv/bin/python3)
Program bzip2 found: YES (/usr/bin/bzip2)
Program iasl found: NO
Compiler for C supports link arguments -Wl,-z,relro: YES
Compiler for C supports link arguments -Wl,-z,now: YES
Compiler for C supports link arguments -Wl,--warn-common: YES
Compiler for C supports arguments -Wundef: YES
Compiler for C supports arguments -Wwrite-strings: YES
Compiler for C supports arguments -Wmissing-prototypes: YES
Compiler for C supports arguments -Wstrict-prototypes: YES
Compiler for C supports arguments -Wredundant-decls: YES
Compiler for C supports arguments -Wold-style-declaration: YES
Compiler for C supports arguments -Wold-style-definition: YES
Compiler for C supports arguments -Wtype-limits: YES
Compiler for C supports arguments -Wformat-security: YES
Compiler for C supports arguments -Wformat-y2k: YES
Compiler for C supports arguments -Winit-self: YES
Compiler for C supports arguments -Wignored-qualifiers: YES
Compiler for C supports arguments -Wempty-body: YES
Compiler for C supports arguments -Wnested-externs: YES
Compiler for C supports arguments -Wendif-labels: YES
Compiler for C supports arguments -Wexpansion-to-defined: YES
Compiler for C supports arguments -Wimplicit-fallthrough=2: YES
Compiler for C supports arguments -Wmissing-format-attribute: YES
Compiler for C supports arguments -Wno-initializer-overrides: NO
Compiler for C supports arguments -Wno-missing-include-dirs: YES
Compiler for C supports arguments -Wno-shift-negative-value: YES
Compiler for C supports arguments -Wno-string-plus-int: NO
Compiler for C supports arguments -Wno-typedef-redefinition: NO
Compiler for C supports arguments -Wno-tautological-type-limit-compare: NO
Compiler for C supports arguments -Wno-psabi: YES
Compiler for C supports arguments -Wno-gnu-variable-sized-type-not-at-end: NO
Compiler for C supports arguments -Wthread-safety: NO
Program cgcc found: NO
Library m found: YES
Run-time dependency threads found: YES
Library util found: YES
Run-time dependency appleframeworks found: NO (tried framework)
Found pkg-config: /usr/bin/pkg-config (0.29.2)
Run-time dependency glib-2.0 found: NO (tried pkgconfig)
../meson.build:729:10: ERROR: Dependency "glib-2.0" not found, tried pkgconfig
A full log can be found at /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/meson-logs/meson-log.txt
ERROR: meson setup failed
またパッケージが見つからなくて怒られました。
以下の記事を参考にインストールしました。
【C言語】glib2.0を使ってみた〜confファイル読み込み〜 #Config - Qiita
sudo apt install libglib2.0-dev
再度実行します。
% ./configure
# ...中略....
../meson.build:840:11: ERROR: Dependency "pixman-1" not found, tried pkgconfig
A full log can be found at /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/meson-logs/meson-log.txt
ERROR: meson setup failed
また失敗しました。
(いっぺんに出してほしい…)
これもインストールします。
sudo apt install -y libpixman-1-dev
再度実行します。
% ./configure
# ...中略....
Program scripts/decodetree.py found: YES (/home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/pyvenv/bin/python3 /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/scripts/decodetree.py)
Program flex found: NO
../target/hexagon/meson.build:180:8: ERROR: Program 'flex' not found or not executable
A full log can be found at /home/username/Project/personal/hugo-blog/qemu-8.1.0-rc4/build/meson-logs/meson-log.txt
ERROR: meson setup failed
これもインストールします。
sudo apt install -y flex
再実行してやっと成功しました。
make
も実行しましょう。
make
これがめっっっっっっっっちゃ時間かかりました。
というかここまでやって分かったんですが、ソースコードからコンパイルする必要なかったです!!!!!!
brew使っているなら一発でダウンロードできました!!!!!今までの時間!!!!!!!
% brew install qemu
# ...中略...
==> Pouring llvm@15--15.0.7.x86_64_linux.bottle.tar.gz
Error: Too many open files @ rb_sysopen - /home/linuxbrew/.linuxbrew/Cellar/llvm@15/15.0.7/bin/verify-uselistorder
ただ途中でインストールできませんでした。かなしい。
結局先程ビルドしたディレクトリの一部をPATHに通すように.zshrc
を書き換えることでコマンドを使用可能にしました。
export PATH="[格納されたディレクトリ]/qemu-8.1.0-rc4/build:$PATH"
qemuのコマンドが使用可能になったら、ディスクイメージを作成します。
qemu-img create -f raw disk.img 200M
mkfs.fat -n "MIKAN OS" -s 2 -f 2 -R 32 -F 32 disk.img
mkdir -p mnt
sudo mount -o loop disk.img mnt
sudo mkdir -p mnt/EFI/BOOT
sudo cp BOOTX64.efi mnt/EFI/BOOT/BOOTX64.efi
sudo umount mnt
これでディスクイメージが出来上がりました。(disk.img
)
qemu-system-x86_64 \
-drive if=pflash,file=../mikanos-build/devenv/OVMF_CODE.fd \
-drive if=pflash,file=../mikanos-build/devenv/OVMF_VARS.fd \
-hda disk.img
-drive
オプションで指定しているファイルは、作者のリポジトリに上がっていました。
これをダウンロードしておきます。
mikanos-build/devenv at master · uchan-nos/mikanos-build · GitHub
これを実行します。
% qemu-system-x86_64 \
-drive if=pflash,file=../mikanos-build/devenv/OVMF_CODE.fd \
-drive if=pflash,file=../mikanos-build/devenv/OVMF_VARS.fd \
-hda disk.img
WARNING: Image format was not specified for '../mikanos-build/devenv/OVMF_CODE.fd' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
WARNING: Image format was not specified for '../mikanos-build/devenv/OVMF_VARS.fd' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
WARNING: Image format was not specified for 'disk.img' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
Could not open option rom 'kvmvapic.bin': No such file or directory
qemu-system-x86_64: failed to find romfile "vgabios-stdvga.bin"
うまくいきませんね…
なんかファイルが見つからないようです。
あまりに面倒くさすぎて2日ほど放置していました。
調べると、以下のような記事が見つかりました。
qemuの特定のディレクトリでコマンドを実行する必要があるようです。
面倒ですが、qemu-system-x86_64コマンドを実行するためのshファイルを実装します。
これはコマンド実行のたびにディレクトリ移動をしないために用意します。
#!/bin/bash
cd $HOME/Project/tools/qemu-8.1.0-rc4/pc-bios
qemu-system-x86_64 $@
実行権限を付与します。
chmod -x qemu-system-x86_64.sh
このshを実行するエイリアスを登録します。
alias qemu-system-x86_64="$HOME/Project/tools/toolbox/qemu-system-x86_64.sh"
これで再度コマンドを実行しましょう。
ただ、これにより相対パス指定が使えなくなったので絶対パスに直しておきます。
% qemu-system-x86_64 \
-drive if=pflash,file=$HOME/Project/study/mikanos-build/devenv/OVMF_CODE.fd \
-drive if=pflash,file=$HOME/Project/study/mikanos-build/devenv/OVMF_VARS.fd \
-hda $HOME/Project/study/custom_os/disk.img
WARNING: Image format was not specified for '/home/username/Project/study/mikanos-build/devenv/OVMF_CODE.fd' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
WARNING: Image format was not specified for '/home/username/Project/study/mikanos-build/devenv/OVMF_VARS.fd' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
WARNING: Image format was not specified for '/home/username/Project/study/custom_os/disk.img' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
qemu-system-x86_64: could not read keymap file: 'en-us'
またエラーです。
なんでこう一筋縄じゃいかないかね。。。
もうDockerとかで動かす方法ないかな〜と思って調べていたんですが、この辺の手順でやり忘れがありそうだったのでやってみます。
linuxでマルチアーキテクチャに対応したdockerイメージを作ろうの巻(buildx) | ゆっくり遅報
qemuのインストールディレクトリにscriptsディレクトリがあるので、ここのshを/usr/local/binに移動します。
chmod +x scripts/qemu-binfmt-conf.sh
sudo mv scripts/qemu-binfmt-conf.sh /usr/local/bin/qemu-binfmt-conf.sh
あとはカーネルに登録するための準備を行います。
cat <<EOF | sudo tee /usr/local/bin/register.sh
#!/bin/sh
QEMU_BIN_DIR=${QEMU_BIN_DIR:-/usr/bin}
if [ ! -d /proc/sys/fs/binfmt_misc ]; then
echo "No binfmt support in the kernel."
echo " Try: '/sbin/modprobe binfmt_misc' from the host"
exit 1
fi
if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
fi
if [ "${1}" = "--reset" ]; then
shift
find /proc/sys/fs/binfmt_misc -type f -name 'qemu-*' -exec sh -c 'echo -1 > {}' \;
fi
exec /usr/local/bin/qemu-binfmt-conf.sh --qemu-suffix "-static" --qemu-path "${QEMU_BIN_DIR}" $@
EOF
sudo chmod +x /usr/local/bin/register.sh
cat <<EOF | sudo tee /etc/systemd/system/register.service
[Unit]
Description= register cpu emulator
[Service]
ExecStart = /usr/local/bin/register.sh
Restart = no
Type = simple
RemainAfterExit=yes
[Install]
WantedBy = multi-user.target
EOF
カーネルに登録しました。
sudo systemctl daemon-reload
sudo systemctl enable register.service
sudo systemctl start register.service
%sudo systemctl status register.service
× register.service - register cpu emulator
Loaded: loaded (/etc/systemd/system/register.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2023-08-25 09:24:25 JST; 17s ago
Process: 573950 ExecStart=/usr/local/bin/register.sh (code=exited, status=126)
Main PID: 573950 (code=exited, status=126)
CPU: 3ms
8月 25 09:24:25 username-ThinkPad-X260 systemd[1]: Started register cpu emulator.
8月 25 09:24:25 username-ThinkPad-X260 register.sh[573950]: /usr/local/bin/register.sh: 15: exec: /usr/local/bin/qemu-binfmt-conf.sh: Permission deni>
8月 25 09:24:25 username-ThinkPad-X260 systemd[1]: register.service: Main process exited, code=exited, status=126/n/a
8月 25 09:24:25 username-ThinkPad-X260 systemd[1]: register.service: Failed with result 'exit-code'.
まぁ失敗したんですけどね。
エミュレートするだけでこんなに面倒ですか。くそ〜〜〜〜〜
一旦心が折れたので、QEMUの動作環境構築は次回にまわして終わります。。
まとめ
大変すぎるぜQEMUの構築。
そもそも最初のソースコードからビルドする段階で間違っていたんだろうか。。
いろいろ前途多難です。