私はLinuxカーネルアーキテクチャを専門的に学んでいて、3章メモリ管理を勉強しています。私が研究したとき、カーネルアドレス空間自体は直接マッピング領域、vmalloc領域、kmap領域、固定マッピング領域に分かれていました。
私が知りたいことは以下の通りです。
__va、__pa、およびその他の機能により、MMUなしで32ビットマシンのカーネルアドレス空間の直接マッピング領域(896MB)にアクセスできますか?
1.これがtrueの場合、デフォルトのカーネルページテーブル(swapper_pg_dir)は128 MBだけを管理しますか?
カーネルコードを見てみると、32ビットと64ビットのpaging_init関数に違いがあることがわかりました。 32ビットでは、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ビットではカーネルページテーブル関連の関数が見つかりません。ページングの初期化機能。
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
質問1と2への答え:いいえ。ページングが有効な場合、CPUコマンドは仮想アドレスのみを使用し、RAMを読み書きする前にMMUを使用して仮想アドレスを物理アドレスに変換します。__va
マクロは__pa
メモリにアクセスせずにアドレス空間間のアドレスを変換するだけです。 32ビットシステムでは、物理アドレスが仮想アドレスになるようにマッピングがすでに設定されているため、引数として指定された物理アドレスを__va
追加するだけです。0xc0000000
N
N+0xc0000000
CPUがアクセスしようとしているアドレスはマッピングする必要があり、MMUをバイパスすることはできません。したがって、128MBのマップを管理するだけでは十分ではありません。