-
Notifications
You must be signed in to change notification settings - Fork 10
zulinx86; home
Takahiro Itazuri edited this page Jan 27, 2023
·
59 revisions
低レイヤーの技術に興味があり、個人的に勉強を進めています! まだまだ初学者ですが、頑張ります!
- 開発環境
- ローカル PC: macOS Catalina 10.15.7
- ビルド環境: Ubuntu 18.04 on EC2 (AMI: ami-0ef85cf6e604e5650)
- 実機環境
-
ASUS ZenBook UX310UQ
- CPU: Intel Core i5-7200U
- GPU: NVIDIA GeForce 940MX
- Memory: 8 GB (DDR4-2133)
- Storage: SSD 256 GB
-
ASUS ZenBook UX310UQ
1 章 (2021/03/25)
- バイナリエディタ Hex Friend をインストール
- 「Disk Utility」から USB を「MS-DOS (FAT)」にフォーマットし、BOOTX64.EFI をコピー
- 1.1 ハローワールド
- 実機で動作確認
- 1.4 エミュレータでのやり方
- QEMU で動作確認
$ git clone https://github.com/uchan-nos/mikanos-build.git
$ MIKANOS_BUILD=<mikanos-build へのパス>
$ qemu-img create -f raw disk.img 200M
$ hdiutil attach -nomount disk.img
/dev/disk3
$ newfs_msdos /dev/disk3
$ mkdir mount
$ mount -t msdos /dev/disk3 mnt/
$ mkdir -p mnt/EFI/BOOT
$ cp BOOTX64.EFI mnt/EFI/BOOT
$ hdiutil deatch disk3
$ 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
- 1.9 C 言語でハローワールド
-
Ubuntu 18.04 上に開発環境構築
- Mac 環境でやってらっしゃる方 もいらっしゃいましたが、私のような初心者はとりあえず環境を合わせてやることに。
- 実機と QEMU で動作確認
-
Ubuntu 18.04 上に開発環境構築
2 章 (2021/03/26)
- EDK II による
build
時にNo module named 'distutils.util'
エラーが出たら、python3-distutils をインストール
$ sudo apt install python3-distutils
- 3.3 初めてのカーネル
-
3.4 ブートローダからピクセルを描く
- 実機だと "Kernel: " の行だけじゃなく、左上の部分が大きく黒くなった。推測でしかないが、別のフレームバッファが存在していて、何らかの更新があった場合に、そのフレームバッファ全体が描画されてそう。
- 3.5 カーネルからピクセルを描く
-
3.6 エラー処理をしよう
-
kernel_file_size
に大きな値を入れて、わざとページ割り当てに失敗するようにして、エラー処理ができていることを確認。
-
- 4.2 ピクセルを自在に描く
-
4.3 C++ の機能を使って書き直す
- C++ のクラスと継承の復習
- 配置 new の勉強
- 6.1 マウスカーソル (2021/04/01)
- 6.2 PCI デバイスの探索 (2021/04/01)
- 6.4 ポーリングでマウス入力
- USB 関連のドライバーも理解したくて、uchan さんの「USB 3.0 ホストドライバ自作入門 - Hello uchan world - BOOTH」を購入
- なぜか QEMU でも、実機でもマウスが動いれくれず。。。 (2021/04/04)
- uchan さんがアドバイスをくださいました! (2021/04/05)
- 色々あって途中で挫折してしまったが、2021 年のやり残したこと No.1 なので、再開することを決意。
- とりあえず写経は諦めて読破を目標とし、一度読破した後に、写経したり、気になったところを深掘りしていく。
- 気になった点・深掘りしたい点
- コンパイラやリンカのオプションがそれぞれどういう意味なのか。
- 気になった点・深掘りしたい点
- AppPkg 配下のアプリケーションの例を通して、UEFI に慣れたい。
- OVMF の実装を読みたい。
- 気になった点・深堀りしたい点
- 名前修飾 (name mangling) の規則を調べる。
-
-fno-rtti
の動的型情報とは何か。なぜ必要か。 -
-z norelro
でリロケーション情報を read only にしてはいけない理由は何か。 -
reinterpret_cast
を含むキャスト周りとしっかりと勉強しておきたい。https://en.cppreference.com/w/cpp/language/reinterpret_cast -
alignas
とalignof
を使ってみる。
- 気になった点・深堀りしたい点
- C++ の純粋仮想関数や継承、メソッドオーバーライド周りを復習しておきたい。
- 配置 new を定義するときのシンタックスを確認しておきたい。https://en.cppreference.com/w/cpp/language/new
- 「リンカ・ローダ実践開発テクニック」も積読にしてしまってるので、読んでおきたい。
- 気になった点・深掘りしたい点
-
makefont.py
の中身を読んでおきたい。 - Newlib の中身が気になる。
- Newlib を使わずに標準ライブラリの関数を自前実装してみたい。
-
- 気になった点・深堀りしたい点
- USB ドライバーの実装を読む。
- PCI / PCIe について理解を深める。
- 気になった点・深堀りしたい点
- 「30 日でできる!OS 自作入門」でやった割り込みと違って PIC の初期化とかがなかったが、UEFI がやってくれてるのだろうか。
- 「30 日でできる!OS 自作入門」でやった割り込みでは、IRETD 命令を使って割り込み処理から抜けていて、EOI への通知は明示的に実行してなかったが、この辺がどうなってるのか。
- 気になった点・深掘りしたい点
- 64-bit mode におけるメモリ管理の知識を深めておきたい。
- UEFI がデフォルトで設定している GDT や Paging をダンプできるようにしたい。
- 転職など色々あり、Second Try も挫折しました。
- 友人が読み進めるというので、便乗して再び完走を目指します。
- 今回は開発環境は M1 Mac で開発しようと思います。
- 1.1 ハローワールド
- バイナリエディタは Visual Studio Code の Hex Editor を使用
$ dd if=/dev/zero of=BOOTX64.EFI bs=1 count=0x600 1536+0 records in 1536+0 records out 1536 bytes transferred in 0.010300 secs (149126 bytes/sec)
$ sum BOOTX64.EFI 12430 2 BOOTX64.EFI
- バイナリエディタは Visual Studio Code の Hex Editor を使用
- 1.4 エミュレータでのやり方
- 必要なパッケージのインストール
-
qemu
: エミュレータ本体 -
dosfstools
:mkfs.fat
コマンドで必要
$ brew install qemu dosfstools
-
- ループバックデバイスのマウントができない模様
$ qemu-img create -f raw disk.img 200M Formatting 'disk.img', fmt=raw size=209715200 $ mkfs.fat -n 'MIKAN OS' -s 2 -f 2 -R 32 -F 32 disk.img mkfs.fat 4.2 (2021-01-31) $ hdiutil attach -nomount disk.img /dev/disk4 $ diskutil list /dev/disk4 /dev/disk4 (disk image): #: TYPE NAME SIZE IDENTIFIER 0: MIKAN OS +209.7 MB disk4 $ sudo mount -t msdos /dev/disk4 mnt Executing: /usr/bin/kmutil load -p /System/Library/Extensions/msdosfs.kext $ sudo mkdir -p mnt/EFI/BOOT $ sudo cp BOOTX64.EFI mnt/EFI/BOOT/BOOTX64.EFI $ sudo umount mnt $ hdiutil detach disk4 "disk4" ejected.
- mikanos-build リポジトリを submodule に追加して、QEMU を実行。
$ git submodule add https://github.com/uchan-nos/mikanos-buil $ 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 $ ./mikanos-build/devenv/run_image.sh disk.img
- 必要なパッケージのインストール
- 1.9 C 言語でハローワールド
-
lld-link
コマンドを使うため、llvm
パッケージをインストールして、パスを通す。(今後のために .bashrc や .zshrc などに登録しておくとよい)$ brew install llvm $ export PATH=/opt/homebrew/opt/llvm/bin:$PATH
-
mikanos-build
のrun_qemu.sh
を使うために以下の変更を加えるdiff --git a/devenv/make_image.sh b/devenv/make_image.sh index 1f99933..0330974 100755 --- a/devenv/make_image.sh +++ b/devenv/make_image.sh @@ -30,4 +30,4 @@ then sudo cp $ANOTHER_FILE $MOUNT_POINT/ fi sleep 0.5 -sudo umount $MOUNT_POINT +hdiutil detach $MOUNT_POINT diff --git a/devenv/mount_image.sh b/devenv/mount_image.sh index ba8233e..fda1d59 100755 --- a/devenv/mount_image.sh +++ b/devenv/mount_image.sh @@ -17,4 +17,4 @@ then fi mkdir -p $MOUNT_POINT -sudo mount -o loop $DISK_IMG $MOUNT_POINT +hdiutil attach -mountpoint $MOUNT_POINT $DISK_IMG
- 本の通り実行
$ clang -target x86_64-pc-win32-coff -o hello.o -c hello.c $ lld-link /subsystem:efi_application /entry:EfiMain /out:hello.efi hello.o $ ../mikanos-build/devenv/run_qemu.sh hello.efi
-
- 2.2 EDK II でハローワールド
- EDK II のリポジトリのクローン
$ cd ~ $ git clone https://github.com/tianocore/edk2.git $ cd edk2 $ git submodule update --init
- EDK II のビルドに当たって以下のパッチを適用
--- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -89,7 +89,7 @@ BUILD_OPTFLAGS = -O2 $(EXTRA_OPTFLAGS) ifeq ($(DARWIN),Darwin) # assume clang or clang compatible flags on OS X BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror \ --Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -g +-Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -Wno-stringop-truncation -nostdlib -g else ifeq ($(CXX), llvm) BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -fwrapv \
- EDK II のビルド
$ cd BaseTools/Source/C $ make
-
MikanLoaderPkg.dsc
の[LibraryClasses]
に以下を追加RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
- ビルド前の準備
$ ln -s $WORKPLACE/mikanos/src/MikanLoaderPkg ./ $ source edksetup.sh
-
Conf/target.txt
の変更ACTIVE_PLATFORM = MikanLoaderPkg/MikanLoaderPkg.dsc # snipped TARGET = DEBUG # snipped TARGET_ARCH = X64 # snipped TOOL_CHAIN_TAG = CLANGPDB
- EDK II のリポジトリのクローン
- 3.3 初めてのカーネル
- readelf のインストール
$ brew install binutils $ echo 'export PATH="/opt/homebrew/opt/binutils/bin:$PATH"' >> ~/.zshrc $ source ~/.zshrc
- readelf の代わりに greadelf が使えるようになる
- readelf のインストール