簡易的なOSを作ってみる（未解決）

こんにちは！

先日、[OSの開発をするためにAIに相談してみた](https://qiita.com/yam_dev/items/0173abe20478356ac0c5)という記事を書きました。

方向性は固まったものの、まずは簡易的なOSを作るところから始めます。
まだうまくいっておらず、今回は途中経過です。

# 環境構築
Dockerで動かしてみたいので、まずはDockerfileから。

```dockerfile:Dockerfile
FROM ubuntu:latest

RUN apt-get update && \
    apt-get install -y nano build-essential nasm qemu-system-x86
```
ビルド
```bash
docker build -t os-dev .
```
実行
```bash
docker run -it --name os-dev-container os-dev
```
コンテナに入った直後の状態
```bash
root@69205e6f39e2:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
```
作業ディレクトリを作成して、始めます。
```bash
mkdir work
cd word
```
# OS用のコード
以下の3ファイルを作成。

**boot.asm:**
ブートローダーと通信するためのマルチブートヘッダとカーネルのエントリポイント定義。

**kernel.c:**
カーネルの主要な処理（ここでは画面出力）を行うメイン関数の実装。

**link.ld:**
カーネルのメモリレイアウトとエントリポイントの設定を行うリンカスクリプト。
```bash:boot.asm 
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:
```

```c:kernel.c
void kernel_main() {
    char* video_memory = (char*) 0xb8000;
    *video_memory = 'X';
}

void dummy() {

}
```

```bash:link.ld
ENTRY(start)

SECTIONS {
    . = 1M;

    .multiboot_header : {
        *(.multiboot_header)
    }

    .text : {
        *(.text)
    }

    .bss : {
        *(.bss)
    }
}
```
boot.asm ファイルをアセンブルして、オブジェクトファイル boot.o を生成します。
```bash
nasm -f elf32 boot.asm -o boot.o
```
kernel.c ファイルをコンパイルして、オブジェクトファイル kernel.o を生成します。
```bash
gcc -m32 -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra
```
リンカスクリプト link.ld を使用して、オブジェクトファイル boot.o と kernel.o をリンクして、実行可能なカーネルイメージ kernel.bin を生成します。
```bash
ld -m elf_i386 -T link.ld -o kernel.bin boot.o kernel.o
```

# 実行
それでは、Docker上で実行してみましょう！
```bash
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...

```
きたか？？
と思ったら、全然進みません。
時間がかかるのかと思い、しばらく離席しましたが、全く進みません。

どうやら失敗しているようです。

# トラブルシューティング
以下のコマンドでログ出力し、再実行。
```bash
qemu-system-x86_64 -kernel kernel.bin -display curses -machine type=pc-i440fx-3.1 -d int,cpu_reset -D qemu.log
```

ログを確認してみます。
```bash
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
```
最初は良さそうなのですが、途中から
```bash
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の開発を行なってみました。
まだ解決できていない問題がありますが、引き続き調査し、解決編を執筆できるようにがんばります:muscle:

色々とチャレンジしてみると面白いので、みなさん一緒にチャレンジしましょう:smiley: