《Linux内核设计与实现》学习【10】—— 进程地址空间

本文详细介绍了进程地址空间的概念,包括其特点、组成元素如代码段、数据段等,以及Linux中如何通过内存描述符和内存区域来管理和操作进程的虚拟内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  进程地址空间:系统中每个用户空间进程所看到的内存。

1 地址空间

进程地址空间由进程可寻址的虚拟内存组成。特点:
  1)平坦的:地址空间范围是一个独立的连续区间
  2)寻址范围:4GB虚拟内存(32位地址空间中),可以被合法访问的地址空间称为内存区域。如果一个进程访问了不在有效范围中的内存区域,或以不正确的方式访问了有效地址,那么内核就会终止该进程,并返回“段错误”信息。
  3)内存区域可包含的对象:

  • 可执行文件代码的内存映射称为代码段。(text section)
  • 可执行文件的已初始化全局变量的内存映射,称为数据段。(data section)
  • 包含未初始化全局变量,也就是bss段的零页的内存映射。
  • 用于进程用户空间栈的零页的内存映射
  • 每一个诸如C库或动态连接程序等共享库的代码段、数据段和bss也会被载入进程的地址空间
  • 任何内存映射文件
  • 任何共享内存段
  • 任何匿名的内存映射,比如由malloc()分配的内存

2 内存描述符

内存描述符由mm_struct结构体表示,定义在文件<linux/sched.h>中。
操作

#define allocate_mm()    (kmem_cache_alloc(mm_cachep, GFP_KERNEL))
#define free_mm(mm)    (kmem_cache_free(mm_cachep, (mm)))

3 内存区域

  内存区域在linux中也被称为虚拟内存区域(VMA),由vm_area_struct描述,描述了进程地址空间上一段连续的内存范围,定义在linux/mm_types.h中。
  操作函数由vm_operations_struct结构体表示。

struct vm_operations_struct {
    void (*open)(struct vm_area_struct * area);  
    void (*close)(struct vm_area_struct * area); 
    int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf); 
    int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
    int (*access)(struct vm_area_struct *vma, unsigned long addr,
              void *buf, int len, int write);
#ifdef CONFIG_NUMA
    int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
    struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
                    unsigned long addr);
    int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
        const nodemask_t *to, unsigned long flags);
#endif
};

  实际使用中的内存区域可以使用/proc文件系统和pmap工具,查看给定进程的内存空间和其中所含的内存区域。

cat /proc/<pid>/maps
pmap <pid>

4 操作内存区域

内存区域

//在<mm/mmap.c>中
//在指定的地址空间中搜索第一个vm_end大于addr的内存区域
struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);

struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
                         struct vm_area_struct **pprev);

static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)

地址区间

//创建一个新的线性地址空间
static inline unsigned long do_mmap(struct file *file, unsigned long addr,
    unsigned long len, unsigned long prot,
    unsigned long flag, unsigned long offset)

//从特定的进程地址空间中删除指定地址区间
int do_munmap(struct mm_struct *, unsigned long, size_t);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值