📄 内存.txt
字号:
内存
内存
目 录
内存
内存管理子系统导读from aka
用户态
内核页目录的初始化
内核线程页目录的借用
用户进程内核页目录的建立
内核页目录的同步
mlock代码分析
memory.c
copy_page
clear_page_tables
oom
free_page_tables
new_page_tables
copy_one_pte
copy_pte_range
copy_pmd_range
copy_page_range
free_pte
forget_pte
zap_pte_range
zap_pmd_range
zap_page_range
zeromap_pte_range等
remap_pte_range等
put_dirty_page
handle_mm_fault
mmap.c
伙伴(buddy)算法
页目录处理的宏
MM作者的文章
内存
内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量。虚拟内存就是为了克服这个矛盾而采用的策略。系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量。
虚拟内存可以提供以下的功能:
*广阔的地址空间。
系统的虚拟内存可以比系统的实际内存大很多倍。
*进程的保护。
系统中的每一个进程都有自己的虚拟地址空间。这些虚拟地址空间是完全分开的,这样一个进程的运行不会影响其他进程。并且,硬件上的虚拟内存机制是被保护的,内存不能被写入,这样可以防止迷失的应用程序覆盖代码的数据。
*内存映射。
内存映射用来把文件映射到进程的地址空间。在内存映射中,文件的内容直接连接到进程的虚拟地址空间。
*公平的物理内存分配。
内存管理系统允许系统中每一个运行的进程都可以公平地得到系统的物理内存。
*共享虚拟内存。
虽然虚拟内存允许进程拥有自己单独的虚拟地址空间,但有时可能会希望进程共享内存。
linux仅仅使用四个段
两个代表 (code 和 data/stack)是内核空间从[0xC000 0000] (3 GB)到[0xFFFF FFFF] (4 GB)
两个代表 (code 和 data/stack)是用户空间从[0] (0 GB) 到 [0xBFFF FFFF] (3 GB)
__
4 GB--->| | |
| Kernel | | 内核空间 (Code + Data/Stack)
| | __|
3 GB--->|----------------| __
| | |
| | |
2 GB--->| | |
| Tasks | | 用户空间 (Code + Data/Stack)
| | |
1 GB--->| | |
| | |
|________________| __|
0x00000000
内核/用户 线性地址
linux可以使用3层页表映射,例如在高级的I64服务器上,但是i386体系结构下只有2层有实际意义:
------------------------------------------------------------------
线性地址
------------------------------------------------------------------
\___/ \___/ \_____/
PD 偏移 PF 偏移 Frame 偏移
[10 bits] [10 bits] [12 bits]
| | |
| | ----------- |
| | | Value |----------|---------
| | | | |---------| /|\ | |
| | | | | | | | |
| | | | | | | Frame 偏移 |
| | | | | | \|/ |
| | | | |---------|<------ |
| | | | | | | |
| | | | | | | x 4096 |
| | | PF 偏移 |_________|------- |
| | | /|\ | | |
PD 偏移 |_________|----- | | | _________|
/|\ | | | | | | |
| | | | \|/ | | \|/
_____ | | | ------>|_________| 物理地址
| | \|/ | | x 4096 | |
| CR3 |-------->| | | |
|_____| | ....... | | ....... |
| | | |
页目录表 页表
Linux i386 分页
注意内核(仅仅内核)线性空间就等于内核物理空间,所以如下:
________________ _____
| 其他内核数据 |___ | | |
|----------------| | |__| |
| 内核 |\ |____| 实际的其他 |
3 GB --->|----------------| \ | 内核数据 |
| |\ \ | |
| __|_\_\____|__ Real |
| Tasks | \ \ | Tasks |
| __|___\_\__|__ Space |
| | \ \ | |
| | \ \|----------------|
| | \ | 实际内核空间 |
|________________| \|________________|
逻辑地址 物理地址
[内存实时分配]
|copy_mm
|allocate_mm = kmem_cache_alloc
|__kmem_cache_alloc
|kmem_cache_alloc_one
|alloc_new_slab
|kmem_cache_grow
|kmem_getpages
|__get_free_pages
|alloc_pages
|alloc_pages_pgdat
|__alloc_pages
|rmqueue
|reclaim_pages
·copy_mm [kernel/fork.c]
·allocate_mm [kernel/fork.c]
·kmem_cache_alloc [mm/slab.c]
·__kmem_cache_alloc
·kmem_cache_alloc_one
·alloc_new_slab
·kmem_cache_grow
·kmem_getpages
·__get_free_pages [mm/page_alloc.c]
·alloc_pages [mm/numa.c]
·alloc_pages_pgdat
·__alloc_pages [mm/page_alloc.c]
·rm_queue
·reclaim_pages [mm/vmscan.c]
[内存交换线程kswapd]
|kswapd
|// initialization routines
|for (;;) { // Main loop
|do_try_to_free_pages
|recalculate_vm_stats
|refill_inactive_scan
|run_task_queue
|interruptible_sleep_on_timeout // we sleep for a new swap request
|}
·kswapd [mm/vmscan.c]
·do_try_to_free_pages
·recalculate_vm_stats [mm/swap.c]
·refill_inactive_scan [mm/vmswap.c]
·run_task_queue [kernel/softirq.c]
·interruptible_sleep_on_timeout [kernel/sched.c]
[内存交换机制:出现内存不足的Exception]
| Page Fault Exception
| cause by all these conditions:
| a-) User page
| b-) Read or write access
| c-) Page not present
|
|
-----------> |do_page_fault
|handle_mm_fault
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -