您好,欢迎访问三七文档
Linux2.6内存管理地址类型(1)用户虚拟地址用户空间的程序使用的地址根据硬件体系结构,可以是32位或64位每个进程拥有自己独立的虚拟地址空间地址类型(2)物理地址物理内存地址处理器和系统内存之间使用根据硬件体系结构,可以是32位或64位总线地址总线寄存器地址外设总线和内存之间使用地址类型(3)内核逻辑地址常规的内核地址空间映射了大部分主存,可以当作物理内存使用内核逻辑地址与相应的物理地址相差一个常数偏移量逻辑地址使用硬件特有的指针大小,在配置大量内存的32位系统上可能无法直接访问所有的物理内存可将内核逻辑地址与物理地址相互转换,定义在asm/page.h中地址类型(4)内核虚拟地址由函数vmalloc和kmap返回的地址不能直接对应物理内存需要内存分配和地址转换才能与逻辑地址联系起来通常保存在指针变量中地址类型(5)低端内存与高端内存均指物理内存低端内存代表存在于内核空间的与逻辑地址相应的物理内存高端内存是那些不存在逻辑地址的内存,通常保留给用户空间的进程使用在i386体系结构下,低端和高端之间的界限通常为1GB用户进程可访问4GB虚拟线性空间,0到3GB为用户空间,3GB到4GB为内核空间所有进程内核空间均相同,具有相同页目录和页表内核虚拟空间3GB到3GB+8MB映射到物理内存0到8MB,对应内核启动和设备内存映射等内存保护(1)不同任务之间的保护MMU实现任务虚拟地址空间的隔离每个任务拥有不同的虚拟地址到物理地址的映射操作系统的保护通过任务共享地址空间实现地址空间分为全局地址空间和局部地址空间内存保护(2)同一任务的保护定义4种特权级别,限制内存访问0级是操作系统内核,处理IO,内存管理及其他关键操作1级系统调用处理程序2级库过程3级用户程序Linux只用0级和3级,1级和2级归到0级中80386段页式管理机制Linux内存管理的硬件基础Linux内存管理的概念基础通过386的硬件机制,区分内存管理中硬件与软件的分工存储器地址(1)存储器地址逻辑地址(logicaladdress)机器语言指令中用来指定一个操作数或一条指令的地址,通常我们写程序中引用的符号地址是逻辑地址线性地址(linearaddress/virtualaddress)标识0-4GB范围的地址物理地址(physicaladdress)送到地址线上的地址,用于对物理存储单元寻址存储器地址(2)三种地址之间的关系通过硬件的分段和分页进行转换逻辑地址->线性地址->物理地址硬件分段(1)为支持保护模式,段改由段描述符来描述段基址段限长类型访问该段所需的昀小特权级…段描述符存放在GDT或LDT中(全局/局部描述符表)中GDT/LDG的基址存放在寄存器GDTR/LDTR中硬件分段(2)段寄存器CS:代码段寄存器DS:数据段寄存器SS:堆栈段寄存器ES、FS、GS…每个段寄存器存放段选择符GDT/LDT的索引TI位:指定描述符是GDT还是LDTRPL:CPU的当前特权级硬件分段(3)逻辑地址到线性地址的转换硬件分页(4)页vs.页框页:数据块,可以在主存也可以在磁盘页框:固定长度的RAM块分页IntelCPU处理4KB的页(why4KB?)通过设置CR3的PG位开启分页数据结构页目录当前使用的页目录的物理地址在CR3中页表硬件分页(5)硬件的分页过程发生在物理地址送地址线之前MMU中进行硬件分页(6)TLB(TranslationLookasideBuffer)硬件,用来加速页表查找关键的一点:如果操作系统更改了页表内容,它必须相应的刷新TLB以使CPU不误用过时的表项CR3发生改变时,硬件自动更新TLB中所有的表项硬件保护机制段描述符type标志:读/写/执行页表项User/Supervisor标志Read/Write标志硬件产生pagefault扩展分页(1)允许页框为4MB扩展分页——物理地址扩展分页(PAE)内核不能直接对1G以上的RAM进行寻址市场需求刺激下,Intel进行了修补:在PentiumePro体系结构,地址线36位,但仍必须把32位线性地址转换为36位办法:页表项长度改为64位(因为32位已不够用),再增加一级页表,该页表4个表项,基址存在CR3中Linux中的分段(1)内核代码段__KERNEL_CS:范围0-4G;可读、执行;DPL=0内核数据段__KERNEL_DS:范围0-4G;可读、写;DPL=0用户代码段__USER_CS:范围0-4G;可读、执行;DPL=3内核代码段__USER_DS:范围0-4G;可读、写;DPL=3Linux中的分段(2)TSS(任务状态段):存储进程的硬件上下文,进程切换时使用,每个CPU有一个default_ldt:理论上每个进程都可以同时使用很多段,这些段可以存储在自己的ldt段中,但实际linux极少利用x86的这些功能,多数情况下所有进程共享这个段,它只包含一个空描述符Linux中的分段(3)由于历史原因,IA32体系结构仍然强制使用硬件分段段式映射基地址总是0,逻辑地址与虚拟地址总是一致的Linux中的分页(1)与体系结构无关的三级页表模型pgd,页目录pmd,页中级目录pte,页表项为什么使用三级页表设计目标决定:可移植性硬件特性决定:PAELinux中的分页(2)Linux中的分页(3)进程页表各进程拥有自己的3G用户空间内核占用昀高的1G作为系统空间,系统空间由所有进程共享Linux中的分页(4)1G的内核空间内核空间==物理内存空间1G的后128MB用作实现非连续内存分配和固定映射的线性地址IA-64Linux地址空间划分64位虚地址空间划分为8个相等的区,高3位表示区号0-4区作为用户空间,5-7区作为核心空间内核空间可进一步划分为页表映射段和对等映射段页表映射段用于实现内核的vmalloc区域,实现虚地址连续的大内存块分配对等映射段包含Linux内核,该段虚拟地址可与物理地址直接映射,虚地址减去一个基地址得到物理地址虚拟地址格式采用三级页表结构,每个页框8KB,每级目录占用一个页框,每项8字节大小,由全局目录(PGD)、中间目录(PMD)、页表项(PTE)组成全局目录索引被分为pgdh和pgdl,ar.k7寄存器指向当前进程的页表树基地址IA-64中使用0-4区作为用户空间,5-7区作为核心空间区号使用页大小范围映射方式7Cache256MB全局对等6Cache256MB全局对等5Vmalloc,,guard,gate8KB全局页表4堆栈8KB进程页表3数据段8KB进程页表2正文段8KB进程页表1共享内存8KB进程页表0IA-32模拟8KB进程页表内存管理场景shell参与,利用fork或exec以及mmap系统调用构造进程页表创建进程mm_struct,mmap构造进程页表运行过程中发生缺页,通过内核请求页面调用C库函数malloc申请堆空间内存不够,将页面换入换出进程的内存组织内存管理数据结构每个进程有一个mm_struct结构,描述进程的虚拟内存vm_area_struct结构描述进程的虚拟内存地址区域对页错误处理有同一规则的进程虚拟内存空间部分,如共享库、堆栈page结构描述一个物理页,系统保证跟踪到每一个物理页数据结构-mm_structstructmm_struct{structvm_area_struct*mmap;structvm_area_struct*mmap_avl;structvm_area_struct*mmap_cache;pgd_t*pgd;atomic_tcount;intmap_count;structsemaphoremmap_sem;unsignedlongcontext;unsignedlongstart_code,end_code,start_data,end_data;unsignedlongstart_brk,brk,start_stack;unsignedlongarg_start,arg_end,env_start,env_end;unsignedlongrss,total_vm,locked_vm;unsignedlongdef_flags;unsignedlongcpu_vm_mask;unsignedlongswap_cnt;unsignedlongswap_address;void*segments;};VMA链,VMAAVL树,和最近使用的VMACache指向PGD的指针代码,数据,堆栈段的地址范围Mm_struct标识了一个进程定义在文件/linux/include/linux/sched.h数据结构-vm_area_structstructvm_area_struct{structmm_struct*vm_mm;unsignedlongvm_start;unsignedlongvm_end;structvm_area_struct*vm_next;pgprot_tvm_page_prot;unsignedshortvm_flags;shortvm_avl_height;structvm_area_struct*vm_avl_left;structvm_area_struct*vm_avl_right;structvm_area_struct*vm_next_share;structvm_area_struct**vm_pprev_share;structvm_operations_struct*vm_ops;unsignedlongvm_offset;structfile*vm_file;unsignedlongvm_pte;};VMA的地址范围VMA链VMAAVL树VMA保护位和标志共享VMA链VMA操作函数表对应file及其偏移Vm_area_struct管理着进程的虚拟空间的一个区域定义在文件/linux/include/linux/sched.h数据结构-Pagetypedefstructpage{structpage*next;structpage*prev;structinode*inode;unsignedlongoffset;structpage*next_hash;atomic_tcount;unsignedlongflags;structwait_queue*wait;structpage**pprev_hash;structbuffer_head*buffers;}mem_map_t;空闲页面链orinode页面链表对应的inode及其偏移buffercache头结构贮留在内存中页面的HASH链表Page(mem_map_t)代表了物理上的一个页定义在文件/linux/include/mm.h查看进程内存布局进程内存布局实例[root@serv3~]#cat/proc/1/maps起始结束权限偏移主从设备号inode号文件映像001be000-001bf000r-xp001be00000:000[vdso]001e7000-00201000r-xp0000000003:014471690/lib/ld-2.3.6.so00201000-00202000r-xp0001900003:014471690/lib/ld-2.3.6.so00202000-00203000rwxp0001a00003:014471690/lib/ld-2.3.6.so00205000-00328000r-xp0000000003:014471692/lib/libc-2.3.6.so00328000-0032a000r-xp0012200003:014471692/lib/libc-2.3.6.so0032a000-0
本文标题:Linux内存管理
链接地址:https://www.777doc.com/doc-4580886 .html