4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

自作OS(1) GRUBからの起動

Posted at

はじめに

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

環境

今更、ブートローダーから書くのもだるいし、今時の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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?