Linux memory management ■i386保护模式的分段与分页 Linux分页 ■线性地址空间分布 ■用户地址空间 ■内核地址空间 ■空闲物理内存管理 ■内核物理内存分配接口 共享存储
Linux memory management ◼ i386保护模式的分段与分页 ◼ Linux分页 ◼ 线性地址空间分布 ◼ 用户地址空间 ◼ 内核地址空间 ◼ 空闲物理内存管理 ◼ 内核物理内存分配接口 ◼ 共享存储
Intel x86保护模式的地址映射 逻辑地址 段选择子16bits 段内偏移32bits GDT、LDT 线性地址 页目录索引10bits页表索引10bits页内偏移12bits pgd、pte 物理地址 物理地址32bits
Intel x86保护模式的地址映射 段选择子16bits 段内偏移32bits 页内偏移12bits 物理地址32bits 页目录索引10bits 页表索引10bits 逻辑地址 线性地址 物理地址 GDT、LDT pgd、pte
Intel x86的分段 段选择子 描述符索引13 bits GDt/ LDT 1bit访间特权级2bits 段描述符8 bytes 段基地址32bts段界限20bits 段内偏移32bits GDT 线性地址32bits
…… Intel x86的分段 描述符索引13bits GDT/LDT 1bit 段选择子 访问特权级 2bits 段内偏移32bits 段基地址32bits 段描述符8bytes + 线性地址32bits 段界限20bits GDT
Linux在i386上的分页 线性地址 页目录索引10bits页表索引10bis页内偏移12bits 页帧首地址 pg d 20bits>PMD SHIFT)& (PTRS PER PMD-1)
…… …… Linux在i386上的分页 线性地址 物理地址32bits pmd_t * dir + 页帧首地址 20bits >PMD_SHIFT) & (PTRS_PER_PMD-1)) pgd pte
页目录表项和页表项 用户态/核心 已写标表示是否启 态访问位 志位 用高速缓存 存在位 页面表或页框的物 OS专用 理地址 PSE D PCDJPWT U/S 有录表项和剪表项的格 页大小,4K(0)或 读写位 4M(1),只适用于页访问位表示是否采 目录表项 用写透方式
存在位 读写位 用户态/核心 态访问位 表示是否采 用写透方式 表示是否启 用高速缓存 访问位 已写标 志位 页大小,4K(0)或 4M(1),只适用于页 目录表项 页目录表项和页表项
Linux的线性地址空间分配 4G线性地址空间分为用户空间和内核空间,内 核空间又分为物理内存区、虚拟内存分配区 高端页面映射区、专用页面映射区和系统保留 映射区 ■线性地址从0X00000000到 OXBFFFFFFF的3G 为用户和内核共同访问,0XC0000000以上的 1G由内核独享,用户态无法访问 ■因此所有进程的页目录的后四分之一均指向内 核页目录的相应目录项。为减小同步的开销, 内核只在处理 page faul时同步用户进程的页 目录项,因此页目录项不一致的情况是有的
Linux的线性地址空间分配 ◼ 4G线性地址空间分为用户空间和内核空间,内 核空间又分为物理内存区、虚拟内存分配区、 高端页面映射区、专用页面映射区和系统保留 映射区 ◼ 线性地址从0x00000000到0xBFFFFFFF的3G 为用户和内核共同访问,0xC0000000以上的 1G由内核独享,用户态无法访问 ◼ 因此所有进程的页目录的后四分之一均指向内 核页目录的相应目录项。为减小同步的开销, 内核只在处理page_fault时同步用户进程的页 目录项,因此页目录项不一致的情况是有的
Linux的线性地址空间分配 虚拟内核态空间lGB) 虚拟用户态空间 进程1的进程2的 进程n的 用户态空用户态空 用户态空 间(3GB)间(3GB) 间(3GB) Linux进程的虚拟空间
Linux的线性地址空间分配
Linux的线性地址空间分布 Memory layout of ELF programs Kernel Virtual Memory memory invisible to user mode code Stack Memory mapped region memory mapped region File-mapping Shared libraries The brk pointer run-time data uninitialized data Initialized data Program text
Linux的线性地址空间分布 Memory mapped region: File-mapping Shared libraries
process-specific data structures (page tables, task and mm structs) same physical memory for each proces kernel code/data/stack kernel OXcO Pesp stack demand-zero process VM Memory mapped region data for shared libraries text libc. so brk runtime heap(via malloc) demand-zero uninitialized data( bss) initialized data .data) data 匚 program text(tex text forbidden
kernel code/data/stack Memory mapped region for shared libraries runtime heap (via malloc) program text (.text) initialized data (.data) uninitialized data (.bss) stack forbidden 0 %esp process VM brk 0xc0 same physical memory for each process process-specific data structures (page tables, task and mm structs) kernel VM .data .text p demand-zero demand-zero libc.so .data .text
Linux的用户地址空间分布 例: #include intz=0;/*进程的数据段中* int maino int*a=0;/进程的用户栈中 int pid=getpid 0; if (pid= forko) i /父进程执行这里的代码* a=(int*)malc(100* sizeof(int);/父进程的堆空间, runtime data*/ z= pid printf(“zl=%dⅦn”,z); 3 else i 子进程执行的代码 a=&z; a= pid printf(“2=%dⅦn”,z); printf(all done, pid=%d\n", pid); return 1
Linux的用户地址空间分布 例: #include int z = 0; /*进程的数据段中*/ int main() { int *a = 0; /*进程的用户栈中*/ int pid = getpid(); if (pid = fork()) { /*父进程执行这里的代码*/ a = (int *) malloc(100*sizeof(int));/*父进程的堆空间,runtime data*/ z = pid; printf(“z1 = %d\n”, z); } else { /*子进程执行的代码*/ a = &z; *a = pid; printf(“z2 = %d\n”, z); } printf(“all done, pid = %d\n”, pid); return 1; }