setup_paging 手続き

なんつーか朝イチしかこれ系の時間が取れないですが、今日は昼に時間が取れそげ。
とりあえず順に掘削。

pg_dir is at 0x000

ええと以下は

setup_paging:
	movl $1024*3,%ecx
	xorl %eax,%eax
	xorl %edi,%edi			/* pg_dir is at 0x000 */
	cld;rep;stosl

0x0 から 3072 bytes 分を 0 で初期化しているのかな。

  • CLD 命令で DF をクリアして以降の命令でインデクスレジスタをストリングな命令実行時にインクリメントするように設定
  • rep 命令で繰り返しを指示
  • stosl 命令 (stosl ってマニュアルに出てないなぁ) で edi (0x0) から始まって ecx 分の領域 (3072 bytes) を eax (0x0) で初期化

という事と理解。

何してるのか意味不明。しかも部屋の隣と上で大工仕事が開始されますた。

	movl $pg0+7,pg_dir		/* set present bit/user r/w */
	movl $pg1+7,pg_dir+4		/*  --------- " " --------- */

pg_dir って何かというと記述が以下。

.code32
.text
.globl idt,gdt,pg_dir,startup_32
pg_dir:
startup_32:
	movl $0x10,%eax

ええと、pg_dir と startup_32 は同じソレを指してるって思って良いのかなぁ。あるいは $pg0+7 とか 7 加算してるんだけど意味がさっぱり分からない。
ちょっとここは一旦スルーします。
で、次のブロックなのですが以下。

	movl $pg1+4092,%edi
	movl $0x7ff007,%eax		/*  8Mb - 4096 + 7 (r/w user,p) */
	std
1:	stosl			/* fill pages backwards - more efficient :-) */
	subl $0x1000,%eax
	jge 1b
  • コピー先始点は $pg1+4092 (%edi の値)
  • コピーする情報は %eax の値 (最初は 0x7ff007 のはず)
  • %eax から 0x1000 をデクリメントしつつコピー実施
  • %eax の値が負になったらループ終了

という風に読めるのですが、これが何を意味するかは微妙だなぁ。4096 って hex にするとどうなるのだったかというと 0x1000 か。てことは

.org 0x2000
pg1:

.org 0x3000
pg2:		# This is not used yet, but if you
		# want to expand past 8 Mb, you'll have
		# to use it.

となっているから、pg1 が指す領域全部という事なのか。

で、最後に

	xorl %eax,%eax		/* pg_dir is at 0x0000 */
	movl %eax,%cr3		/* cr3 - page directory start */
	movl %cr0,%eax
	orl $0x80000000,%eax
	movl %eax,%cr0		/* set paging (PG) bit */
	ret			/* this also flushes prefetch-queue */

で、cr3 レジスタを初期化して cr3 の PG をリセットして ret してます。また、ret する事で main 手続きに jmp するというのが現時点の認識です。
とりあえず上記不明点を踏まえて、空き時間に intel のマニュアルを睨んでみます。