一、Linux内核地址空间

一般来说Linux 内核按照 3:1 的比率来划分虚拟内存(X86等):3 GB 的虚拟内存用于用户空间,1GB 的内存用于内核空间。当然有些体系结构如MIPS使用2:2 的比率来划分虚拟内存:2 GB 的虚拟内存用于用户空间,2 GB 的内存用于内核空间,另外像ARM架构的虚拟空间是可配置(1:3、2:2、3:1)。内核线性地址空间用于为内核的运行提供最基本的支持,也是操作系统赖以存在的基础。所谓内核线性地址空间就是说内核态下虚拟地址与物理地址是线性关系,两者相差一个固定偏差,计算公式为VA(虚拟地址)=PA(物理地址)+PAGE_OFFSET。

二、什么是高端内存

以x86为例linux中内核使用3G-4G的线性地址空间,也就是说总共只有1G的地址空间可以用来映射物理地址空间。但是,如果内存大于1G的情况下内核态线性地址就不够用了。为此内核引入了一个高端内存的概念,把1G的线性地址空间划分为两部分:小于896M物理地址空间的称之为低端内存,这部分内存的物理地址和3G开始的线性地址是一一对应映射的,也就是说内核使用的线性地址空间(VA)3G--(3G+896M)和物理地址空间(PA)0-896M一一对应,PAGE_OFFSET=0xC0000000;剩下的128M的线性空间用来映射剩下的大于896M的物理地址空间,这也就是我们通常说的高端内存区,这部分空间需要MMU通过TLB表来建立动态的映射关系。

三、高端内存映射

高端内存映射有三种方式:

1、  临时映射空间

固定映射空间是内核线性空间中的一组保留虚拟页面空间,位于内核线性地址的末尾即最高地址部分。其地址编译时确定,用于特定用途(如VSYSCALL系统调用,MIPS的cache着色)。由枚举类型  fixed_addresses决定,内核在FIXADDR_START 到 FIXADDR_TOP 之间

在这个空间中,有一部分用于高端内存的临时映射。这块空间具有如下特点: 每个 CPU 占用一块空间;可以用在中断处理函数和可延迟函数的内部,从不阻塞,禁止内核抢占;在每个 CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个 page,每个小空间用于一个目的,这些目的定义在 kmap_types.h 中的 km_type 中。

当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的地址作为映射地址。这意味着一次临时映射会导致以前的映射被覆盖。

接口函数:kmap_atomic/kunmap_atomic。 使用从FIX_KMAP_BEGIN到FIX_KMAP_END之间的物理页

2、  长久映射空间

长久映射地址空间是预留的线性地址空间。访问高内存的一种手段。使用方式是先通过alloc_page() 获得了高端内存对应的 page,然后内核从专门为此留出的线性空间分配一个虚拟地址,在 PKMAP_BASE 到 FIXADDR_START 之间。

接口函数:void*kmap(struct *page)、 void kumap(struct *page)

该接口函数在高/低内存都能使用,可以睡眠,数量有限。对于不使用的的 page,及应该时从这个空间释放掉(也就是解除映射关系)。

#definePKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) & PMD_MASK)

#defineLAST_PKMAP 1024

3、非连续映射地址空间

非连续映射地址空间适用于为不频繁申请释放内存的情况,这样不会频繁的修改内核页表。总的来说,内核主要在以下情况使用非连续映射地址空间:映射设备的I/O空间;为内核模块分配空间;为交换分区分配空间

每个非连续内存区都对应一个类型为vm_struct 的描述符,通过next字段,这些描述符被插入到一个vmlist链表中。

这种方式下高端内存使用简单,因为通过vmalloc() ,在”内核动态映射空间“申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说高端内存有可能映射到”内核动态映射空间“中。

接口函数:vmalloc(vfree):物理内存(调用alloc_page)和线性地址同时申请,物理内存是 __GFP_HIGHMEM类型(分配顺序是HIGH, NORMAL , DMA )(可见vmalloc不仅仅可以映射HIGHMEM页框,它的主要目的是为了将零散的,不连续的页框拼凑成连续的内核逻辑地址空间... );

vmap(vumap):vmalloc的简化版;

ioremap(iounmap):分配I/O映射空间;

下图简单表达了linux内核对虚拟地址的映射,其中highmem区域用于对高端内存映射:

四、MIPS的高端内存

在MIPS32 CPU中不经过MMU转换的内存窗口只有kseg0和kseg1 的512MB的大小,而且这两个内存窗口映射到同一得0~512M的物理地址空间。其余的3G虚拟地址空间需要经过MMU转换成物理地址,这个转换规则是由CPU 厂商实现的。换句话说,在MIPS32 CPU下面访问高于512M的物理地址空间,必须通过MMU地址转换。即按VA=PA+PAGE_OFFSET公式映射的空间最大只有512M,其中PAGE_OFFSET=0x80000000,而在Linux中MIPS32只使用其中的256MB。

MIPS在higmem使用过程中需要注意两个问题:一是要考虑由higmem带来的整个系统性能和稳定性间的平衡,二是highmem不支持cache aliases。

五、总结

高端内存含义为:线性地址空间 PAGE_OFFSET+HIGHSTART至4G的最后线性地址 <==映射==> HIGHSTART以上的物理页框,非直接映射。有3种方法:非连续内存区映射,永久内核映射,临时内核映射(固定映射)。

用户空间当然可以使用高端内存,而且是正常的使用,内核在分配那些不经常使用的内存时,都用高端内存空间(如果有),所谓不经常使用是相对来说的,比如内核的一些数据结构就属于经常使用的,而用户的一些数据就属于不经常使用的。

用户在启动一个应用程序时,是需要内存的,而每个应用程序都有3G的线性地址,给这些地址映射页表时就可以直接使用高端内存。

总之,内核的高端线性地址是为了访问内核固定映射以外的内存资源。实际上高端内存是针对内核一段特殊的线性空间提出的概念,和实际的物理内存是两码事。进程在使用内存时,触发缺页异常,具体将哪些物理页映射给用户进程是内核考虑的事情。在用户空间中没有高端内存这个概念。

注:1、本文中本文中虚拟地址和线性地址没做细致区分,可认为是一个概念。

2、关于highmem的代码分析可参见《关于高端内存的一些笔记》一文:http://bbs.chinaunix.net/thread-1938084-1-1.html

Linux内存管理原理

本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

Linux内存管理原理【转】

转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

Windows内存管理和linux内存管理

windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

Linux内核分析(三)----初识linux内存管理子系统

原文:Linux内核分析(三)----初识linux内存管理子系统 Linux内核分析(三) 昨天我们对内核模块进行了简单的分析,今天为了让我们今后的分析没有太多障碍,我们今天先简单的分析一下linu ...

伙伴系统之伙伴系统概述--Linux内存管理&lpar;十五&rpar;

在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法. Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, ...

启动期间的内存管理之bootmem&lowbar;init初始化内存管理–Linux内存管理&lpar;十二&rpar;

1. 启动过程中的内存初始化 首先我们来看看start_kernel是如何初始化系统的, start_kerne定义在init/main.c?v=4.7, line 479 其代码很复杂, 我们只截取 ...

启动期间的内存管理之初始化过程概述----Linux内存管理&lpar;九&rpar;

在内存管理的上下文中, 初始化(initialization)可以有多种含义. 在许多CPU上, 必须显式设置适用于Linux内核的内存模型. 例如在x86_32上需要切换到保护模式, 然后内核才能检 ...

Linux内存管理 &lpar;25&rpar;内存sysfs节点解读

1. General 1.1 /proc/meminfo /proc/meminfo是了解Linux系统内存使用状况主要接口,也是free等命令的数据来源. 下面是cat /proc/meminfo的 ...

Linux内存管理 &lpar;1&rpar;物理内存初始化

专题:Linux内存管理专题 关键词:用户内核空间划分.Node/Zone/Page.memblock.PGD/PUD/PMD/PTE.lowmem/highmem.ZONE_DMA/ZONE_NOR ...

随机推荐

php使用PDO连接mysql数据库

ListView在列表的头部和底部添加布局——addHeaderView,addFooterView

addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 以addHeaderView为例: View he ...

IPC 机制简介

IPC 机制简介 概述 在Unix早期发展中,做出重大贡献的两大主力Bell实验室和伯克利大学(BSD)在IPC(InterProcess Communication)方面的侧重点有所不同.前者对Un ...

Java AIO 入门实例(转)

Java7 AIO入门实例,首先是服务端实现: 服务端代码 SimpleServer: public class SimpleServer { public SimpleServer(int port ...

彻底理解Java的Future模式

先上一个场景:假如你突然想做饭,但是没有厨具,也没有食材.网上购买厨具比较方便,食材去超市买更放心. 实现分析:在快递员送厨具的期间,我们肯定不会闲着,可以去超市买食材.所以,在主线程里面另起一个子线 ...

eclipse安装checkstyle无法加载到preferences的问题

描述一下问题,eclipse安装checkstyle,不管是在线安装还是下载安装,在preferences都没有checkstyle选项,如下: 然我们要的效果是这样的:   解决方案如下: 1 启动 ...

第九节,MXNet:用im2rec&period;py将图像打包生成&period;rec文件

1.生成.lst文件 制作一个文件路径和标签的列表: import os import sys #第一个参数是输入路径 input_path=sys.argv[1].rstrip(os.sep) #第 ...

【题解】Luogu P2147 &lbrack;SDOI2008&rsqb;洞穴勘测

原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 我不太会踩爆Link-Cut-Tree的并查集做法qaq 我们用Link-Cut-Tree维护连通性(十分无脑) Co ...

(转第二方案)在 ASP&period;NET 環境下使用 Memcached 快速上手指南

转自:http://blog.miniasp.com/post/2010/01/27/Memcached-for-ASPNET-Quick-Start-Guide.aspx 之前一直想研究 Memca ...

linux内存管理子系统采用基于内存区域,Linux 内存管理之highmem简介相关推荐

  1. 基于linux的智能小车_基于ARM10与LINUX智能小车系统设计.doc

    基于ARM10与LINUX智能小车系统设计 基于ARM的智能小车系统的设计 摘 要 基于ARM的嵌入式系统其性能优良,移植性好,已广泛应用在各个行业,因此将ARM微处理器应用于智能小车的控制系统是一种 ...

  2. arm linux考勤,定稿毕业论文_基于ARM与Linux的员工刷卡考勤系统喜欢就下吧(范文1)...

    <毕业论文_基于ARM与Linux的员工刷卡考勤系统.doc>由会员分享,可免费在线阅读全文,更多与<(定稿)毕业论文_基于ARM与Linux的员工刷卡考勤系统(喜欢就下吧)> ...

  3. 工资管理信息系统java_基于jsp的职工工资管理信息系统-JavaEE实现职工工资管理信息系统 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的职工工资管理信息系统, 该项目可用各类java课程设计大作业中, 职工工资管理信息系统的系统架构分为前后台两部分, ...

  4. android日程管理开题报告,基于andorid,安卓个人行程管理软件app,毕业论文设计,课程,开题报告...

    andorid项目源码日程管理带文档毕业论文设计 1.引言 1.1目标 本文编辑的目标旨在帮助读者了解和熟悉Android个人行程管理软件-Reminder的各部分功能实现和操作使用方法.通过阅读本文 ...

  5. linux文件系统目录结构采用的是,在Linux中,文件系统的目录结构采用的是()。...

    在Linux中,文件系统的目录结构采用的是(). 更多相关问题 徒长枝属于以下哪种一年生枝条类别中的一种() 以下对得房率描述正确的是() 用拉伸试验的方法,可测定金属材料的(). 以下对得房率描述正 ...

  6. Linux串口打印信息工具,基于Qt实现Linux或Windows串口打印工具

    一.运行结果 二.实现过程 1.打开串口 首先我们需要创建一个QSerialPort对象,然后调用它的open函数打开串口设备,然后再调用它的bool setBaudRate(qint32 baudR ...

  7. linux电容触摸屏驱动参数,基于FT5x06嵌入式Linux电容触摸屏驱动

    **************************************************************************************************** ...

  8. ubuntu系统虚拟机linux系统,基于虚拟机的Linux操作系统安装(Ubuntu

    <基于虚拟机的Linux操作系统安装(Ubuntu>由会员分享,可在线阅读,更多相关<基于虚拟机的Linux操作系统安装(Ubuntu(13页珍藏版)>请在人人文库网上搜索. ...

  9. java美容美发项目下载_基于jsp的美容美发管理-JavaEE实现美容美发管理 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的美容美发管理, 该项目可用各类java课程设计大作业中, 美容美发管理的系统架构分为前后台两部分, 最终实现在线上 ...

最新文章

  1. Twiiter,下一个热点
  2. 重磅!微软发布 vscode.dev,把 VS Code 带入浏览器!
  3. python全局解释锁_Python GIL 全局解释性锁介绍
  4. 开发留言本,学习笔记
  5. UItableView的一些特殊点击效果
  6. Windows7下注册OCX的注意事项
  7. hbase regions_使用Regions ADF 11g进行Master Detail CRUD操作
  8. Xenix — 微软与UNIX的短暂爱恋
  9. 安卓开发面试题及答案,一次哔哩哔哩面试经历,年薪50W
  10. pdfContentByte 类 图像和文本的绝对位置
  11. mysql重复数据处理_MySQL 处理重复数据
  12. 开启UDK(Unreal Development Kit)之旅
  13. 朋友:趣头条上市了!我:谁?
  14. mysql pxc介绍_MySQL高可用之PXC简介
  15. 饥荒如何修改服务器人数,饥荒联机怎么改房间人数?饥荒修改房间人数方法
  16. [必看]身份证复印件的正确用法
  17. H5地理定位、百度地图使用
  18. lm283_BP283X 最小输入输出压差和OVP电压的关系
  19. MySQL字段类型如何选择?
  20. 【蓝桥杯省赛真题36】Scratch三国演义字数统计 少儿编程scratch编程蓝桥杯省赛真题讲解

热门文章

  1. 量化交易alpha策略是什么?
  2. html自动隐藏滚动条,隐藏HTML页面上的滚动条
  3. g代码生成器 源代码_生成源代码,这是一个妥协
  4. 在微软官网下载旧版本的Visual Studio
  5. 不到50行代码,HTML+CSS+JS创建一个简单的色轮
  6. tomcat 在linux上的重启和关闭命令
  7. python2.7web代码用python3.6运行时,浏览器发送请求报错TypeError: Object of type 'bytes' is not JSON serializable的解决办法
  8. 利用武稀松版HtmlParser解析Html,使用CSS选择器定位节点
  9. FPGA:Error: Current license file does not support the EP2C35F672C6 device
  10. Python编程风格和设计模式