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 のマニュアルを睨んでみます。