「オペレーティングシステム」の版間の差分

削除された内容 追加された内容
1,611 行
 
== プロテクトモード ==
プロテクトモードとは、CPUの32ビットモード(および32ビット以上のモード)のこと。
 
32ビットモードには、アクセス権の無い状態からのアクセスを禁止するという、特権レベルによる保護機能などがあるので、プロテクトモードという。
 
 
プロテクトモードにいこうするためのコードの一部を抜粋すると、おおむね書きのような感じになる<ref>白崎博生 著『Linuxのブートプロセスをみる』、株式会社KADOKAWA(発行)、アスキー・メディアワークス(プロデュース)、2014年10月2日 初版、98ページ </ref>。
 
1,636 ⟶ 1,641行目:
mov cr0, eax
</source>
の3行の処理で、cr0レジスタの最下位ビットを1に設定している。なお、このcr0の最下位ビットのことをプロテクト・エネーブルド pr0tect enebled という意味でPEビットという
 
 
1,647 ⟶ 1,652行目:
なので、CPUのパイプラインをフラッシュするためにジャンプ命令を使っている。
 
 
 
 
 
;全体像
さて、一般にWindowsやLinuxなどのOSには、パーティションという、インストール時にハードディスクの使用領域を決める機能がある。
 
実はCPU側に、メモリに関する機能だが、似たような動作を機能がある。
 
 
GDT(グローバル ディスクリプタ テーブル Global Descriptor Table)といって、メモリのアドレスのどこからどこまでがそのCPUで使える領域を定義する機能がある。
 
で、プロテクトモードでは、あらかじめ、このGDTを設定しないと動作しない。そういう仕様で、むかしのインテルあたりの人が決めてしまったので、従うしかない。
 
で、実はCPUにGDTレジスタ(GDTR)という、GDTの場所を保管する専用レジスタがあるので、このGDTレジスタにGDTのアドレスなどの情報を入れる必要がある。
 
さらに、このGDTレジスタに書き込むための専用の命令 lgdt (ロードgdt)があるので、これを使う必要がある。(「書き込みだから save では?」という疑問も、わくかもしれないが、こういう名前に決まってしまってるので、従うしかない。)
 
 
 
同様に IDT(Interrupt Descriptor Table)というのがある。
 
さらに、16ビット時代の昔はCPUのアドレスバスが20本までだったので、リアルモードでは利用するアドレスバスが20本までという制限が掛かっており、A00からA19までを使用している。A20以降はマスクされている。この制限のことを「A20のマスク」という。プロテクトモードに以降するためには、このA20のマスクを解除しないといけない。
 
 
下記の順序で作業しないといけない。そういう仕様である。
 
#  GDT(Global Descriptor Table)の作成
#  GDTレジスタの設定
#  IDT(Interrupt Descriptor Table)の作成
#  IDTレジスタの設定
#  A20のマスク解除
#  CPUへの割り込み禁止
#  cr0レジスタの最下位ビット(PEビット)を1に設定
#  CPUの先読み(パイプライン)を除去する(jmp命令で除去できる)
#  セグメントレジスタの設定
 
 
A20マスクの解除には複数の方法がある。
* キーボードコントローラーから解除
* System Control Portから制御
* BIOSの割り込み命令 int 15 で解除
 
 
キーボードコントローラから解除できる理由は、単に昔のインテルかどこかの人が設計したとき、たまたまキーボードコントローラ用のアドレスバスが余ってたからだけと言う理由らしく、あまり技術的な深い意味は無い。
 
 
なお作業の順番について、A20のマスク解除の順場は多少前倒しになっても平気なようである。
 
== Linuxのブートローダはkernelには無い ==