64bit環境での32bitプロセスの動作
Rev.3を表示中。最新版はこちら。
概要
64bit環境においても、32bitプロセスを動作させることができるが、どのように動作しているか。CPU(x86)の動作モード
まずはCPUの動作モードから。
Intel64アーキテクチャのCPUには、従来のProtectedモードの他にIA-32eモードがある。IA-32eモードの中にはさらに、64bitモードと互換モードの二つのサブモードがあり、互換モードでは、Protectedモードでの32bit動作と同じ動きをする。
64bitカーネル(CONFIG_X86_64付きでコンパイルされたカーネル)は、IA-32eモードの64bitサブモードで動作し、32bitプロセスを動作させる場合は、64bitモード、互換モードを切り替えながら動作する。
動作中のサブモードはCode Segmentによって決まる。現在使用中のCode Segment DescriptorのL bitが立っていると64bitモード、クリアされていると互換モードでの動作になる。
図1 Segment Descriptorのフォーマット
(Intel® 64 and IA-32 Architectures Software Developer’s Manualより)
セグメント設定
64bit環境では図2に示すようにGDTが作成されている。64bit(L bit = 1)のディスクリプタと32bit(L bit = 0)のディスクリプタがあり、64bit/32bitプロセスは、それぞれのCode Segment Descriptorを使用する。このため、64bitプロセスは64bitサブモードで、32bitプロセスは互換サブモードで動作する。
なお、Data Segmentは64bit/32bitで同じものを使用する。
図2 セグメント設定
(*) GDTの設定はarch/x86/kernel/cpu/common.c
補足:32bitプロセスのフラグ
32bitプロセスに設定されるフラグのメモ
_TIF_IA32
32bitプロセスのthread_info.flagsにセットされる。
TASK_SIZEマクロなどは本フラグの有無で値が変わり、仮想アドレス空間の割当て可能範囲が変わるようになっている。
32Bit Process: 0xffffe000 (*1)
64Bit Process: 0x7ffffffff000
(*1) 32BitカーネルだとTASK_SIZEは0xc0000000だが、64Bit環境だと32Bitプロセスでも0xffffe000まで利用できる。これは、64bit環境では0xc0000000以降にカーネル空間がないため。
TS_COMPAT
32bitプロセスがシステムコールを実行中にthread_info.statusに設定される。
32bitシステムコールの入り口で設定され、ユーザモードに戻る前にクリアされる。
64bit/32bitでシステムコールの引数の渡し方が異なるので、その処理の振り分けなどに使われる。