こんにちは!
先日、OSの開発をするためにAIに相談してみたという記事を書きました。
方向性は固まったものの、まずは簡易的なOSを作るところから始めます。
まだうまくいっておらず、今回は途中経過です。
環境構築
Dockerで動かしてみたいので、まずはDockerfileから。
FROM ubuntu:latest
RUN apt-get update && \
apt-get install -y nano build-essential nasm qemu-system-x86
ビルド
docker build -t os-dev .
実行
docker run -it --name os-dev-container os-dev
コンテナに入った直後の状態
root@69205e6f39e2:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
作業ディレクトリを作成して、始めます。
mkdir work
cd word
OS用のコード
以下の3ファイルを作成。
boot.asm:
ブートローダーと通信するためのマルチブートヘッダとカーネルのエントリポイント定義。
kernel.c:
カーネルの主要な処理(ここでは画面出力)を行うメイン関数の実装。
link.ld:
カーネルのメモリレイアウトとエントリポイントの設定を行うリンカスクリプト。
section .multiboot_header
align 4
dd 0xe85250d6
dd 0
dd - (0xe85250d6 + 0)
section .text
global start
extern kernel_main
start:
mov esp, kernel_stack_top
call kernel_main
jmp $
section .bss
resb 8192
kernel_stack_top:
void kernel_main() {
char* video_memory = (char*) 0xb8000;
*video_memory = 'X';
}
void dummy() {
}
ENTRY(start)
SECTIONS {
. = 1M;
.multiboot_header : {
*(.multiboot_header)
}
.text : {
*(.text)
}
.bss : {
*(.bss)
}
}
boot.asm ファイルをアセンブルして、オブジェクトファイル boot.o を生成します。
nasm -f elf32 boot.asm -o boot.o
kernel.c ファイルをコンパイルして、オブジェクトファイル kernel.o を生成します。
gcc -m32 -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra
リンカスクリプト link.ld を使用して、オブジェクトファイル boot.o と kernel.o をリンクして、実行可能なカーネルイメージ kernel.bin を生成します。
ld -m elf_i386 -T link.ld -o kernel.bin boot.o kernel.o
実行
それでは、Docker上で実行してみましょう!
qemu-system-x86_64 -kernel kernel.bin -display curses -machine type=pc-i440fx-3.1
お、これは、、
SeaBIOS (version 1.15.0-1)
iPXE (https://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+07F8B440+07ECB440 CA00
Booting from ROM...
きたか??
と思ったら、全然進みません。
時間がかかるのかと思い、しばらく離席しましたが、全く進みません。
どうやら失敗しているようです。
トラブルシューティング
以下のコマンドでログ出力し、再実行。
qemu-system-x86_64 -kernel kernel.bin -display curses -machine type=pc-i440fx-3.1 -d int,cpu_reset -D qemu.log
ログを確認してみます。
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=00000000 EFL=00000000 [-------] CPL=0 II=0 A20=0 SMM=0 HLT=0
ES =0000 00000000 00000000 00000000
CS =0000 00000000 00000000 00000000
SS =0000 00000000 00000000 00000000
DS =0000 00000000 00000000 00000000
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 00000000 00000000
TR =0000 00000000 00000000 00000000
GDT= 00000000 00000000
IDT= 00000000 00000000
CR0=00000000 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=0000000000000000 DR7=0000000000000000
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=0000 FSW=0000 [ST=0] FTW=ff MXCSR=00000000
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
最初は良さそうなのですが、途中から
SMM: after RSM
EAX=000000b5 EBX=00007d44 ECX=00005678 EDX=00000003
ESI=07ecb440 EDI=07fbec71 EBP=00006958 ESP=00006958
EIP=00007d44 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =d980 000d9800 ffffffff 00809300
CS =f000 000f0000 ffffffff 00809b00
SS =0000 00000000 ffffffff 00809300
DS =0000 00000000 ffffffff 00809300
FS =0000 00000000 ffffffff 00809300
GS =ca00 000ca000 ffffffff 00809300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 00000000
IDT= 00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000001 CCO=EFLAGS
EFER=0000000000000000
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
check_exception old: 0xffffffff new 0x6
と、「check_exception old: 0xffffffff new 0x6」が延々と続きます。
よく分からないので、他のブログを確認したり、AIに聞いてみたりしているところです。
まとめ
今回は、初のチャレンジとして、簡易的なOSの開発を行なってみました。
まだ解決できていない問題がありますが、引き続き調査し、解決編を執筆できるようにがんばります
色々とチャレンジしてみると面白いので、みなさん一緒にチャレンジしましょう