怎么通过mm_struct获取到页框信息
时间: 2023-06-20 07:04:49 浏览: 60
在 Linux 内核中,每个进程都有一个与之相关联的 mm_struct 结构体,它描述了进程的内存管理情况。mm_struct 中有一个成员 pgd,它是一个指向一级页表的指针。通过这个指针,可以遍历整个页表,从而获取到进程使用的所有物理页框的信息。
具体地说,可以使用函数 walk_page_range() 遍历一页一页的虚拟地址,然后使用函数 page_address() 获取每一页对应的物理地址。对于每个物理地址,可以使用函数 virt_to_page() 获取对应的 struct page 结构体,从而可以获取到页框的各种信息,比如页框的状态、引用计数等。
相关问题
mm_struct头文件
mm_struct是Linux内核中用于管理进程地址空间的数据结构,它定义在<linux/mm_types.h>头文件中。
该结构体的定义包括了进程的许多重要信息,如进程的内存映射表,虚拟地址空间的大小,以及进程的用户态和内核态栈等。它还包含了指向进程地址空间的pgd指针,以及指向内存管理器的指针,用于在内存不足时分配和回收进程的物理内存。
mm_struct结构体的定义如下:
```
struct mm_struct {
struct vm_area_struct *mmap; /* 进程的内存映射表 */
struct rb_root mm_rb; /* 虚拟地址区间红黑树 */
struct vm_area_struct *mmap_cache; /* 最近使用的内存映射 */
unsigned long task_size; /* 进程虚拟地址空间的大小 */
unsigned long start_code, end_code; /* 可执行代码段的开始和结束地址 */
unsigned long start_data, end_data; /* 数据段的开始和结束地址 */
unsigned long start_brk, brk; /* 进程堆的开始和结束地址 */
unsigned long start_stack; /* 用户态栈的开始地址 */
unsigned long arg_start, arg_end; /* 进程参数的开始和结束地址 */
unsigned long env_start, env_end; /* 进程环境变量的开始和结束地址 */
unsigned long saved_auxv[AT_VECTOR_SIZE]; /* 辅助向量 */
pgd_t *pgd; /* 进程的页表指针 */
atomic_t mm_users; /* 进程共享该地址空间的用户数 */
atomic_t mm_count; /* 进程共享该地址空间的引用计数 */
int map_count; /* 进程内存映射表中的区间数 */
spinlock_t page_table_lock; /* 页表锁 */
struct rw_semaphore mmap_sem; /* 内存映射表锁 */
struct list_head mmlist; /* 进程地址空间的链表 */
unsigned long hiwater_rss; /* 进程使用的最大物理内存 */
unsigned long hiwater_vm; /* 进程使用的最大虚拟内存 */
unsigned long total_vm; /* 进程使用的总虚拟内存 */
unsigned long locked_vm; /* 进程使用的锁定虚拟内存 */
unsigned long pinned_vm; /* 进程使用的固定虚拟内存 */
unsigned long data_vm; /* 进程使用的数据段虚拟内存 */
unsigned long exec_vm; /* 进程使用的可执行代码段虚拟内存 */
unsigned long stack_vm; /* 进程使用的用户态栈虚拟内存 */
unsigned long def_flags; /* 进程缺省的内存映射标志 */
unsigned long nr_ptes; /* 进程使用的页表条目数 */
unsigned long nr_pmds; /* 进程使用的页中页条目数 */
unsigned long nr_puds; /* 进程使用的页上页条目数 */
unsigned long nr_p4ds; /* 进程使用的页上页上页条目数 */
struct task_struct *owner; /* 拥有该地址空间的进程 */
struct file *exe_file; /* 执行文件的文件指针 */
};
```
在进程创建时,Linux内核会为该进程分配一个新的mm_struct结构体,并初始化其中的各个字段。当进程调用fork()函数创建子进程时,子进程会共享父进程的mm_struct结构体,使得子进程和父进程共享同一个虚拟地址空间。在进程结束时,Linux内核会回收该进程的mm_struct结构体及其相关资源。
mm_struct 结构体展示
`mm_struct` 是 Linux 内核中的一个重要结构体,代表了进程的内存管理信息。它包含了进程的虚拟内存空间的信息,如进程的内存映射,页表等。
以下是 `mm_struct` 结构体的定义(摘自 Linux 内核源代码 v5.14.5):
```c
struct mm_struct {
struct vm_area_struct *mmap; /* 进程的内存映射 */
struct rb_root mm_rb; /* 红黑树,用于快速查找虚拟地址所在的 VMA */
struct vm_area_struct *mmap_cache; /* 最近访问的 VMA 缓存 */
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
unsigned long mmap_base; /* 进程的默认映射地址 */
unsigned long mmap_legacy_base; /* 用于兼容 32 位系统的默认映射地址 */
unsigned long task_size; /* 进程的虚拟地址空间的最大值 */
unsigned long highest_vm_end; /* 进程的虚拟地址空间中最高地址 */
pgd_t *pgd; /* 进程页全局目录 */
atomic_t mm_users; /* 引用计数,记录共享该内存管理信息的进程数 */
atomic_t mm_count; /* 记录该内存管理信息的结构体被共享的次数 */
int map_count; /* 进程的内存映射数量 */
spinlock_t page_table_lock; /* 用于保护页表的自旋锁 */
struct rw_semaphore mmap_sem; /* 用于保护进程的内存映射操作 */
struct list_head mmlist; /* 进程链表 */
unsigned long hiwater_rss; /* 进程历史上 RSS 的最高值 */
unsigned long hiwater_vm; /* 进程历史上 total_vm 的最高值 */
unsigned long total_vm; /* 进程的虚拟地址空间总大小 */
unsigned long locked_vm; /* 进程锁定的虚拟地址空间大小 */
unsigned long pinned_vm; /* 进程固定的虚拟地址空间大小 */
unsigned long data_vm; /* 进程数据段的虚拟地址空间大小 */
unsigned long stack_vm; /* 进程栈的虚拟地址空间大小 */
unsigned long def_flags; /* 进程默认的内存映射标志 */
unsigned long 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]; /* 进程的 auxv 信息 */
struct vm_unmapped_area_info *unmap_area; /* 用于管理进程的匿名映射 */
unsigned long *pmd_huge_pte; /* 用于管理大页 */
struct rw_semaphore page_table_lock;
struct file *exe_file; /* 进程的可执行文件 */
unsigned long flags; /* 进程的内存管理相关标志 */
struct mm_rss_stat rss_stat; /* 进程的 RSS 统计信息 */
struct linux_binfmt *binfmt; /* 进程的二进制格式 */
cpumask_var_t cpu_vm_mask_var; /* 表示哪些 CPU 上有进程的页表 */
/* ... */
};
```
`mm_struct` 结构体比较庞大,其中包含了很多与进程内存管理相关的信息,如内存映射、页表、锁、统计信息等。通过这些信息,内核可以对进程的内存进行管理和保护。