Linux内存管理概述


(该图转自http://bbs.chinaunix.net/thread-2018659-2-1.html,作者Aryang)

下面对各部分进行概述。

Linux进程的线性地址空间(进程虚拟地址空间分布),0~3G是User地址空间,3~4G是Kernel地址空间。(适用于ARM、X86等,mips按0~2G,2~3G划分)

关于线性地址布局,此图未说明部分:

1.紧接着内核数据区向上是mem_map全局page数组。

2. kernel启动地址并非是0xC0000000,而是PAGE_OFFSET+TEXT_OFFSET(0x8000),而在这32k大小的空间存放着内核一级页表数组swapper_pg_dir(每一项一级页表4个字节,映射1M内存,4G空间共4K项一级页表,占用16k内存),页表在启动阶段setup_arch->paging_init中调用prepare_page_table()和map_lowmem()进行初始化和映射,将在另一篇详细叙述。

3.内核动态加载驱动模块so将被load到紧接着MODULES_VADDR~0xC0000000的16M空间。


小于896M的物理内存直接映射到内核3G~3G+896M线性地址空间内,VA=PA-PHYS_OFFSET+PAGE_OFFSET

大约896M的物理内存通过建立各级页表的方式映射到高端映射区。

每个task在起task_struct内都有一个指针mm指向mm_struct,其控制着该task的所有内存信息,其成员mmap指向vma区链表,pgd指向页全局目录位置。

切换任务时要为下一个task装载其pgd到C2(X86为cr3)。

在cpu寻址时,mmu将虚拟地址按照2级映射方式,映射到对应物理叶匡的地址偏移上去。

而在内存管理上,系统启动阶段使用的是Bootmem,它是以简单的bitmap方式(0:未使用,1:已用)。

系统启动后buddy接手内存管理(以页为单位),分为两种情况,per_cpu_pageset和free_area,前者用来分配单个页(在Linux物理内存描述三个层级中有详细描述),后者用来分配多页的情况,11个链表管理页块的大小从2^1~2^11,每个链表中又分为不同迁移类型的子链表。

#define MIGRATE_UNMOVABLE     0
#define MIGRATE_RECLAIMABLE   1
#define MIGRATE_MOVABLE       2
#define MIGRATE_PCPTYPES      3 /* the number of types on the pcp lists */
#define MIGRATE_RESERVE       3
#define MIGRATE_ISOLATE       4 /* can't allocate from here */

MIGRATE_TYPES是为了有效解决内存碎片问题而引入的,将可移动(用户空间申请的内存可以重新映射)、不可移动(内核空间通常申请的)、可回收(文件映射)等组织在不同的链表中,申请内存时按照不同情况在各自类型的链表中释放,如果所在类型内存不足,会fallback到其他类型链表继续分配。在系统初始化完成时全部内存划分给MOVABLE类型链表,当有其他类型需求时再从MOVABLE中释放生成。

slab分配器是面向对象的分配机制,其建立在buddy基础之上,细节待另一篇详述。


框架

(该图转自bullbat的博客,强烈推荐该博客http://blog.csdn.net/bullbat/article/details/7166140)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值