090310

|



先週、もつ定を食べに筑波に行った日のせいでハイエースが泥んこ。水洗いだ
けしました。ボンネットに汚れが沈着してしまっているのが前から気になって
いた。パーツクリーナーでも落ちないのでプラスチックコンパウンドで削り落
とした。イヤらしいくらいテカテカに。



x86もなんとか保護モードにまで入りました。x86はとにかくセグメントだ。保 護モードに入る前に少なくともメモリセグメントの設定をロードしないといけ ない。286の設定を引き継ぎ、そして割り込み、例外、トラップ、タスクもセグ メントとして扱えるようになっているのでその設定は混迷を極める。このあた りはインテルの初期のツールチェーンでは設定をビルドファイルに記述して、 「BLD オブジェクト BF(ビルドファイル)」というようにして、複雑さを包み込ん でいたようだ。
気をつけるのは、セグメントにはサイズじゃなくリミットを設定すること。 そうしないと4G設定できないしね。
スタックの時の設定はコード、データと違う。
下方伸張型セグメント(スタック)ではリミットは、設定の仕方が異なる。

上方伸張型: リミット+1 以上は違反
下方伸張型: リミット+1 以上(0xffffffffまで)が合法
となるので、
リミットはサイズをマイナスにして、さらに1を引いたものになる。

ESP <=>

プロテクトモードには
	lgdt	lgdt_arg
	movl	%cr0,	%eax
	orl	$0x1,	%eax
	movl	%eax,	%cr0
	ljmp	$0x8,	$flush	// Load CS(0x08) with pipeline flush.
flush:	.code32
	// Load DS(0x10),ES,FS,GS
	movw	$0x10,	%ax
	movw	%ax,	%ds
	movw	%ax,	%es
	movw	%ax,	%fs
	movw	%ax,	%gs
	// Load SS
	movw	$0x18,	%ax
	movw	%ax,	%ss
この入り方しかない。movl %eax, %cr0で、セグメントユニットのアドレス変換 機能が変わるので、パイプラインがある場合、それに入っているのをフラッシュ するのはいいとして、ljmpをどうフェッチするかだ。セグメント変換機能は変 更されたけれど、CSはまだ保護モード用に変更されてないし、既にリアルモー ドじゃない。
これはリアルモードで動いてるうちはプロセッサが自動的に保護モードのセグ メントデスクリプタをそれに矛盾のないように更新しているから大丈夫らしい。 このljmpの後が、gdtで設定したCS。このサンプルコードは、保護モードのCSを 設定(リアルモードのオフセット==保護モードのオフセット)してある。