背景
OSの勉強がしたくてMikanOSの本を購入した。実際に手を動かして学べる部分が多いテキストだが読むだけの部分も多いので、自分なりにその辺を文章の形でまとめることにした。
OSを作りたい
極論でいえばファイルの全てはバイナリから構成されている。OS自体もファイル、つまりバイナリから出来ているのだからバイナリエディタでOSも作成できる(すごい)。
作ったのかOS
今回バイナリエディタでパチパチ作成したのはEFIファイルと言われるもの。
EFIはExtensible Firmware Interfaceの略で、ブートローダ(OSをメインメモリに読み込んで起動させるプログラム)の機能を呼び出すファイルとなっている。
今回はUEFI BIOSという規格上で動くブートローダとしてEFIファイルを作成した。
OSを起動させたい
OS起動用USBの作成
今回はUSBから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 made.EFI mnt/EFI/BOOT/
sudo umount mnt
詳細は以下のようになる。
qemu-img create -f raw disk.img 200M
qemu-img create -f rawでraw形式のイメージ(disk.img)を作成している。200Mはイメージのサイズ(200MB)。
mkfs.fat -n 'Mikan OS' -s 2 -f 2 -R 32 -F 32 disk.img
作成したdisk.imgのフォーマットを行う。ファイルシステムはFATを使用。
オプションはFAT固有の値?(よくわからない)
mount -o loop disk.img mnt
イメージをマウント(フォーマット済みの領域に対し他のディレクトリからアクセスを行えるよう設定を行う)する。今回は作成したmntディレクトリをdisk.imgと結びつける。
その後mnt/EFI/BOOT/
ディレクトリを作成し、EFIファイルをそのディレクトリ配下に置く。
sudo umount mnt
マウント後はディレクトリをアンマウントする。
起動方法
(物理媒体を使っているならば)EFIファイルの保存されたUSBをPCに挿して電源を入れることでOSが起動する。上記のように仮想的にイメージを作成した場合はQEMUでOSを起動させることも可能である。
PC内のファームウェアといわれるプログラムが、OSをストレージ(2次記憶装置)からメインメモリ(主記憶装置)へと読み出す役割を担っている。
今回はUEFIというファームウェアが実行可能なEFIファイルを作成している。
C言語で作って起動しよう
C言語で作る場合
本来はEFIファイルをバイナリ直打ちで作成することはない。
今回作成したファイルも本来はC言語で作成されたものとなっている。
流れとしては、C言語で書かれたファイルをコンパイル(CPUが実行できるように機械語に翻訳)してオブジェクトファイルを作成し、その後リンクという作業を行うことで複数のオブジェクトファイルをまとめて1つのEFIファイルを作成する。
実行可能ファイルの形式について
C言語で書かれたファイルをコンパイルする形式としてはCOFF形式やELF形式などが存在する。今回はリンクの際にCOFF形式が要求されるため、C言語で書かれたファイルをCOFF形式でコンパイルされている。
COFFファイルをリンクすることでWindows標準のPE形式の実行可能ファイル(EFI)が得られる(本来はWindowsでのPEとUEFIのPEでは異なる部分がある)。
実行可能ファイルの形式としては他にもLinux標準であるELF形式などが存在する。
ELFは実行可能ファイルでもありながら、オブジェクトファイルとして表現されることも可能な形式となっている。