私はProfessionalLinux Kernel Architectureを勉強していて、第3章メモリ管理にいます。私が研究している間、カーネルアドレス空間自体は、直接マッピング領域、vmalloc領域、kmap領域、および固定マッピング領域に分割されます。
私が疑問に思っているのは、以下のようなものです。
32ビットマシンのカーネルアドレス空間のダイレクトマッピングエリア(896MB)には、MMUなしで__va、__ paなどの関数からアクセスできますか?
1.がtrueの場合、マスターカーネルページテーブル(swapper_pg_dir)は128MBのみを管理しますか?
カーネルコードを研究しているときに、32ビットと64ビットのpaging_init関数に違いがあることがわかりました。 32ビットでは、 paging_init 関数でカーネルページテーブルを初期化およびマスターするpagetable_init関数を見つけました。
32ビットの関数paging_init
void __init pageit_init(void){
pagetable_init();
__flush_tlb_all();
kmap_init();
olpc_dt_build_devicetree();
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
zone_sizes_init();
}
しかし、64ビットでは、 paging_init 関数にカーネルページテーブル関連の関数が見つかりませんでした。
void __init paging_init(void)
{
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
node_clear_state(0, N_MEMORY);
if (N_MEMORY != N_NORMAL_MEMORY)
node_clear_state(0, N_NORMAL_MEMORY);
zone_sizes_init();
}
64ビットカーネルにはマスターカーネルページテーブルがありませんか?それが本当なら、それは直接マッピングによってのみカーネルメモリにアクセスするだけですか?
質問1と2への回答:いいえ、ページングが有効になると、CPU命令は仮想アドレスのみを使用し、RAMの読み取りまたは書き込みの前にMMUを使用して物理アドレスに変換されます。__va
および__pa
マクロはメモリにアクセスせず、アドレス空間間でアドレスを変換するだけです。32ビットマシンでは、__va
は次のように指定された物理アドレスに0xc0000000
を追加するだけです。物理アドレスN
が仮想アドレスN+0xc0000000
になるようにマッピングが設定されているためです。
CPUでアクセスするアドレスには、マッピングが必要です。 MMUをバイパスすることはできません。したがって、128MBのみを管理するマッピングでは不十分です。