linux-0.01 読み (3)
とりあえず、うにまがの_Linux のブートプロセスをみる_の 2002.5 〜 2002.9 なあたりのソレを読みつつ、ポイントを控えるかも。。
リアルモードからプロテクトモードへの移行
cr0 レジスタの最下位ビットが云々、との記述がある。1 ならプロテクトモードで 0 ならリアルモードとの事。
このあたりを切り口にうにまが読んでたらなんとなく見えてきたようなそうでも無いような。とりあえず setup_paging な末端な以下の処理は
orl $0x80000000,%eax movl %eax,%cr0 /* set paging (PG) bit */ ret /* this also flushes prefetch-queue */
諸々の準備を終えて cr0 な最下位ビットを 1 にしていますね。あるいは startup_32 な先頭部分の以下なソレは
startup_32: movl $0x10,%eax mov %ax,%ds mov %ax,%es mov %ax,%fs mov %ax,%gs lss stack_start,%esp call setup_idt call setup_gdt movl $0x10,%eax # reload all the segment registers mov %ax,%ds # after changing gdt. CS was already mov %ax,%es # reloaded in 'setup_gdt' mov %ax,%fs mov %ax,%gs lss stack_start,%esp
セグメントレジスタを 0x10 で初期化しつつ idt と gdt を設定して再設定してるように見えます。ただ、stack_start を esp に云々という処理は理解が微妙。
あるいはその直後の以下な部分
xorl %eax,%eax 1: incl %eax # check that A20 really IS enabled movl %eax,0x000000 cmpl %eax,0x100000 je 1b
は A20 が有効になってるかどうかなチェック (コメントにも記述あり) に見えるんですが、これって A20 が有効になるまではループし続けるんじゃないのか。
A20 がマスクされてたら 0x000000 と 0x100000 は同じソレを指すはずなので、これって A20 が有効になってるチェックなはずなんだけど、何故にここでなのかが微妙。
ここは一旦スルーするとして以降のソレが以下。
movl %cr0,%eax # check math chip andl $0x80000011,%eax # Save PG,ET,PE testl $0x10,%eax jne 1f # ET is set - 387 is present orl $4,%eax # else set emulate bit 1: movl %eax,%cr0 jmp after_page_tables
ええとコメント通り、cr0 の PG、ET、PE を eax に保存してます。で、ET がセットされているかどうかを確認して
testl $0x10,%eax
equal でなければ jmp してて、セットされてなかったらセットした後で cr0 に戻しております。
とりあえず
全然謎だらけなんですが、今からもう少しがつっと記事を読んでみます。
む
segment descriptor はプロテクトモードに移行する前に自分で作れ、という記述がある。てか、連載一発目でハードルが物凄く高いんですがorz
segment descriptor table という名前が付いてるようです。ってかプロテクトモードのセグメント・ワールドはさらに複雑に、という記述があるなorz
明日も会社に持ってって、って思ってますが多分読むヒマは無いはず。