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

アドレス空間


Rev.1を表示中。最新版はこちら

メモリマップ


アドレス空間
+-------------+ 0x00000000 (3GB)
| Process空間 |
| プロセス毎  |
|             |
|             |
|             |
|             |
|             |
|             |
|             |
|             |
|             |
+-------------+
| Kernel空間  | 0xc0000000 (high_memoryまで896MB)
|             |   物理ページ0以降へ順番にストレートマップされる(LowMem)
|             |   896MB以降の物理メモリはHighMem。
|             |
|             |
|             |
+-------------+ high_memory (0xf8000000) <== __va(highstart_pfn * PAGE_SIZE)
| 8MB hole    |  オーバラン検出用
+-------------+ VMALLOC_START (約112MB)
| vmalloc用   |
|             |
+-------------+ VMALLOC_END
+-------------+ PKMAP_BASE (PAGE_SIZE*(LAST_PKMAP + 1) 約4MB) CONFIG_HIGHMEM定義時のみ
|             |  1025 Page 1つのPageTableにはPTEは1024Entry
+-------------+ FIXADDR_BOOT_START
+-------------+ FIXADDR_START
|  :          |   fixed addr領域 ref to include/asm-i386/fixmap.h
+-------------+ FIXADDR_TOP (0xfffff000)
+-------------+ 0xffffffff


Kernel空間がストレートマップ出来るところまではLowMem(896MB)
それ以降はHighMemとなる。


1.5GB メモリ実装時
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009d000 (usable)
 BIOS-e820: 000000000009d000 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 000000005ffd0000 (usable)
 BIOS-e820: 000000005ffd0000 - 000000005ffde000 (ACPI data)
 BIOS-e820: 000000005ffde000 - 0000000060000000 (ACPI NVS)
 BIOS-e820: 00000000ffb80000 - 0000000100000000 (reserved)

(gdb) p max_pfn
$2 = 393168 <= 4096かけると0x5ffd0000 

(gdb) p max_low_pfn
$3 = 229376 <= 896MB LowMemの最後のページ番号

(gdb) p highstart_pfn
$9 = 229376
(gdb) p highend_pfn
$8 = 393168

(gdb) p/x high_memory
$5 = 0xf8000000


-----------------------------
HighMemory

カーネル空間(0xc0000000〜)からストレートマップされていないメモリ
896MB以降

ユーザ空間へのページの割り当てはGFP_HIGHUSERで積極的にHighMemoryを使用する。
(malloc()した領域もHIGHMEMからとられているっぽい。)

ユーザデータは出来るだけHighMemoryに追い出してLowMemoryを空ける。
カーネルデータはLowMemoryに置かれる(カーネル空間がストレートマップされているため)
<== 大規模なシステムだとカーネルデータが大きくなり、LowMemoryのサイズがネックになってくる
<== PageCache等のカーネルデータもHighMemoryを使えるみたい


カーネルがHighMemoryにアクセスする場合はkmap()を使って
一時的にHighMemoryの指定ページをカーネル空間内にマップする。
# 高速版のkmap_atomic()もある。kmap_atomic()ではマップしている間はsleep禁止。
# kmap()ではsleepしてよい。
#
# kmap()でマップしたページは PKMAP_BASEからの4MBの領域のどこかにマップされる。
# kmap_atomic()の場合はtypeによって静的に決定される。
# (fixed address領域のFIX_KMAP_BEGINから始まるエリア)


kmap(page)
	pageがHighMemでなければpage_address()で該当仮想アドレスを返す
	HighMemならkmap_high()->map_new_virtual()でマップ(PTE設定)してアドレスを返す

最終更新 2006/03/27 13:47:59 - kztomita
(2006/03/27 13:47:59 作成)


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