Chinaunix首页 | 论坛 | 博客
  • 博客访问: 294178
  • 博文数量: 56
  • 博客积分: 3025
  • 博客等级: 中校
  • 技术积分: 534
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-06 17:28
个人简介

Honesty and diligence should be your eternal mates.

文章分类

全部博文(56)

文章存档

2012年(1)

2011年(27)

2010年(20)

2008年(8)

分类: LINUX

2010-11-17 22:09:38

一、用户空间的管理:
 
        用户进程最大有3G的虚拟地址空间,其代码段、数据段以及堆栈段分配如下:
        空洞指的是进程在运行期间可以动态地调用malloc()进行动态分配的空间。堆栈位于进程空间的顶部,进程运行时自顶向下分配。
        尽管进程地址空间有3GB,但是程序运行时并不是将所有的3GB大小都映射到物理地址空间,而是向内核申请部分虚存区间和若干物理页面,并对他们建立起映射关系。

二、用户空间所用到的数据结构:

1、mm_struct结构:
用于描述整个用户进程空间,其具体定义如下(include/linux/mm_types.h):
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
struct vm_area_struct * mmap_cache; /* last find_vma result */
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
       unsigned long (*get_unmapped_exec_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
unsigned long mmap_base; /* base of mmap area */
unsigned long task_size; /* size of task vm space */
unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
int map_count; /* number of VMAs */
struct rw_semaphore mmap_sem;
spinlock_t page_table_lock; /* Protects page tables and some counters */

struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
* together off init_mm.mmlist, and are protected
* by mmlist_lock
*/

/* Special counters, in some configurations protected by the
* page_table_lock, in other configurations by being atomic.
*/
mm_counter_t _file_rss;
mm_counter_t _anon_rss;

unsigned long hiwater_rss; /* High-watermark of RSS usage */
unsigned long hiwater_vm; /* High-water virtual memory usage */

unsigned long total_vm, locked_vm, shared_vm, exec_vm;
unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;

unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */

struct linux_binfmt *binfmt;

cpumask_t cpu_vm_mask;

/* Architecture-specific MM context */
mm_context_t context;

/* Swap token stuff */
/*
* Last value of global fault stamp as seen by this process.
* In other words, this value gives an indication of how long
* it has been since this task got the token.
* Look at mm/thrash.c
*/
unsigned int faultstamp;
unsigned int token_priority;
unsigned int last_interval;

unsigned long flags; /* Must use atomic bitops to access the bits */

struct core_state *core_state; /* coredumping support */
#ifdef CONFIG_AIO
spinlock_t ioctx_lock;
struct hlist_head ioctx_list;
#endif
#ifdef CONFIG_MM_OWNER
/*
* "owner" points to a task that is regarded as the canonical
* user/owner of this mm. All of the following must be true in
* order for it to be changed:
*
* current == mm->owner
* current->mm != mm
* new_owner->mm == mm
* new_owner->alloc_lock is held
*/
struct task_struct *owner;
#endif

#ifdef CONFIG_PROC_FS
/* store ref to file /proc//exe symlink points to */
struct file *exe_file;
unsigned long num_exe_file_vmas;
#endif
#ifdef CONFIG_MMU_NOTIFIER
struct mmu_notifier_mm *mmu_notifier_mm;
#endif
};

mmap、mm_rb都是描述内存区块的结构体,不同的是,mmap是以链表的方式,适合高效的遍历,而mm_rb是以红黑树的方式表示,便于索引指定节点。

pdg 存放的是页目录项的基地址,当调度程序调度一个进程运行时,就将这个地址转化为物理地址,并写入cr3.

mm_usrs和mm_count是两个计数器,前者表示的是使用该内存的进程的个数,而后者是引用该结构体的进程或内核线程的个数。

start_code, end_code, start_data, end_data 分别表示代码段的起至地址和数据段的起至地址。
start_brk,brk记录堆的起至位置,start_stack记录栈的起始位置。

2、vm_area_struct结构:

        linux用vm_area_struct来描述用户进程空间的各个区域。也定义在include/linux/mm_types.h中:

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, *vm_prev;

pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, see mm.h. */

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;
};
    
        vm_mm指向的是自己所属的用户进程空间,vm_start和vm_end表示区域的起止区间。vm_next和vm_prev将区域连成一个链表,首个表项地址存放于mm_struct的mmap中。

三、进程用户空间的创建:

        当创建一个进程时,它复制或共享父进程的用户空间。内核调用copy_mm()函数,写时复制。内核线程空间的创建是通过调用clone()函数,和父进程共享用户空间。

四、虚存映射:

        Linux并不是将可执行文件装入物理内存,而是将其链接到用户进程空间。只有在程序运行期间被使用到程序部分才会被装入物理内存。虚存映射分为共享、私有以及匿名映射。




阅读(867) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~