本文共 1689 字,大约阅读时间需要 5 分钟。
linux 内存 从 内存类型角度分为 A. 虚拟内存 B. 物理内存linux 内存 从 管理角度分为 A. 用户内存 B. 内核内存从而 正交 形成了 4种 1. 内核物理内存 由 struct page 管理, 不同的 内存模型 有不同的管理方式 // CONFIG_FLATMEM CONFIG_DISCONTIGMEM CONFIG_SPARSEMEM_VMEMMAP CONFIG_SPARSEMEM 2. 内核虚拟内存 由 四种方式() 管理 // 直接(线性)映射 vmalloc动态映射 持久映射kmap 固定映射fixmap之kmap_atomic(临时映射) 3. 用户物理内存 由 struct page 管理, 不同的 内存模型 有不同的管理方式 // CONFIG_FLATMEM CONFIG_DISCONTIGMEM CONFIG_SPARSEMEM_VMEMMAP CONFIG_SPARSEMEM 4. 用户虚拟内存 由 task_struct 中的 mm_struct 中的 vmap_area(VMA) 管理---------------------------------------------------------------------------------------------------总结上面的 , 即以下内核物理内存管理方式 有4种 : 根据配置选一种 CONFIG_FLATMEM CONFIG_DISCONTIGMEM CONFIG_SPARSEMEM_VMEMMAP CONFIG_SPARSEMEM内核虚拟内存管理方式 有5种 : 4种用于异常/内核线程/用户进程内核态,1种用于进程用户态内存 直接(线性)映射 vmalloc动态映射 持久映射kmap 固定映射fixmap之kmap_atomic(临时映射) VMA // VMA管理的地址范围在 0x00000000 - 0xbfffffff // 其他四种管理方式瓜分了 0xc00000000 - 0xffffffff // buddy 和 slab 申请的虚拟地址空间都是 在直接映射区,申请的物理地址都是连续的
异常 用的 物理虚拟内存 是怎么管理的 ??? .code .rodata .data .bss .stack .heap .code .rodata .data .bss 都是 内核的,与内核线程共享 .stack 有可能是 内核栈(中断栈与内核栈共用,叫做共享中断栈,每个进程一个),有可能是独立的中断栈 .heap 还是封装的 1 2 但是注意,不能做 中断中不能做的动作(睡眠) 中断 的栈 如果采用 内核栈(sp对齐8KB,获得的是同一个值) , 应该是可以睡眠的, 因为可以用 current(就是根据sp对齐8KB获得的 ) 获取到 当前的 stack_struct , 所以就可以调用schedule
用户空间的内存 是 内核 管理的glibc提供了malloc 和 mmap 函数,封装了 brk mmap 系统调用应用程序的加载和运行 都是用的 brk mmap 系统调用 , 封装了 上面说的 3 4 // 其实 3 是在 缺页异常 中处理的内核常用的 内存申请api 是 alloc_pages函数(buddy) vmalloc函数() , 都是封装的 1 2 kmalloc函数(slab) 是 基于 1 之上,又实现了一套 物理内存的管理,虚拟内存的管理还是封装了 2
内核物理内存管理方式 有4种 根据配置选一种内核虚拟内存管理方式 有5种 4种用于异常/内核线程/用户进程内核态,1种用于进程用户态内存以上的管理方式,不是完美的,会造成很多问题:问题 : 内存碎片/内存不足/无法申请到连续的物理页方案 : 内存规整/内存释放/CMA
转载地址:http://ijigi.baihongyu.com/