Linux 进程地址空间1_数据结构和接口
来源:互联网 发布:手机一键装windows系统 编辑:程序博客网 时间:2024/05/15 23:48
数据结构
内存描述符:
mm_struct<linux/sched.h>
struct mm_struct {
struct vm_area_struct * mmap; /*内存区域链表*/
rb_root_t mm_rb; /*内存区域红黑树的根*/
struct vm_area_struct * mmap_cache; /*最后使用的内存区域*/
pgd_t * pgd; /*页全局目录*/
atomic_t mm_users; /*正在使用该地址的进程数*/
atomic_t mm_count; /*主引用计数*/
int map_count; /*内存区域数目*/
struct rw_semaphore mmap_sem; /*内存区域信号量*/
spinlock_t page_table_lock; /*页表锁*/
struct list_head mmlist; /*包含全部mm_struct的链表*/
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 rss, total_vm, locked_vm;
/*物理页,全部页面数目,上锁的页面数目*/
unsigned long def_flags; /*默认的访问标志*/
unsigned long cpu_vm_mask; /*lazy TLB交换掩码*/
unsigned long swap_address; /*最后被扫描的地址*/
unsigned dumpable:1; /*是否可以产生内存信息转储*/
/* Architecture-specific MM context */
mm_context_t context; /*体系结构特殊数据*/
};
对数据的一些解释:
mm_users记录的是那些需要访问该内存空间的进程数。 mm_count 记录的是那些和该内存空间相关的匿名进程数。匿名进程是指:该进程只是借用该mm_struct,但不会访问该内存空间的进程,mm_count被第一个访问它的进程初始化为1.
mmap和mm_rb这两个不同数据结构体描述的对象是相同的。
在进程的进程描述符中,mm域存放着该进程使用的内存描述符,所以current->mm便指向当前进程的内存描述符。
mm_struct与内核线程:
内核线程没有进程地址空间,也没有相关的内存描述符。所以内核线程对应的进程描述符中mm域为空,即:他们没有用户上下文。当新内核线程运行时,内核线程将直接使用前一个进程的内存描述符。
内存区域
内存区域由vm_area_struct<linux/mm.h>结构体描述,内存区域在内核中经常被称作虚拟内存区域或VMA。vm_area_struct用于描述指定地址空间内连续区间上的一个独立内存范围。内核将每个内存区域作为一个单独的内存对象管理,每个内存区域都拥有一致的属性。
struct vm_area_struct {
struct mm_struct * vm_mm; /*该mm_struct所属的VMA结构*/
unsigned long vm_start; /*区间的首地址*/
unsigned long vm_end; /*区间的尾地址*/
struct vm_area_struct *vm_next; /*VMA链表*/
pgprot_t vm_page_prot; /*访问控制权限*/
unsigned long vm_flags; /*标志*/
rb_node_t vm_rb; /*??该VMA节点所属的红黑树的根*/
/*
* For areas with an address space and backing store,
* one of the address_space->i_mmap{,shared} lists,
* for shm areas, the list of attaches, otherwise unused.
*/
struct vm_area_struct *vm_next_share;
struct vm_area_struct **vm_pprev_share;
/* Function pointers to deal with this struct. */
struct vm_operations_struct * vm_ops; /*操作表*/
/* Information about our backing store: */
unsigned long vm_pgoff; /*文件中的偏离量*/
struct file * vm_file; /*被映射的文件(can be NULL). */
unsigned long vm_raend; /* XXX: put full readahead info here. */
void * vm_private_data; /* was vm_pte (shared mem) 私有数据*/
};
vm_mm域指向和VMA相关的mm_struct结构体,每个VMA对其相关的mm_struct结构体来说都是唯一的,及时两个独立的进程将同一个文件映射到各自的地址空间,他们分别会有一个vm_area_struct结构体来标志自己的内存区域(两个线程共享一个地址空间除外)。
相关接口
vm_area_struct结构体中的vm_ops域指向与该区域相关的操作函数表,内核使用表中的方法操作VMA。vm_area_struct作为通用对象代表了任何类型的内存域,而操作表描述针对特定的对象实例的特定方法。
vm_operations_struct<linux/mm.h>
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
/*指定的内存区域被加入到一个地址空间时,该函数被调用*/
void (*close)(struct vm_area_struct * area);
/*制定的内存区域从地址空间删除时,该函数被调用*/
struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
/*要访问的页面不再物理内存中时,该函数被页面错误处理程序调用*/
};
查找地址区间:
<mm/mmap.c>
struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
/*在制定的地址空间中搜索第一个vm_end大于addr的内存区域*/
<linux/mm.h>
struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,struct vm_area_struct **pprev) /*返回第一个小于addr的VMA*/
<linux/mm.h>
static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
/*返回第一个和指定地址区间相交的VMA*/
创建地址区间
内核中的两种内存映射的函数:
<linux/mm.h>
static inline unsigned long do_mmap(
struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
/*映射由file制定的文件,具体映射的是文件中从偏移offset出开始,长度为len字节的范围内的数据。成功的话,它会在虚拟内存中分配一个合适的新内存区域,如果有可能的话,将新区域和邻近区域合并,否则内核从vm_area_cachep(slab)缓存中分配一个vm_area_struct结构体,并更新红黑树和链表*/
<Sys_i386.c>
static inline long do_mmap2(
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
/*do_mmap的变种,作用也是内存空间映射,最后一个参数pgoff是页面偏移,能够偏移更大的位置*/
用户空间可以通过mmap()系统调用获取内核函数do_mmap()的功能。
删除地址空间
<linux/mm.h>
int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
/*从特定的进程地址空间中删除指定地址空间。mm指定要删除区域所在的地址空间,删除从地址start开始,长度为len字节的地址区间,返回零表示成功。*/
<linux/mm/mmap.c>
int munmap(void *start, size_t length)
/*给用户空间提供的从自身地址空间中删除指定地址去见的方法,是对do_munmap()的简单封装*/
- Linux 进程地址空间1_数据结构和接口
- 进程地址空间 - 数据结构
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- linux 内核地址空间和进程地址空间
- Linux内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- Linux内核--内核地址空间分布和进程地址空间
- linux进程和内核地址空间
- Linux进程地址空间
- linux 线程学习(二)属性设置
- PHP 正则表达式 (preg_match)
- Android 启动init.rc 中mount 分区
- 网页设计中需要注意的WEB安全色谱
- Flex编码随笔
- Linux 进程地址空间1_数据结构和接口
- cetia4 1.1文档-2.9 Separating Methods by Request Type
- .NET委托:一个C#睡前故事
- MSFlexGrid控件属性及使用方法
- 初学嵌入式-WinCE
- 1 .NET FrameWork概述
- Android Donut 系统烧写到开发板,脱离NFS启动
- 三种方法在玻璃上标记
- 连接失败:未能在sysdatabases中找到数据库所对应的条目