系列文章目录
Linux 内核设计与实现
深入理解 Linux 内核
Linux 设备驱动程序
Linux设备驱动开发详解
深入理解Linux虚拟内存管理(一)
深入理解Linux虚拟内存管理(二)
深入理解Linux虚拟内存管理(三)
深入理解Linux虚拟内存管理(四)
深入理解Linux虚拟内存管理(五)
深入理解Linux虚拟内存管理(六)
深入理解Linux虚拟内存管理(七)
深入理解Linux虚拟内存管理(八)
文章目录
- 系列文章目录
- 一、进程内存描述符
- 1、 进程内存描述符
- (1)初始化一个描述符
- (2)复制一个描述符
- (a)copy_mm
- (b)mm_init
- (3)分配一个描述符
- (a)allocate_mm
- (b)mm_alloc
- (4)销毁一个描述符
- (a)mmput
- (b)mmdrop
- (c)__mmdrop
- 2、创建内存区域
- (1)创建一个内存区域
- (a)do_mmap
- (b)do_mmap_pgoff
- (2)插入一个内存区域
- (a)__insert_vm_struct
- (b)find_vma_prepare
- (c)vma_link
- (d)__vma_link
- (e)__vma_link_list
- (f)__vma_link_rb
- (g)__vma_link_file
- (3)合并相邻区域
- (a)vma_merge
- (b)can_vma_merge
- (4)重映射并移动一个内存区域
- (a)sys_mremap
- (b)do_mremap
- (c)move_vma
- (d)make_pages_present
- (e)get_user_pages
- (f)move_page_tables
- (g)move_one_page
- (h)get_one_pte
- (i)alloc_one_pte
- (j)copy_one_pte
- (5)删除内存区域
- (a)do_munmap
- (b)unmap_fixup
- (6)删除所有的内存区域
- (a)exit_mmap
- (b)clear_page_tables
- (c)free_one_pgd
- (d)free_one_pmd
- 3、查找内存区域
- (1)查找已映射内存区域
- (a)find_vma
- (b)find_vma_prev
- (c)find_vma_intersection
- (2)查找空闲内存区域
- (a)get_unmapped_area
- (b)arch_get_unmapped_area
- 4、对内存区域上锁和解锁
- (1)对内存区域上锁
- (a)sys_mlock
- (b)sys_mlockall
- (c)do_mlockall
- (d)do_mlock
- (2)对区域解锁
- (a)sys_munlock
- (b)sys_munlockall
- (3)上锁/解锁后修整区域
- (a)mlock_fixup
- (b)ulock_fixup_all
- (c)mlock_fixup_start
- (d)mlock_fixup_end
- (e)mlock_fixup_middle
- 5、缺页中断
- (1)x86 缺页中断处理程序
- (a)do_page_fault
- (2)扩展栈
- (a)expand_stack
- (3)独立体系结构的页面中断处理程序
- (a)hanle_mm_fault
- (b)handle_pte_fault
- (4)请求分配
- (a)do_no_page
- (b)do_anonymous_page
- (5)请求分页
- (a)do_swap_page
- (b)can_share_swap_page
- (c)exclusive_swap_page
- (6)写时复制(COW) 页面
- (a)do_wp_page
- 6、页面相关的磁盘 I/O
- (1)一般文件读
- (a)generic_file_read
- (b)do_generic_file_read
- (c)generic_file_readahead
- (2)一般文件 mmap
- (a)generic_file_mmap
- (3)一般文件截断
- (a)vmtruncate
- (b)vmtruncate_list
- (c)zap_page_range
- (d)zap_pmd_range
- (e)zap_pte_range
- (f)truncate_inode_pages
- (g)truncate_list_pages
- (h)truncate_complete_page
- (i)do_flushpage
- (j)truncate_partial_page
- (4)从页面高速缓存中读入页面
- (a)filemap_nopage
- (b)age_cache_read
- (5)为 nopage() 进行预读文件
- (a)nopage_sequential_readahead
- (b)read_cluster_nonblocking
- (6)交换相关的预读
- (a)swapin_readahead
- (b)valid_swaphandles
- 符号
一、进程内存描述符
1、 进程内存描述符
(1)初始化一个描述符
系统中的 mm_struct 开始称为 init_mm ,它在编译时由宏 INIT_MM() 静态初始化。
// include/linux/sched.h
#define INIT_MM(name) \
{ \
mm_rb: RB_ROOT, \
pgd: swapper_pg_dir, \
mm_users: ATOMIC_INIT(2), \
mm_count: ATOMIC_INIT(1), \
mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \
page_table_lock: SPIN_LOCK_UNLOCKED, \
mmlist: LIST_HEAD_INIT(name.mmlist), \
}
// arch/i386/kernel/init_task.c
struct mm_struct init_mm = INIT_MM(init_mm);
新 mm_struct 在建立以后,是它们父 mm_struct 的备份,并且它们由 copy_mm() 以 init_mm() 初始化的字段来复制。
(2)复制一个描述符
(a)copy_mm
(b)mm_init
(3)分配一个描述符
(a)allocate_mm
(b)mm_alloc
(4)销毁一个描述符
(a)mmput
(b)mmdrop
(c)__mmdrop
2、创建内存区域
(1)创建一个内存区域
(a)do_mmap
(b)do_mmap_pgoff
(2)插入一个内存区域
(a)__insert_vm_struct
(b)find_vma_prepare
(c)vma_link
(d)__vma_link
(e)__vma_link_list
(f)__vma_link_rb
(g)__vma_link_file
(3)合并相邻区域
(a)vma_merge
(b)can_vma_merge
(4)重映射并移动一个内存区域
(a)sys_mremap
(b)do_mremap
(c)move_vma
(d)make_pages_present
(e)get_user_pages
(f)move_page_tables
(g)move_one_page
(h)get_one_pte
(i)alloc_one_pte
(j)copy_one_pte
(5)删除内存区域
(a)do_munmap
(b)unmap_fixup
(6)删除所有的内存区域
(a)exit_mmap
(b)clear_page_tables
(c)free_one_pgd
(d)free_one_pmd
3、查找内存区域
(1)查找已映射内存区域
(a)find_vma
(b)find_vma_prev
(c)find_vma_intersection
(2)查找空闲内存区域
(a)get_unmapped_area
(b)arch_get_unmapped_area
4、对内存区域上锁和解锁
(1)对内存区域上锁
(a)sys_mlock
(b)sys_mlockall
(c)do_mlockall
(d)do_mlock
(2)对区域解锁
(a)sys_munlock
(b)sys_munlockall
(3)上锁/解锁后修整区域
(a)mlock_fixup
(b)ulock_fixup_all
(c)mlock_fixup_start
(d)mlock_fixup_end
(e)mlock_fixup_middle
5、缺页中断
(1)x86 缺页中断处理程序
(a)do_page_fault
(2)扩展栈
(a)expand_stack
(3)独立体系结构的页面中断处理程序
(a)hanle_mm_fault
(b)handle_pte_fault
(4)请求分配
(a)do_no_page
(b)do_anonymous_page
(5)请求分页
(a)do_swap_page
(b)can_share_swap_page
(c)exclusive_swap_page
(6)写时复制(COW) 页面
(a)do_wp_page
6、页面相关的磁盘 I/O
(1)一般文件读
(a)generic_file_read
(b)do_generic_file_read
(c)generic_file_readahead
(2)一般文件 mmap
(a)generic_file_mmap
(3)一般文件截断
(a)vmtruncate
(b)vmtruncate_list
(c)zap_page_range
(d)zap_pmd_range
(e)zap_pte_range
(f)truncate_inode_pages
(g)truncate_list_pages
(h)truncate_complete_page
(i)do_flushpage
(j)truncate_partial_page
(4)从页面高速缓存中读入页面
(a)filemap_nopage
(b)age_cache_read
(5)为 nopage() 进行预读文件
(a)nopage_sequential_readahead
(b)read_cluster_nonblocking
(6)交换相关的预读
(a)swapin_readahead
(b)valid_swaphandles
符号
⇐ ⇒ ⇔ ⇆ ⇒ ⟺
①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿
⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑿⒀⒁⒂⒃⒄⒅⒆⒇
➊➋➌➍➎➏➐➑➒➓⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴
⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵
ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ
ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ
🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩
123
y = x 2 + z 3 y = x^2 + z_3 y=x2+z3
y = x 2 + z 3 + a b + b a y = x^2 + z_3 + \frac {a}{b} + \sqrt[a]{b} y=x2+z3+ba+ab
y = x 2 + z 3 (1) y = x^2 + z^3 \tag{1} y=x2+z3(1)