More Related Content Similar to Ch. 3: Memory Management in Linux Similar to Ch. 3: Memory Management in Linux (20) Ch. 3: Memory Management in Linux3. 3
*. 一個小 job
*. 由 job 自行簡易管理
*. memory 不須劃分 pfn
*. 可存取任意位置
*. 數個小 job
*. memory 集中管理
*. memory 必須劃分 pfn
*. bitmap
*. 紀錄 free/reserve
*. 數個 job
*. memory 集中管理
*. memory 必須劃分 pfn
*. struct page
*. 紀錄複雜 status
page
page
page
page
kernel 初期
bootmem allocator
kernel 後期
buddy system
6. 6
6M
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
1M
2M
512M
512M
1. start_kernel 初始狀況 (MMU, mapping)
0xC0008000, kernel(init, text, data)
0xC0004000, page table
7. 7
Physical Address Virtual Address
0x00000000
512M
512M
*. mapping 目標存在 : CPU 可正常存取
*. mapping 多個目標 : ( 私以為 ) 不可能
mapping
destination
mapping
source
*. 多個 mapping 目標 overlap: 可以
*. mapping 目標不完全存在 :
目標存在部份 , CPU 可正常存取
目標不存在部份 , CPU 不可正常存取
*. mapping 根本沒建 : CPU 不可正常存取
*. mapping 目標不存在 : CPU 不可正常存取
這些 mapping 都紀錄在 page table 裡
結論 : 目標存在 , mapping 有建 -->( 原則上 ) 正常存取
8. 8
6M
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
1M
2M
512M
512M
1. start_kernel 初始狀況 (MMU, mapping)
1
CPUMMU
TLB
2
3
4
1. 當 CPU 對某 VA 作存取
2. 實際上會被 MMU 作 VA->PA 的轉換
3. TLB 是 MMU 的 cache, 快速查表
4. TLB 沒紀錄就去 page table 查表
5. 得到 PA 後 , 去實際所在作存取
*. 以上 , CPU 本身不知道
*. 建立 mapping 就是填值 , 讓 MMU 可以查表
9. 9
6M
Physical Address Virtual Address
1M
2M
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
0xC0008000, kernel(init, text, data)
0xC0000100, boot args
0xC0004000, page table
10. 10
6M
Physical Address Virtual Address
1M
2M
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
0xC0008000, kernel(init, text, data)
0xC0000100, boot args
0xC0004000, page table
sboot
*. 硬體初始化
*. 把 uboot 載入 memory
*. 交接給 uboot
uboot
*. 把 boot args 存在某位置
*. 把 kernel 載入 memory
*. 交接給 kernel
kernel
*. kernel 自行解壓縮 & 執行
*. 從某位置讀出 boot args
*. ......
11. 11
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
12. 12
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
0xC0510000, bitmap( 幾乎緊貼著 kernel)
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
14. 15
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
bootmem_data
node_min_pfn
node_low_pfn
node_bootmem_map
0xC0510000, bitmap
資料結構 ( 含 bitmap) + 演算法
--> bootmem allocator
kernel 一開始的 memory 管理
接下來如果需要 memory
bootmem allocator
會負責找合適的位置 & 回傳
page table
kernel
bitmap
15. 16
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
0xC0000000, section info
0xC0510000, bitmap
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
18. 19
page
page
page
page
page frame, ID 0
page frame, ID 0x40000
struct page array
Flat Model
0x00000000
1. 實體 memory 劃分成一堆 page frame
2. 每個 page frame 有自己的 unique ID
3. 分配一個 page frame, 建立 mem_section
3. 分配數個 page frame, 建立 struct page array
4. 每個 page frame 對應一個 struct page
5. mem_map 紀錄 struct page array 起點
( 示意圖 )
bitmap
mem_map
21. 22
Physical Address Virtual Address
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
zone 0
zone 1
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
highmem boundary
23. 24
Physical Address Virtual Address
Highmem
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
x86 case
Normal
DMA
Lowmem
(DMA+Normal)
DMA
Normal
超過 lowmem 的部份
無法 1-to-1 mapping
屬於 highmem
24. 25
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
Physical Address Virtual Address
0x00000000
Lowmem
(Normal)
x86 case arm case
Normal
DMA
Lowmem
(DMA+Normal)
boundary 是 CPU-specific
不同 CPU 可能不同
0x40000000
0x60000000
0xA0000000
0xC0000000
Normal
Highmem
Highmem
25. 26
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
Physical Address Virtual Address
0x00000000
Lowmem
(Normal)
arm case
our RAM
arm case
不同的 RAM 分佈
只差在 mapping 不同
0x40000000
0x60000000
0xA0000000
0xC0000000
Normal
Lowmem
(Normal)
Normal
Normal
Highmem
Highmem
26. 27
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
arm case
our RAM
Lowmem
(Normal)
Normal
Normal
Highmem
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
arm case
our RAM
our layout
Normal
Normal
Lowmem
(Normal)
我們沒讓 kernel 管理所有的 RAM
29. 31
UMA
(uniform memory access)
我們只有 1 個 node
我們有 2~3 個 zone
CPU CPU CPU
node zone
( 示意圖 )
node_zones[ZONE_NORMAL_MIU0]
zone_pgdat
zone_start_pfn
spanned_pages
present_pages
name
zone_pgdat
zone_start_pfn
spanned_pages
present_pages
name
node_zones[ZONE_NORMAL]
node_start_pfn
bdata
node_present_pages
node_spanned_pages
pg_data_t
0x9BC6
0x9D00
0x40200
"Normal_MIU0"
0x49F00
0x65E00
0x2E44
"Normal"
bootmem_data
node_min_pfn
node_low_pfn
node_bootmem_map bitmap 的位置 , in VA
0x40200
0xAFD00
contig_page_data
zone
30. 32
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table
0xC0000000, section info
0xC051E000, struct page array
0xC0510000, bitmap
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
31. 33
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar
0xC0000000, section info
0xC051E000, struct page array
0xC0510000, bitmap
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
32. 34
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd
0xC0000000, section info
0xC051E000, struct page array
0xC0510000, bitmap
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
33. 35
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
0xC0000000, section info
0xC051E000, struct page array
0xC0510000, bitmap
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
34. 36
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
0xC0000000, section info
0xFFFF0000, vector table
0xC051E000, struct page array
0xC0510000, bitmap
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
1. 目標存在
2. mapping 有建
3. 有程式可讓執行
35. 37
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
1
0xFFFF0000, vector table
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
*. kernel 裡有個 vector table
1. 分配一個 page frame, (PA)0x????????
2. 建立 mapping
(VA)0xFFFF0000 -> (PA)0x????????
3. 複製 vector table 到 0xFFFF0000
*. 發生 exception, CPU 會自動跳轉到對應項
Address Exception Type
0xFFFF0000 Reset
0xFFFF0004 Undefined instruction
0xFFFF0008 Software interrupt
0xFFFF000C Prefetch abort
0xFFFF0010 Data abort
0xFFFF0014 Reserved
0xFFFF0018 IRQ
0xFFFF001C FIQ
36. 38
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC0510000, bitmap
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
37. 39
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7 0xC0D46000, per-cpu data(for cpu1)
0xC0D36000, per-cpu data(for cpu0)
0xC0029000, per-cpu data
for cpu0
for cpu1
static
static
dynamic
+ reserve
dynamic
+ reserve
static kernel 自帶
bootmem
allocator
分配空間
38. 40
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7 0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC0510000, bitmap
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
39. 41
UMA
(uniform memory access)
我們只有 1 個 node
我們有 2~3 個 zone
CPU CPU CPU
node
zone
( 示意圖 )
node_zones[ZONE_NORMAL_MIU0]
zone_pgdat
zone_start_pfn
spanned_pages
present_pages
name
zone_pgdat
zone_start_pfn
spanned_pages
present_pages
name
node_zones[ZONE_NORMAL]
pg_data_t
0x9BC6
0x9D00
0x40200
"Normal_MIU0"
0x49F00
0x65E00
0x2E44
"Normal"
bootmem_data
node_min_pfn
node_low_pfn
node_bootmem_map bitmap 的位置 , in VA
0x40200
0xAFD00
contig_page_data
zonelist
_zonerefs[0]
_zonerefs[1]
zone
zone
fallback list
40. 42
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7 0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC0510000, bitmap
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
42. 46
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
vmalloc
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
12. 把所有 free page & bitmap 轉給 buddy system
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC0510000, bitmap
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init, text, data)
0xC0004000, page table
0xC0000100, boot args
63. 74
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
vmalloc
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
12. 把所有 free page & bitmap 轉給 buddy system
13. 建立 kmem cache
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init)
0xC0004000, page table
0xC0000100, boot args
0xC002C000, kernel(text, data)
112. 131
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
vmalloc
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
12. 把所有 free page & bitmap 轉給 buddy system
13. 建立 kmem cache
14. 建立 per-cpu 的 pageset
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC002C000, kernel(text, data)
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init)
0xC0004000, page table
0xC0000100, boot args
116. 135
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
vmalloc
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC002C000, kernel(text, data)
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init)
0xC0004000, page table
0xC0000100, boot args
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
12. 把所有 free page & bitmap 轉給 buddy system
13. 建立 kmem cache
14. 建立 per-cpu 的 pageset
15. 設定 zone 的 threshold
118. 138
1. start_kernel 初始狀況 (MMU, mapping)
2. 從 boot args 讀取 memory 範圍
3. 更新 mapping
4. 建立 bitmap, 預留位置 (bitmap, kernel, page table)
5. 建立 section info & struct page array
6. 設定 node & zone
7. 新增 mapping: vector table & mstar & twd & L2
8. 複製 vector table
9. 建立 & 複製 per-cpu data
10. 設定 zone 的 fallback list
11. 釋放 bank 之間對應的 struct page 給 bootmem
12. 把所有 free page & bitmap 轉給 buddy system
13. 建立 kmem cache
14. 建立 per-cpu 的 pageset
15. 設定 zone 的 threshold
16. 釋放 kernel 的 init 部份給 buddy system
Physical Address Virtual Address
0x40000000
0x60000000
0xA0000000
0xC0000000
0x00000000
59M
157M
216M
2
5
1
0
3
4
6
7
vmalloc
0xC0D46000, per-cpu data(for cpu1)
0xC0000000, section info
0xFFFF0000, vector table
0xC0D36000, per-cpu data(for cpu0)
0xC051E000, struct page array
0xC002C000, kernel(text, data)
0xC0029000, per-cpu data
0xC0009E04, vector table
0xC0008000, kernel(init)
0xC0004000, page table
0xC0000100, boot args
120. 140
Physical Address Virtual Address
0x00000000
static
static
dynamic
+ reserve
dynamic
+ reserve
page
page
page
page
pcp
high
batch
per_cpu_pageset
listslru
page
lru
page
pcp
high
batch
per_cpu_pageset
listslru
page
lru
page
RAM
bootmem
allocator
struct
page
array
pageset
buddy system
per-cpu
area