LoginSignup
4
4

More than 5 years have passed since last update.

はじめに

作りかけては断念し、というのを繰り返していたので、記録を兼ねて、記事にしていきます。

環境

今更、ブートローダーから書くのもだるいし、今時のOSっぽくないしということで、GRUBを使って起動させます。これで、アセンブリ言語を使う箇所が減らせます。

さらに、よくあるOS入門系の記事は、x86をターゲットに32bitOSを作っていますが、これも今時っぽくないので、x86_64をターゲットにしたいと思います。

なお、Bochsで、「The Multiboot Speci cation version 1.6」に準拠したものを起動させられなかったので、0.6.96準拠で行きたいと思います。

loader

GRUBに対応するには、multi boot headerが8192byte以内に存在している必要があります。それをloader.sで設定して上げる必要があります。

ついでに、なるべく早い段階でC言語で記述できるように、スタックポイントなどを指定して、メイン関数を呼び出します。

最低限の設定を行ったあと、C言語で記載した、カーネル本体にジャンプします。

loader.s
MAGIC_NUMBER    equ 0x1BADB002
MAGIC_FLAGS     equ 0x03
ALIGN_MODULE    equ 0x00000000
CHECK_SUM       equ -(MAGIC_NUMBER + MAGIC_FLAGS)

STACK_SIZE  equ 0x1000              ; Kernel Stack Size

global  loader
extern  kmain

section .mbheader
align 8
mbheader:
                dd  MAGIC_NUMBER
                dd  MAGIC_FLAGS
                dd  CHECK_SUM

section .text
align   8
loader:
;;; Initilized Stack Point
                mov esp, stack + STACK_SIZE

                push    ebx
                push    eax

                call    kmain
.loop:
                hlt
                JMP .loop

section .bss
align   8
stack:
                resb    STACK_SIZE
kernel.h
#ifndef __KERNEL_H__
#define __KERNEL_H__

typedef struct
{
    unsigned int    flags;
    unsigned int    mem_lower;
    unsigned int    mem_upper;
    unsigned int    boot_device;
    unsigned int    cmdline;
    unsigned int    mods_count;
    unsigned int    mods_addr;
    unsigned int    syms1;
    unsigned int    syms2;
    unsigned int    syms3;
    unsigned int  syms4;
    unsigned int    mmap_length;
    unsigned int    mmap_addr;
    unsigned int    drives_length;
    unsigned int    drives_addr;
    unsigned int    config_table;
    unsigned int    boot_loader_name;
    unsigned int    apm_table;
    unsigned int    vbe_control_info;
    unsigned int    vbe_mode_info;
    unsigned short  vbe_mode;
    unsigned short  vbe_interface_seg;
    unsigned short  vbe_interface_off;
    unsigned short  vbe_interrace_len;
} BOOTINFO;



void kmain(unsigned int magic, BOOTINFO *bootinfo);

#endif
kernel.c
#include <kernel.h>

void kmain(unsigned int magic, BOOTINFO *bootinfo)
{
}
link.ld
ENTRY(loader)

SECTIONS  {
        . = 0x00100000;
        .mbheader ALIGN (0x1000):
        {
                _kernel_start = .;
                *(.mbheader)
        }

        .text ALIGN (0x1000):
        {
                *(.text)
        }

        .rodata ALIGN (0x1000):
        {
                *(.rodata*)
        }
        .data ALIGN (0x1000):
        {
                *(.data)
        }
        .bss ALIGN (0x1000):
        {
                *(COMMON)
                *(.bss)
                _kernel_end = .;
        }
}

初期化状態

カーネル本体にジャンプした時点で、下記のように設定されています。

  • EAX 0x2BADB002
  • EBX ブート情報を記録したアドレスへのポインタ
  • CS 読み取り実行セグメント offset 0 limit 0xFFFFFFFF
  • DS,ES,FS,GS,SS 読み取り書き込みセグメント offset 0 limit 0xFFFFFFFF
  • A20GATE 有効
  • CR0 PG clear PE set
  • EFLAGS VM clear IF clear

今回のソース

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4