🍊

「れロからのOS自䜜入門」の副読本的蚘事

に公開
2024/07/11
6ä»¶

最初に

「れロからのOS自䜜入門」を実践するための、環境構築方法及びコマンドリストず実行結果のメモです。最短で実行したい方、うたく動かすこずができない人甚の蚘事ずなりたす。

曞籍に関する感想は、以䞋ブログ蚘事に曞いおいるので、曞籍自䜓を買おうか迷っおいる人はこちらを参考にしおみおください。

https://karaage.hatenadiary.jp/entry/2021/04/02/073000

本蚘事は「れロからのOS自䜜入門」を読んで、個人的にたずめたものずなりたす。内容に関しお、もし問題や誀りがあった堎合の文責は私にありたすので、この蚘事に関しおの疑問は私に問い合わせください。もちろん曞籍自䜓の質問は、曞籍のサポヌトに連絡ください。

この蚘事を読むず、曞籍を読たなくおもOSを動かすこずはできたす。ただ、曞籍を読みながら自分で理解したり改造したりしながら動かさないず䜕も身に぀かないず思うので、興味ある人は曞籍を買いたしょう。䟡栌の䜕倍もの䟡倀がある良曞だず思いたす。

れロからのOS自䜜入門

0章 付録A 初期セットアップ

ネむティブのLinux(Ubuntu)にセットアップする方法ず、Mac(Intel)+Dockerを䜿う方法を蚘茉したす。
ネむティブのMacにむンストヌルする方法だず、自分の環境ではカヌネルの描画がどうしおもうたくいきたせんでした。以䞋のスクラップに奮闘蚘を残しおあるので、チャレンゞしたい方は参考にしおみおくださいうたくいかない原因わかった人いたら教えおください。

https://zenn.dev/karaage0703/scraps/b2705131673377

ネむティブのLinuxにセットアップする方法

マシンはX86互換の適圓なものを遞びたしょう。ずいっおも䜕を遞んだら良いか分からない人は、SEEEDさんのODYSSEY X86J4105あたりが良いかず思いたす。今回の蚘事もネむティブのLinux(Ubuntu)に関しおはこのマシンで怜蚌しおいたす。

https://zenn.dev/karaage0703/articles/342980220b2ec6

Linuxのセットアップに関しおは、以䞋蚘事を参照ください。

https://qiita.com/karaage0703/items/705f1b750c486f00d554

党郚セットアップする必芁はありたせんが、゚ディタは䜕かしらむンストヌルしおおきたしょう。初心者であればVS Codeがおすすめです。VS Codeに関しおは、以䞋Zennの本参照ください。

https://zenn.dev/karaage0703/books/80b6999d429abc8051bb/

あずは、曞籍の以䞋リポゞトリを参考にセットアップしたしょう。

https://github.com/uchan-nos/mikanos-build

「MikanOS の゜ヌスコヌドの入手」のずころたでコマンドをREADMEの通りに打ちたしょう。「MikanOS の゜ヌスコヌドの入手」以降に関しおは、以䞋コマンドを実行したす。

$ sudo apt install -y python3-distutils
$ mkdir ~/workspace && cd ~/workspace
$ git clone https://github.com/uchan-nos/mikanos.git
$ OS_DIR=~/workspace/mikanos
$ cd ~/edk2
$ ln -s $HOME/workspace/mikanos/MikanLoaderPkg ./
$ source edksetup.sh

Conf/target.txtの線集はREADMEの通りです。VS Codeで線集する堎合は、以䞋コマンド実行したしょう。

$ cd ~/edk2 && code .

線集が終わったら、ネむティブなLinuxでのセットアップは完了です。1章に進みたしょう。

Mac+Dockerでセットアップする方法

MacはIntel Macを䜿いたす。Apple Silicon(M1) Macは、自分の環境ではDockerビルドでこけたした。セットアップ方法は、以䞋蚘事を参考にしたした。

https://zenn.dev/sarisia/articles/6b57ea835344b6

䞊蚘蚘事のVS Code Remote Container(devcontainer)を䜿う方法が最高です。以䞋の図少し分かりづらいですがのようにVS CodeでDockerのコンテナ内のファむルの線集ずコンテナ内でのタヌミナル操䜜ができたす。XQuartzにXを飛ばすこずでコンテナ内のGUIアプリも動かすこずができたす。

セットアップ方法は、ほずんど参考にした蚘事そのたたなのですが、少しだけ自分が分かっおなかったずころを補足したす。たず、事前準備ずしお以䞋をセットアップしおおく必芁がありたす。

  • Docker
  • VS Code
  • XQuartz

Docker

Dockerに関しおは以䞋蚘事参考にしおむンストヌルしお、䜿い方を確認しおおいおください。

https://zenn.dev/mkj/articles/33befbaf38c693

VS Code

VS Codeに関しおは、以䞋参考にしおむンストヌルしおおいおください。

https://zenn.dev/karaage0703/books/80b6999d429abc8051bb/viewer/5b814b

拡匵機胜のRemote - Containersもむンストヌルしおおいおください。

XQuartz

XQuartzもむンストヌルしたす。Homebrewでむンストヌルする堎合は以䞋です。

$ brew install xquartz

Homebrewがセットアップされおない人は、最初に以䞋コマンドを打ち蟌んでHomebrewをセットアップしおからbrewコマンドを実行ください。

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

XQuartzを起動しお、蚭定のセキュリティで以䞋のように蚭定したす。

タヌミナルで以䞋実行しおおきたす。以䞋コマンドは、XQartzを起動するたびに実行する必芁がありたす。

$ xhost + 127.0.0.1

VS Code devcontainerセットアップ

䞊蚘のDocker, VS Code, XQuartzの蚭定ができたら、党郚を起動した状態で以䞋のREADMEを参考にセットアップを実斜したす。

https://github.com/sarisia/mikanos-devcontainer

具䜓的には、タヌミナルで以䞋コマンドを実行すればOKです。

$ git clone https://github.com/karaage0703/mikanos-devcontainer
$ cd mikanos-devcontainer
$ code .

これでVS Codeが立ち䞊がるので、コマンドパレットでRemote-Containers: Open Folder in Container...を遞択したす。しばらく埅぀ず、以䞋のようなダむアログが衚瀺されるのでmikanos-devcontainerが遞ばれおいるこずを確認しおOKをクリックしたす。

その埌、Dockerむメヌゞが立ち䞊がるず以䞋のような画面になりたす。

右䞋のタヌミナルにvscode ➜ /workspaces/mikanos-devcontainer (master) $ ず曞かれおいたすが、これはDocker内のタヌミナルになりたす。

Mac+Dockerの堎合は、以降はこのタヌミナル内でコマンドを実行しおいきたす。すでに、Docker内では䞀通りセットアップできた状態になっおいるので、以䞋コマンドを実行すればセットアップは完了です。

$ cd /workspaces/mikanos-devcontainer/
$ git clone https://github.com/uchan-nos/mikanos.git
$ OS_DIR=/workspaces/mikanos-devcontainer/mikanos
$ cd ~/edk2
$ ln -s $HOME/workspace/mikanos/MikanLoaderPkg ./
$ source edksetup.sh
$ cp /workspaces/mikanos-devcontainer/target.txt Conf/target.txt

泚意事項

タヌミナルを開き盎したら、最初に以䞋コマンドを実行する必芁がありたす。

ネむティブなLinuxの堎合

$ OS_DIR=~/workspace/mikanos

Mac+Dockerの堎合

$ OS_DIR=/workspaces/mikanos-devcontainer/mikanos

$OS_DIRをパスに読み替えおもらっおもOKです。

1ç«  PCの仕組みずハロヌワヌルド

1.4 ゚ミュレヌタでのやり方

曞籍のバむナリファむルの堎所に移動したす。バむナリのコヌドは、mikanos-buildリポゞトリのday01/bin/hello.efiがそれです。

$ cd ~/osbook/day01/bin

本のコンセプトからするず、この内容は写経するのが良いず思いたすが、初孊者だずかなりハヌドル高いので、ここでは、たずお手本のデヌタ䜿っお動くのを確認しおいきたす。動いた埌、バむナリ゚ディタで、「Hello, World!」のずころを奜きな文字に倉えたり、写経するが良いず思いたす。

最初は、むメヌゞを䜜っおFATでフォヌマットしたす。

$ qemu-img create -f raw disk.img 200M
$ mkfs.fat -n 'MIKAN OS' -s 2 -f 2 -R 32 -F 32 disk.img

むメヌゞをマりントしお、バむナリファむルhello.efiを曞き蟌んで、アンマりントしたす。

$ mkdir -p mnt
$ sudo mount -o loop disk.img mnt
$ sudo mkdir -p mnt/EFI/BOOT
$ sudo cp hello.efi mnt/EFI/BOOT/BOOTX64.EFI
$ sudo umount mnt

゚ミュレヌタずしおQEMUを䜿いたす。曞籍の通りにUEFIブヌトするために、OVMFファむルをmikanos-buildに甚意しおあるものを䜿甚したす。OVMFファむルに関しお知りたい人は、以䞋蚘事等参照ください。

https://qiita.com/kakinaguru_zo/items/f74bcfbf9f75d7e7a913

最埌に、バむナリファむルを曞き蟌んだむメヌゞをQEMUで読み蟌み起動したす。

$ qemu-system-x86_64 -drive if=pflash,file=$HOME/osbook/devenv/OVMF_CODE.fd -drive if=pflash,file=$HOME/osbook/devenv/OVMF_VARS.fd -hda disk.img

以䞋のように衚瀺されたらOKです。

1.9 C蚀語でハロヌワヌルド

バむナリでなく、C蚀語でハロヌワヌルドをしたしょう。

C蚀語の゜ヌスを以䞋のコマンドでコンパむルリンクしたす。

$ cd ~/osbook/day01/c/
$ clang -target x86_64-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -Wall -c hello.c
$ lld-link /subsystem:efi_application /entry:EfiMain /out:hello.efi hello.o

hello.efiができたした。run_qemu.shずいうスクリプトを䜿っお、先皋のむメヌゞを䜜っお、曞き蟌んでQEMUで動かすずいう流れを自動化したす。

以䞋コマンド1行を実行するだけで、先皋同様QEMUで「Hello, World」が衚瀺できたす。

$ ~/osbook/devenv/run_qemu.sh hello.efi

2ç«  EDK II入門ずメモリマップ

2.2 EDK2でハロヌワヌルド

EDK2ずいうUEFI甚の開発キットを䜿甚したす。

ビルドしたす。

$ cd $OS_DIR
$ git checkout osbook_day02a
$ cd ~/edk2
$ build

QEMUで動かしたす。

$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi

3ç«  画面衚瀺の緎習ずブヌトロヌダ

3.3 初めおのカヌネル

カヌネルをコンパむルしおリンクしたす。

$ cd $OS_DIR
$ git checkout osbook_day03a
$ cd kernel
$ clang++ -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone -fno-exceptions -fno-rtti -std=c++17 -c main.cpp
$ ld.lld --entry KernelMain -z norelro --image-base 0x100000 --static -o kernel.elf main.o

main.cppの䞭身は以䞋たった3行の無限ルヌプです。これがカヌネルです。

extern "C" void KernelMain() {
  while (1) __asm__("hlt");
}

ブヌトロヌダをビルドしおQEMUでカヌネルを起動したす。

$ cd ~/edk2
$ source edksetup.sh
$ build
$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi $OS_DIR/kernel/kernel.elf

info registersを実行したす。

(qemu) info registers
RAX=0000000000100000 RBX=000000003effef18 RCX=0000000000000000 RDX=0000000000000000
RSI=000000003feaca08 RDI=000000003feac9e0 RBP=000000003fea8850 RSP=000000003fea8850
R8 =000000003fea87c4 R9 =000000003fb7b48f R10=000000003fbcd018 R11=fffffffffffffffc
R12=000000003effe920 R13=000000003feac8d0 R14=000000003fea9110 R15=000000003e66273c
RIP=0000000000101011 RFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=1

次の実行される機械語呜什の䜍眮を瀺すRIP付近を2呜什分逆アセンブルしお衚瀺したす。

(qemu) x /2i 0x0000000000101011
0x00101011:  eb fd                    jmp      0x101010
0x00101013:  cc                       int3     

自分のアドレスにゞャンプしおいるので、コヌドの通り氞久ルヌプしおいそうですね。

3.4 ブヌトロヌダからピクセルを描く

$ cd $OS_DIR
$ git checkout osbook_day03b
$ cd kernel
$ clang++ -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone -fno-exceptions -fno-rtti -std=c++17 -c main.cpp
$ ld.lld --entry KernelMain -z norelro --image-base 0x100000 --static -o kernel.elf main.o
$ cd ~/edk2
$ source edksetup.sh
$ build
$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi $OS_DIR/kernel/kernel.elf

3.5 カヌネルからピクセルを描く

$ source ~/osbook/devenv/buildenv.sh
$ echo $CPPFLAGS
$ cd $OS_DIR
$ git checkout osbook_day03c
$ cd kernel
$ clang++ $CPPFLAGS -O2 --target=x86_64-elf -fno-exceptions -ffreestanding -c main.cpp
$ ld.lld $LDFLAGS --entry KernelMain -z norelro --image-base 0x100000 --static -o kernel.elf main.o
$ cd ~/edk2
$ source edksetup.sh
$ build
$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi $OS_DIR/kernel/kernel.elf

3.7 ポむンタ入門ポむンタずアセンブリ蚀語

以䞋のコヌドをfoo.cppずいう名前で保存したす。

#include <cstdint>

void foo() {
    int i = 42;
    int* p = &i;
    int r1 = *p;
    *p = 1;
    int r2 = i;
    uintptr_t addr = reinterpret_cast<uintptr_t>(p);
    int* q = reinterpret_cast<int*>(addr);
}

曞籍では、「Clangで最適化をかけずにコンパむルする」ず曞いおありたす。倚分以䞋のようにしお、アセンブリ蚀語にするずいうこずだず思いたす。

$ source ~/osbook/devenv/buildenv.sh
$ clang++ $CPPFLAGS -O0 --target=x86_64-elf -fno-exceptions -ffreestanding -c foo.cpp -S -masm=intel
$ less foo.s

最適化をかけないために-O0オプションを指定し、曞籍のIntel構文に合わせるために-masm=intelずいうオプションを指定しおいたす。

4ç«  ピクセル描画ずmake入門

4.1 make入門

makeを詊しおみたす。以䞋コマンドでビルドしたす。

$ cd $OS_DIR
$ git checkout osbook_day04a
$ cd kernel
$ make

make cleanもしおみたしょう。

$ make clean

4.2 ピクセルを自圚に描く

$ cd $OS_DIR
$ git checkout osbook_day04b
$ cd kernel
$ source ~/osbook/devenv/buildenv.sh
$ make
$ cd ~/edk2
$ source edksetup.sh
$ build
$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi $OS_DIR/kernel/kernel.elf

5章以降

同じ芁領で実践できるず思いたす。あずは曞籍ず合わせおお楜しみください。

もし、はたりやすいずころや、面癜いず思ったずころがあれば远蚘しおいきたす。

最終最新のMikanOSの動䜜

゚ミュレヌタでの動䜜確認

最終的なMikanOSを動かす方法です。ネむティブのLinuxのみで確認しおいたす。

Mac+Dockerでは./uefi.hpp:7:10: fatal error: 'Uefi.h' file not foundず゚ラヌになり動かせたせんでした原因調査䞭。

$ cd $OS_DIR
$ git checkout master
$ cd kernel
$ source ~/osbook/devenv/buildenv.sh
$ make
$ cd ~/edk2
$ source edksetup.sh
$ build
$ ~/osbook/devenv/run_qemu.sh ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi $OS_DIR/kernel/kernel.elf

以䞋のように衚瀺されたす。かなりOSっぜいですね。

実機での動䜜確認

USBメモリを挿入したす。ここで、挿入したディスクのデバむスファむル名を確認したす。dmesgやdfコマンドを䜿っお調べたしょう。

自分がよくやるのはdf -hをUSBメモリ挿入前、挿入埌で比范し、増えおいるもので特定する方法です。以降は/dev/sdbがUSBメモリの堎合の説明です。

ディスクをアンマりント、FATでフォヌマット、マりントしおファむルの曞き蟌み、アンマントを実斜したす。

$ sudo umount /dev/sdb
$ sudo mkfs.fat /dev/sdb
$ sudo mkdir -p /mnt/usbmem
$ sudo mount /dev/sdb /mnt/usbmem
$ sudo mkdir -p /mnt/usbmem/EFI/BOOT
$ sudo cp ~/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi /mnt/usbmem/EFI/BOOT/BOOTX64.EFI
$ sudo cp $OS_DIR/kernel/kernel.elf /mnt/usbmem/
$ sudo umount /dev/sdb

䞊蚘コマンドを実行するず、メモリの䞭のファむル構成は、曞籍の通り以䞋のようになっおいるはずです。

kernel.elf
/EFI/BOOT/BOOTX64.EFI

この状態で、PCを再起動しおUSBメモリからブヌトさせたす。

USBからブヌトを遞択したす。

無事起動ず蚀いたいずころですが、マりスが動きたせんでした。自䜜OSの沌は深い 

トラブルシュヌティング

git checkoutできない

ずりあえず以䞋実行しおから、git checkoutしたしょう。コマンドの意味は別途調べおおきたしょう。

$ git stash

寄り道 フルスクラッチで䜜る!UEFIベアメタルプログラミング

以䞋のブログで、他にも自䜜OSの情報があるこずを知りたした。

https://fukuno.jig.jp/3165

以䞋、無料で公開されおいたす。

http://yuma.ohgami.jp/UEFI-Bare-Metal-Programming/

玠晎らしい情報です。こちらの曞籍は、edk2を䜿わない分、より䜎レむダヌぞの理解が深たりそうです。ただ、この蚘事の内容「れロからのOS自䜜入門」読んで事前知識なかったら、䜕から初めおよいか途方にくれおいたず思いたす。「れロからのOS自䜜入門」読んで、開発方法などを身に぀けた埌なら、ちょちょいのちょいですね。ありがずう「れロからのOS自䜜入門」。

たずは「hello world」をやっおみたしょう。

適圓なディレクトリを䜜りたす。

$ mkdir -p ~/work && cd ~/work

プログラムをダりンロヌドしお、コンパむル&ビルドしたす。

$ curl -O https://raw.githubusercontent.com/cupnes/c92_uefi_bare_metal_programming_samples/master/sample1_1_hello_uefi/main.c
$ clang -target x86_64-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -Wall -c main.c
$ lld-link /subsystem:efi_application /entry:efi_main /out:main.efi main.o

/entry:efi_mainず゚ントリヌポむントを指定しないずいけない点が泚意です。これは「れロからのOS自䜜入門」では省略されおいたポむントですね。「フルスクラッチで䜜る!UEFIベアメタルプログラミング」では、このあたり説明されおいるので、良い補完関係になっおいるず思いたす。

続いお、「れロからのOS自䜜入門」通りにむメヌゞを䜜りたす。

$ 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 main.efi mnt/EFI/BOOT/BOOTX64.EFI
$ sudo umount mnt

QEMUで実行したら「Hello UEFI」ず衚瀺されたす。

$ qemu-system-x86_64 -drive if=pflash,file=$HOME/osbook/devenv/OVMF_CODE.fd -drive if=pflash,file=$HOME/osbook/devenv/OVMF_VARS.fd -hda disk.img

たずめ

「れロからのOS自䜜入門」が動かせない人・䜕をしおいるかよく分からない人の助けになるような蚘事を曞いおみたした。

自分自身もただただ理解できおないずころがあるので、これはずいうポむントあれば、随時远蚘しおいきたいず思いたす。

れロからのOS自䜜入門

参考リンク

公匏サむト

https://zero.osdev.jp/

https://github.com/uchan-nos/mikanos-build

動画

https://www.youtube.com/playlist?list=PLbBGNsln3DxTLHB9GFM6_drAJ1JQXIOud

Macでの動䜜

https://qiita.com/yamoridon/items/4905765cc6e4f320c9b5

https://zenn.dev/sarisia/articles/6b57ea835344b6

https://gokids.hatenablog.com/entry/2018/11/14/190000

https://zenn.dev/nnabeyang/scraps/f9151dfbe4f294

蚘事

https://zenn.dev/misawa/books/zero2os-notes

Discussion

dtrackerherodtrackerhero

倱瀌したす。私も最近自䜜OS入門を始めお、第章の画面衚瀺の緎習のずころで、癜が衚瀺されるだけの状態になりたした。解決策が分からず、攟り出しそうになりかけたずころ、スクラップを含めたこの蚘事を拝芋させおいただきたした。よろしければ、解決策をご教瀺いただけないでしょうか。よろしくおねがいしたす。

からあげからあげ

@dtrackerhero さん
返信おそくなり申し蚳ありたせん。

ネむティブのMac環境だず私は結局できなくお、ここに蚘茉あるようにMac(Intel)+DockerやネむティブのLinuxを䜿いたした。

yisakayisaka

倱瀌したす
䞀点気づいた点があったのでコメントしたす

「VS Code devcontainerセットアップ」でのシンボリックリンクの蚭定で
$ ln -s $HOME/workspace/mikanos/MikanLoaderPkg ./
ずなっおいたすがmikanos-devcontainerを甚いた堎合「MikanLoaderPkg」が配眮されるのは /workspaces/mikanos-devcontainer/mikanos/MikanLoaderPkg かず思いたす

ですので䞋蚘のように修正する必芁があるず思いたした
↓ 修正版
$ ln -s /workspaces/mikanos-devcontainer/mikanos/MikanLoaderPkg ./

䞊蚘修正をするこずで「2.2 EDK Ⅱ でハロヌワヌルド」p51のbuildが通るようになりたした

もし私の芋圓違いでしたらすみたせん

5
からあげからあげ

コメントありがずうございたす。この蚘事では workspaceで統䞀しおいるのでworkspaceで問題なかった蚘憶ですが、蚘事を曞いおからだいぶ時間が経っおいるので自信がありたせん。
たた詊す機䌚があったら芋盎したいず思いたす。

1
yisakayisaka

お返事頂きありがずうございたす
はいたた機䌚があればお詊しください

環境構築をするにあたりこちらの蚘事倧倉参考になりたした
ありがずうございたした

1
morominmoromin

コメント倱瀌したす。
「VS Code devcontainerセットアップ」のコンテナ内でコマンドを実行しおいくずころなのですが、cpコマンドの匕数コピヌ元、コピヌ先が逆になっおいるかもしれたせん。

元cp /workspaces/mikanos-devcontainer/target.txt Conf/target.txt
修正cp Conf/target.txt /workspaces/mikanos-devcontainer/target.txt

私の環境だず、䞊蚘修正を加えたずころ、ファむルのコピヌが成功したした。

私の勘違いだったらすみたせん。

1