Linux Kernel(2.6)の実装に関するメモ書き

64bit環境での32bitプロセスの動作


概要

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のディスクリプタ(GDT_ENTRY_DEFAULT_USER_CS:L bit = 1)と32bitのディスクリプタ(GDT_ENTRY_DEFAULT_USER32_CS: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でシステムコールの引数の渡し方が異なるので、その処理の振り分けなどに使われる。


最終更新 2011/03/26 03:23:00 - kztomita
(2011/03/26 02:39:38 作成)
添付ファイル
descriptor.png - kztomita
segment.jpg - kztomita


リンク
最近更新したページ
検索