linux内存管理

来源:互联网 发布:中国男乒全军覆没 知乎 编辑:程序博客网 时间:2024/06/04 00:49

存储管理是操作系统的重要组成部分。linux操作系统采用了请求式分页虚拟存储管理办法。系统为每个进程提供4GB的虚拟存储空间。不同进程的虚拟内存是独立的。

1.1进程虚拟空间的管理

在X86架构下,进程的虚拟内存为4GB。进程虚拟空的划分在系统初始化的时候由GDT(global data table全局描述符表)确定,在内核代码的/arch/i386/kernel/head.S(内核版本1.2.13)或者/arch/X86/kernel/head_64.h(内核版本2.6.25.8)

/* * This gdt setup gives the kernel a 1GB address space at virtual * address 0xC0000000 - space enough for expansion, I hope. */.align 4_gdt:.quad 0x0000000000000000/* NULL descriptor */NULL描述符.quad 0x0000000000000000/* not used */未使用.quad 0xc0c39a000000ffff/* 0x10 kernel 1GB code at 0xC0000000 */内核代码段.quad 0xc0c392000000ffff/* 0x18 kernel 1GB data at 0xC0000000 */内核数据段.quad 0x00cbfa000000ffff/* 0x23 user   3GB code at 0x00000000 */用户代码段.quad 0x00cbf2000000ffff/* 0x2b user   3GB data at 0x00000000 */用户数据段.quad 0x0000000000000000/* not used */.quad 0x0000000000000000/* not used */.fill 2*NR_TASKS,8,0/* space for LDT's and TSS's etc */各个进程LDT描述符和TSS描述符的空间
内核2.6.25.8中的描述
/* The TLS descriptors are currently at a different place compared to i386.   Hopefully nobody expects them at a fixed place (Wine?) */ENTRY(cpu_gdt_table).quad0x0000000000000000/* NULL descriptor */.quad0x00cf9b000000ffff/* __KERNEL32_CS */.quad0x00af9b000000ffff/* __KERNEL_CS */.quad0x00cf93000000ffff/* __KERNEL_DS */.quad0x00cffb000000ffff/* __USER32_CS */.quad0x00cff3000000ffff/* __USER_DS, __USER32_DS  */.quad0x00affb000000ffff/* __USER_CS */.quad0x0/* unused */.quad0,0/* TSS */.quad0,0/* LDT */.quad   0,0,0/* three TLS descriptors */ .quad0x0000f40000000000/* node/CPU stored in limit */


linux的存储管理主要是管理进程的虚拟内存的用户区(代码段、数据段、堆栈,以及进程运行的环境变量、参数传递区域等)。每个进程都用一个mm_struct 结构体来定义它的虚拟用户区。mm_struct  结构体首地址在任务结构体task_struct  的成员项mm 中。

1.1.1 进程的虚拟内存区域

虚存区域是虚存空间中一个连续的区域,在这个区域中的信息具有相同的操作和访问特性。每个虚拟区域用一个vm_area_struct  结构体描述,定义在/include/linux/mm_types.h  中,代码:

/* * This struct defines a memory VMM memory area. There is one of these * per VM-area/task.  A VM area is any part of the process virtual memory * space that has a special rule for the page-fault handlers (ie a shared * library, the executable area etc). */struct vm_area_struct {struct mm_struct * vm_mm;/* The address space we belong to. */unsigned long vm_start;/* Our start address within vm_mm. */unsigned long vm_end;/* The first byte after our end address   within vm_mm. *//* linked list of VM areas per task, sorted by address */struct vm_area_struct *vm_next;pgprot_t vm_page_prot;/* Access permissions of this VMA. */unsigned long vm_flags;/* Flags, listed below. */struct rb_node vm_rb;/* * For areas with an address space and backing store, * linkage into the address_space->i_mmap prio tree, or * linkage to the list of like vmas hanging off its node, or * linkage of vma in the address_space->i_mmap_nonlinear list. */union {struct {struct list_head list;void *parent;/* aligns with prio_tree_node parent */struct vm_area_struct *head;} vm_set;struct raw_prio_tree_node prio_tree_node;} shared;

/* * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma * list, after a COW of one of the file pages.A MAP_SHARED vma * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack * or brk vma (with NULL file) can only be in an anon_vma list. */struct list_head anon_vma_node;/* Serialized by anon_vma->lock */struct anon_vma *anon_vma;/* Serialized by page_table_lock *//* Function pointers to deal with this struct. */struct vm_operations_struct * vm_ops;/* Information about our backing store: */unsigned long vm_pgoff;/* Offset (within vm_file) in PAGE_SIZE   units, *not* PAGE_CACHE_SIZE */struct file * vm_file;/* File we map to (can be NULL). */void * vm_private_data;/* was vm_pte (shared mem) */unsigned long vm_truncate_count;/* truncate_count or restart_addr */#ifndef CONFIG_MMUatomic_t vm_usage;/* refcount (VMAs shared if !MMU) */#endif#ifdef CONFIG_NUMAstruct mempolicy *vm_policy;/* NUMA policy for the VMA */#endif};

为了看起来方便建其中注释抹掉之后:

struct vm_area_struct {struct mm_struct * vm_mm;/* The address space we belong to. */vm_mm指针指向进程的mm_struct结构体unsigned long vm_start;/* Our start address within vm_mm. */虚存区域的开始地址unsigned long vm_end;/* The first byte after our end address   within vm_mm. */虚存区域的终止地址
/* linked list of VM areas per task, sorted by address */  vm_area_struct结构体连接成一个单向链表,vm_next指向下一个vm_area_struct结构体
struct vm_area_struct *vm_next;pgprot_t vm_page_prot; /* Access permissions of this VMA. */ 虚存区域的页面保护特性unsigned long vm_flags; /* Flags, listed below. */描述了虚存区域的操作特性,在mm.h 文件中定义struct rb_node vm_rb;

union {struct {struct list_head list;void *parent;/* aligns with prio_tree_node parent */struct vm_area_struct *head;} vm_set;struct raw_prio_tree_node prio_tree_node;} shared;struct list_head anon_vma_node;/* Serialized by anon_vma->lock */struct anon_vma *anon_vma;/* Serialized by page_table_lock *//* Function pointers to deal with this struct. */vm_operations_struct该结构提包含指向各种操作的函数的指针struct vm_operations_struct * vm_ops;/* Information about our backing store: */unsigned long vm_pgoff;/* Offset (within vm_file) in PAGE_SIZE   units, *not* PAGE_CACHE_SIZE */struct file * vm_file;/* File we map to (can be NULL). */void * vm_private_data;/* was vm_pte (shared mem) */unsigned long vm_truncate_count;/* truncate_count or restart_addr */#ifndef CONFIG_MMUatomic_t vm_usage;/* refcount (VMAs shared if !MMU) */#endif#ifdef CONFIG_NUMAstruct mempolicy *vm_policy;/* NUMA policy for the VMA */#endif};


其中各个域的说明:参见mm.h

以上相关代码可以使用source insight 方便的查看;


0 0