ブート・プロセス Edit

目次 Edit

ブート・プロセス Edit

GDT・IDTの設定 Edit

GDTは、32bitモードになったときに必ず必要なので、プロテクトモード移行前に設定しておきます。
IDTは別にこの段階で設定する必要がないようにも思いますが、ついでにやっておきます。

あらかじめデータセクションに、(仮)GDTのデータ・(仮)GDTRのデータ・(仮)IDTRのデータを用意しておきます。

ORIGIN			= 0x30000

#GDT/IDT
GDT_BASE		= 0x10000
GDT_LIMIT		= 0xffff
IDT_BASE		= 0xf800
IDT_LIMIT		= 0x07ff

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
	データ
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
	.section .data
/*******************************************************************************
	GDTR・GDT
*******************************************************************************/
/*------------------------------------------------------------------------------
	GDTR_TEMP
------------------------------------------------------------------------------*/
	.align		16
_GDTR_TEMP:
_GDTR_TEMP_Limit:
	.word		_GDT_END - _GDT - 1
_GDTR_TEMP_Base:
	.long		_GDT + ORIGIN

/*------------------------------------------------------------------------------
	GDTR
------------------------------------------------------------------------------*/
	.align		16
_GDTR:
_GDTR_Limit:
	.word		GDT_LIMIT
_GDTR_Base:
	.long		GDT_BASE

/*------------------------------------------------------------------------------
	GDT
------------------------------------------------------------------------------*/
	.align		16
_GDT:
_GDT_NULL:				#0x0000
	.word		0x0000
	.word		0x0000
	.byte		0x00
	.byte		0x00
	.byte		0x00
	.byte		0x00

_GDT_KernelCS:		#0x0008 Base:0x00000000, Limit:0xfffff(単位:Page), SegmentType:Code(Exe/Read)
	.word		0xffff
	.word		0x0000
	.byte		0x00
	.byte		0x9a
	.byte		0xcf
	.byte		0x00

_GDT_KernelDS:		#0x0010 Base:0x00000000, Limit:0xfffff(単位:Page), SegmentType:Data(Read/Write)
	.word		0xffff
	.word		0x0000
	.byte		0x00
	.byte		0x92
	.byte		0xcf
	.byte		0x00

_GDT_BootLoaderCS:	#0x0018 Base:0x00030000, Limit:0xfffff(単位:Page), SegmentType:Code(Exe/Read)
	.word		0xffff
	.word		0x0000
	.byte		0x03
	.byte		0x9a
	.byte		0xcf
	.byte		0x00

_GDT_END:


/*******************************************************************************
	IDTR
*******************************************************************************/
/*------------------------------------------------------------------------------
	IDTR
------------------------------------------------------------------------------*/
	.align		16
_IDTR:
_IDTR_Limit:
	.word		IDT_LIMIT
_IDTR_Base:
	.long		IDT_BASE

GDTRとIDTRを設定します。

/*------------------------------------------------------------------------------
	GDTRとIDTRの仮設定
------------------------------------------------------------------------------*/
	lgdt		_GDTR_TEMP
	lidt		_IDTR

A20ゲートの開放 Edit

A20を参照。

プロテクトモードへの移行 Edit

プロテクトモードへの移行は、CR0?のPEフラグを1にするだけなのでとても簡単です。
CR0に書き込んだ後は、必ず、near jmpでパイプラインのデータを消去しておきましょう。

CR0_PE			= 0x00000001		#プロテクト・イネーブル・フラグ

/*------------------------------------------------------------------------------
	プロテクトモード移行
------------------------------------------------------------------------------*/
	movl		%cr0,			%eax
	orl		$CR0_PE,		%eax		#プロテクト・イネーブル・フラグ
	movl		%eax,			%cr0
	jmp		_PipelineFlush				#パイプラインを流れているデータを消す。
_PipelineFlush:

32ビットへの移行 Edit

コード・セグメントに、Dbit?が1のセグメント・ディスクリプタを指すセグメント・セレクタをセットすることで、32ビットモードで動作します。

	#ここから32bitです。
	.code32
	.byte		0x66
	ljmp		$0x0018, $_SetCodeSegment		#far jmpでCSをセットする。(CSにDbit=1のディスクリプタを指すセレクタを読み込むことによって、32bitになる。)
_SetCodeSegment:

Since 2008 July. OS Project Wiki
リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS