当前位置:文档之家› Linux源代码分析_存储管理

Linux源代码分析_存储管理

/ / 指向 v ma 段 AVL 树的指针 struct semaphor mmap_sem;
struct vm_area_struct* vm_pr ev_share; struct vm_operation_struct* vm_ops;
/ / vm_o ps 规定 了可 对 V M A 段实 施的操作。
unsigned long vm_offset ; / / VM A 段相对于文件或共享内存 的偏移量。
/ / 进程未初 始化 的数 据段 的起 始地 址 和结束地址
unsig ned lo ng star t_stack, start_mmap; unsig ned lo ng arg_start, arg_end;
/ / 调用参数区的起始地址和 结束地址 unsig ned lo ng env_start, env_end;
/ / 进程环境区的起始地址和 结束地址 unsig ned lo ng rss, total_vm, locked_v m;
/ / rss 是进程内容驻留 在物理 内存的 页 面总数
unsig ned lo ng def_flags; struct v m_ar ea_struct* mmap;
/ / 指向 v ma 段的双向链表的指针 struct v m_ar ea_struct* mmap_av l;
L inux 操作系统 是一种能运行于多种平台、源 代码公开、免费、功能强大、与 Unix 兼容的操 作系 统。自其诞生以来, 发展非常迅速, 在我国也受到政 府、企业、科研单位、大专院校的重视。我们自 2000 年开始对 L inux 源代码( 版本号是 Linux 2 2 16) 进 行分析, 首先剖析了进程管理和存储管理部分, 本文 是有关存储管理的一部分。主要介绍了 Linux 虚存 管理所用到的数据结构及其相互间的关系, 据此可 以更好地理解其存储管理机制, 也可以在此基础上 对其进行改进或在此后的研究中提供借鉴作用。作 为一种功能强大的操作系统, Linux 实现了 以虚拟 内存为主的内存管理机制。即能够克服物理内存的 局限, 使用户进程在透明方式下, 拥有比实际物理内 存大得多的内存。本文主要阐述了 L inux 虚存管理 的基本特点和主要实现技术, 并分析了 L inux 虚存 管理的主要数据结构及其相互关系。
第3期
王艳春: L inux 源代码分析 存储管理
31
程中实现的。进程执行时每用到一个地址, 地址转 换机构都要把虚拟地址转化为内存的实际地址。动
态地址映射使 L inux 可以实现进程在主存中的动态 重定位。虚存段的动态扩展和移动, 也为虚存的实 现提供了基础。
2 Linux 虚存管理数据结构
1) mem_m ap Linux 系统中的物 理内存由 mem_map 表描 述
mm h) , 每一个 mem_map_t 描 述系统的一个 关于
内核态、用户态代码和数据的物理页面, 其定义如 下:
typedef struct pag e {
/ / 在 include/ linux / mm h 中:
struct page* nex t, * prev; / / 由于搜索算法 的约定, 这 两项 必须首先定义
struct inode* v m_inode; / / 指向 VM A 所在文件的 inode 结 构。 若 不 涉 及 文 件, 则 为 N U LL 。
unsigned long vm_pte; / / 用于 共享内 存, 含 SHM_SWP_ T Y PE 和共享内存段 id 号
};
图 4 虚拟内存数据结构示意图
1 Linux 虚存管理概述
Linux 的内存管理采用虚拟页式管理, 使用多 级页表, 动态地址变换。进程在运行过程中可以动 态浮动和扩展, 为用户提供了透明的、灵活有效的 内存使用方式。
1) 32 bit 虚拟地址 在 L inux 中, 进程的 4GB 虚存需通过 32 bit 地 址进行寻址。L inux 中虚拟地址与线性地址为同一 概念, 虚拟地址被分成 3 个子位段, 而大小为 4k, 如图 1 所示。 2) L inux 的多级页表结构
/ / 页帧描述表的首地 址
2) free_area
L inux 采用位示图 ( bitm ap 表) 的方式记录所 有物 理 内 存 的 使 用 状 况。 与 mem_map 一 样,
bit map 表在系统初始化时由 f ree_area_init ( ) 函数
创建 ( 见 mm/ page_alloc. c) 。空闲 的物理页 帧用
4) mm_st ruct 进程的虚拟这间由 mm_st ruct 描述, 该数据结 构包含当前执行程序的映象信息 ( 用户进程中与存 储有关的信息) , 以及一些指向 vm_area_st ruct 结构 的指针, 参见图 5。
图 5 用户进程虚存管理数据结构 struct mm_struct { int count; pg d_t* pgd;
struct inode* ino de;
/ / 若该页帧的内 容是文件, 则 inode 和
unsigned long offset;
struct page* next_hash;
/ / offset 指出文件的 inode 和 偏移 位置
/ / pag e cache 的 hash 表中,
链表 的后继指针
指示地址
Hale Waihona Puke unsig ned lo ng swap_unloch_entry;
unsig ned olng map_nr;
/ / 页 帧 在 mem_map 表 中
的下 标, page map_nr
= = page_mem_map
} mem_map_t;
mem_map_t * mem_map= N U LL ;
/ / 此结构的 nex t、prev 指 针与 struct page 匹配
struct page* prev; unsig ned int * map;
/ / 指向 bitmap } static struct free_ar ea_struct free_area [ N R_M EM_ L IST S] ;
/ / 页帧 的年龄, 越 小越 先换
出 struct wait_queue* wait ;
/ / 等待队列指针 struct page* prev_hash;
/ / page_cach 的 hsh 表 中, 链 表的前向指针
struct buffer_head* buffers;
/ / 若该页帧作为 缓冲区, 则
3) 页表项的格式
图 2 Linux 中页目录项和页表项格式
4) 动态地址映射 L inux 虚存采用动态地址映射方式, 即进程的 地址空间和存储空间的对应关系是在程序的执行过
收稿日期: 2003- 05- 10 作者简介: 王艳春, 女 ( 1964 ) , 副教授, 主要从事操作系统、中文信息处理等方面的研究工作。
Linux 源代码分析 存储管理
王艳春 陈 毓 葛明霞
( 长春理工大学 计算机科学技术学院, 吉林 长春 130022)
摘 要: 本文剖析了 L inux 操作系统的存储管理机制。给出了 L inux 存储管理的特点、虚存的实 现方法, 以及主要数据结构之间的关系。 关键词: L inux 操作系统; 存储管理; 虚拟存储 中图分类号: T P316 81 文献标识码: A
f ree_area 数组记录。该数组由 NR- M EM - LIST S 个 f ree_area_st ruct 结构类型的数组元素构成 ( 见图
3) 。每个元素作为一条空闲链表的表头。
图 3 bitmap 表及其与 free_area 的关系 stuct free_ar ea_struct { struct page* next;
struct vm_area_struct* vm_avl_right ; struct vm_area_struct* vm_nex t;
/ / 链接 每个任 务的 V M A 区, 按 地址分类
struct vm_aea_str uct* vm_nex t_shar ; / / VM A 为共 享区 时所使 用的 前、 后向指针。
/ / 进程页目录的起始地址 unsig ned lo ng star t_code. end_code;
/ / 进程代码段的起始地址和 结束地址 unsig ned lo ng star t_data, end_data;
/ / 进程数据段的起始地址和 结束地址 unsig ned lo ng star t_brk, brk;
struct mm_str uct* vm_mm; / / V M A area parameters
32
长春理工大学学报
2003 年
unsigned long vm_start; / / V M A 描 述的 虚 存 段始 于 vm_ start, 终于 vm_end
unsigned long vm_end; pgprot_t vm_page_rot;
( 见 mm \ memory c) , 是一个 mem_mp_t 类型的队
列, 该队列在系统初始化时由核心 f ree_area_init ( )
创建和初始 化 ( 见 mm \ page_alloc c) , 它本身 是 关于 st ruct page mem_map_t 的 数 组 ( 见 linux \
图 1 32 位虚拟地址
标准的 L inux 的虚存页表为三级页表, 依次为页目 录( Pag e Direct ory PGD) 、中间页目录( Pag e Middle Direct ory P MD ) 、页 表 ( Page T able PT E ) 。 在 i386 机器 上 Linux 的 页表结构实 际为两级, PGD 和 PMD 页表是合二为一的。所有有关 PMD 的操作关际上 是对 PGD 的操作。所以源代码中形如* _pgd_* ( ) 和* _ pmd_* ( ) 函数实现的功能也是一样的。
相关主题