0xc00000000
私の本の中には、Linuxカーネルが32ビットシステムにあり、パフォーマンス上の理由でユーザースペースにマップされていることに注意してください。
これは正しいですか?これをどのように確認しますか?
また、64ビットシステムではカーネルはどこにありますか?まだそこにありますか0xc00000000
、それとも別の場所にありますか?
答え1
物理メモリ
物理メモリでは、カーネルは通常上記のランダムオフセットにあります0x1000000
。これは、カーネル設定オプションとCONFIG_PHYSICAL_START
カーネルコマンドラインオプション/によって異なります。CONFIG_PHYSICAL_ALIGN
CONFIG_RANDOMIZE_BASE
kaslr
nokaslr
Linuxインサイダーブック。
仮想メモリ(32ビット)
32ビットアーキテクチャでは、仮想アドレス空間の分割はカーネル構成オプションによって異なります。CONFIG_PAGE_OFFSET
多くのアーキテクチャでは、これはCONFIG_VMSPLIT_*
オプションによって暗黙的に設定されます。カーネルの構成は通常、カーネルイメージで構成されているため、カーネル/boot/config-<version>
領域が始まる仮想メモリからオフセットを確認できますgrep PAGE_OFFSET "/boot/config-$(uname -r)"
。 x86の一般的な構成は、CONFIG_VMSPLIT_3G
0xC0000000を0xC0000000に設定して、PAGE_OFFSET
カーネル用のアドレス空間の上位1GiBを予約することです。パフォーマンス上の理由から、このマッピングはすべてのユーザー空間プロセスを含むすべての仮想アドレス空間で同じままです。
カーネルコードが始まる正確なアドレスはこの領域のどこかにあり、起動時にランダムに指定できます。これは、物理アドレスのランダム化と同じ構成とカーネルのコマンドライン設定によって異なります。
仮想メモリ(64ビット)
64ビットアーキテクチャでは、アドレス空間がはるかに大きいため、状況は異なります。
詳細はアーキテクチャによって異なりますが、通常、カーネルはアドレス空間の上部のメモリ範囲にあります。
x86-64
x86-64(別名AMD64)では、メモリレイアウトは次のとおりです。よく記録された。ハードウェアサポートと設定オプションに応じて、2つの設定が可能ですCONFIG_X86_5LEVEL
。
開始(4段階ページング) | 寸法(レベル4ページ) | 開始(5段階ページング) | 寸法(レベル5ページ) | 説明する |
---|---|---|---|---|
0xFFFF800000000000 |
8チタンホウ素 | 0xFF00000000000000 |
4PiB | ハイパーバイザー用に予約された保護穴 |
0xFFFF880000000000 |
0.5TiB | 0xFF10000000000000 |
0.25PiB | PTIのLDTリマッピング |
0xFFFF888000000000 |
64チタンホウ素 | 0xFF11000000000000 |
32スキンB | すべての物理メモリの直接マッピング |
0xFFFFC90000000000 |
32TB | 0xFFA0000000000000 |
12.5PiB | vmalloc/ioremap スペース |
0xFFFFEA0000000000 |
1TB | 0xFFD4000000000000 |
0.5PiB | 仮想メモリマッピング |
0xFFFFEC0000000000 |
16TB | 0xFFDF000000000000 |
8PiB | カサンシャドウメモリ |
ここでも同じレイアウト | ||||
0xFFFFFE0000000000 |
0.5TB | cpu_entry_areaマッピング | ||
0xFFFFFF0000000000 |
0.5TB | %esp修理スタック | ||
0xFFFFFFEF00000000 |
64GB | EFIゾーンマッピングスペース | ||
0xFFFFFFFF80000000 |
512MB | カーネルテキストマップ、物理アドレス 0 にマッピング | ||
0xFFFFFFFFA0000000 |
1520MB | モジュールマッピングスペース | ||
FIXADDR_START |
~0.5MB | マッピング範囲、可変サイズ、およびオフセットのカーネル内部修正 | ||
0xFFFFFFFFFF600000 |
4KB | レガシー vsyscall ABI |
したがって、カーネル領域はまたは0xFFFF800000000000
で始まり、0xFF00000000000000
カーネルコードはで始まる領域に(通常は任意のオフセットに)常駐します0xFFFFFFFF80000000
。
ARM64
64ビットARMの場合メモリレイアウトはx86-64のレイアウトと多少似ています。。正確な分割は、カーネル構成(4kB / 64kBページ、2/3/4レベルページング)によって異なります。
ページサイズ | ページングレベル | カーネル領域の開始アドレス |
---|---|---|
4KB | サム | 0xFFFFFF8000000000 |
4KB | 4 | 0xFFFF000000000000 |
64KB | 2 | 0xFFFFFC0000000000 |
64KB | サム | 0xFFFF000000000000 |
答え2
これはaslrのために任意の場所にあります(ファイルを64ビットシステムでコンパイルしたと仮定すると、2016年なので64ビットシステムを実行する必要があるため、そうしない理由はありません.... .システムが低レベルの場合)64ビットカーネル+メモリの32ビットユーザー領域のみ実行)