对于没有启用物理地址扩展的32位系统,两级页表已经足够了。从本质上说Linux通过使“页上级目录”位和“页中间目录”位全为0,彻底取消了页上级目录和页中间目录字段。不过,页上级目录和页中间目录在指针序列中的位置被保留,以便同样的代码在32位系统和64位系统下都能使用。内核为页上级目录和页中间目录保留了一个位置,这是通过把它们的页目录项数设置为1,并把这两个目录项映射到页全局目录的一个合适的目录项而实现的。
1. Linux物理内存三级架构 对于内存管理,Linux采用了与具体体系架构不相关的设计模型,实现了良好的可伸缩性。它主要由内存节点node、内存区域zone和物理页框page三级架构组成。
前面我们提到Linux内核仅使用了较少的分段机制,但是却对分页机制的依赖性很强,其使用一种适合32位和64位结构的通用分页模型,该模型使用四级分页机制,即
在 x86 系统中,内存管理中的分页机制是非常重要的,在Linux操作系统相关的各种书籍中,这部分内容也是重笔浓彩。
在引入虚拟地址概念以后,程序员和CPU看到的都是虚拟地址。当CPU尝试去访问某个虚拟地址的时候,这时候硬件单元MMU就会将此虚拟地址转化为物理地址,然后CPU再去访问。
在虚拟内存中,页表是个映射表的概念, 即从进程能理解的线性地址(linear address)映射到存储器上的物理地址(phisical address).
http://bbs.chinaunix.net/thread-2083672-1-1.html
理想情况下用户对内存的期待是大容量、高速度和持久性,但是现实中却是一个由缓存、主存、磁盘组成的内存架构,该架构中,缓存低容量、速度快但是成本高,主存中速度、中容量和中成本,磁盘就是大容量、持久性但是速度慢。
基于前言中的内核配置,内核采用39位虚拟地址,因此可寻址范围为2^39 = 512G,采用(linux 默认为五级页表,另外还有PUD,P4D,由于本文只配置三级,其他两项不予罗列)3级页表结构,分别为:
RISC-V的指令(包括用户态下的或者内核态下的)里面的地址操作数其实代表了虚拟地址.但是对应地,RAM或者叫做物理内存,自然也有物理地址,物理地址真实唯一地标记实际内存空间,可能RAM的第10006个区块地址就是0x10006.所以说就有页表这个东西,把指令提供的逻辑地址转化到实际内存的物理地址.
大家在看内核代码时会经常看的以上术语,但在ARM的芯片手册中并没有用到这些术语,而是使用L1,L2,L3页表这种术语。
本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。
(1)虚拟地址(VA)为48位,而一般只使用到39位(512G内核,512G用户)
与硬件相关的代码全部放在 arch(architecture 一词的缩写,即体系结构相关)目录下。
注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同。
作者简介: 程磊,一线码农,在某手机公司担任系统开发工程师,日常喜欢研究内核基本原理。 1.1 内存管理的意义 1.2 原始内存管理 1.3 分段内存管理 1.4 分页内存管理 1.5 内存管理的目标 1.6 Linux内存管理体系 2.1 物理内存节点 2.2 物理内存区域 2.3 物理内存页面 2.4 物理内存模型 2.5 三级区划关系 3.1 Buddy System 3.1.1 伙伴系统的内存来源 3.1.2 伙伴系统的管理数据结构 3.1.3 伙伴系统的算法逻辑 3.1.4 伙伴系统的接口 3.1
Linux操作系统概述 Q1.什么是GNU?Linux与GNU有什么关系? A: 1)GNU是GNU is Not Unix的递归缩写,是自由软件基金会(Free Software Foundation,FSF)的一个项目,该项目已经开发了许多高质量的编程工具,包括emacs编辑器、著名的GNU C和C++编译器(gcc和g++); 2)Linux的开发使用了许多GNU工具,Linux系统上用于实现POSIX.2标准的工具几乎都是由GNU项目开发的;Linux内核、GNU工具以及其它一些自由软件组成
平时写过多进程多线程程序,比如使用linux的系统调用fork创建子进程和glibc中的nptl包里的pthread_create创建线程,甚至在java里使用Thread类创建线程等,虽然使用问题不大,但需要知道底层原理。这次在自己写操作系统的时候,看了一遍linux内核的进程创建过程。算是有了比较深入的理解。
虽然我喜欢分级页表,但是反置页表才是更加自然的方式。之所以叫做 反置 页表,大概是因为它颠倒我们常规理解的寻址:
内存管理的必要性 很早之前计算机只能运行单个进程,就算运行批处理程序,也是棑好对,一个一个的进行处理,不存在多个进程并发运行,这时候内核对于内存管理相对比较简单,直接把物理内存地址拿过来是使用即可。 随着计算机演进,支持多进程的OS,多个进程都都使用同一个物理地址空间,很容易多个进程之间相互干扰而引起进程的不可预期的行为。为了解决这个问题,CPU中的MMU(内存管理单元)引入了虚拟地址空间。以32位操作系统经为例,每个进程都可以拥有4G的寻址空间,当进程需要内存时候,通过转换技术和虚拟地址进行关联。MMU通
内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等,而且对性能也有很高的要求。本文从内存管理硬件架构、地址空间划分和内存管理软件架构三个方面入手,尝试对内存管理的软硬件架构做一些宏观上的分析总结。
本篇文章系统的给大家讲述linux操作系统原理,这是一篇非常好的linux系统基础教程,我们总结了相关的全部精选内容,一起来学习下。
In this lab you will explore page tables and modify them to simplify the functions that copy data from user space to kernel space.
操作系统用于处理内存访问异常的入口操作系统的核心任务是对系统资源的管理,而重中之重的是对CPU和内存的管理。为了使进程摆脱系统内存的制约,用户进程运行在虚拟内存之上,每个用户进程都拥有完整的虚拟地址空间,互不干涉。而实现虚拟内存的关键就在于建立虚拟地址(Virtual Address,VA)与物理地址(Physical Address,PA)之间的关系,因为无论如何数据终究要存储到物理内存中才能被记录下来。
你的电脑上或许此时插着一根 8G 的内存条,你经常在使用它,但你有没有想过操作系统是如何管理内存的?如果让你来分配使用,你是否会想着:给正在运行的游戏分配其中的 4G,给我的视频软件分配 2G,给音乐软件分配 1G,分配各自独立,互不干扰。但当我的游戏需要更多的内存的时候,是否我的视频就无法播放了呢?
我们知道LINUX的内存管理系统中有”反向映射“这一说,目的是为了快速去查找出一个特定的物理页在哪些进程中被映射到了什么地址,这样如果我们想把这一页换出(SWAP),或是迁移(Migrate)的时候,就能相应该更改所有相关进程的页表来达到这个目的。
KSMA的全称是Kernel Space Mirror Attack,即内核镜像攻击。本文主要记录对该攻击方法的原理分析以及Linux内核中相关内存管理部分。
假设这里文件在磁盘上都是连续存放的,此时有一个test.c文件,占据了6,7,8三个盘块的位置。
这篇文章是我在公司 TechDay 上分享的内容的文字实录版,本来不想写这么一篇冗长的文章,因为有不少的同学问是否能写一篇相关的文字版,本来没有的也就有了。
cgroup还有其他一些限制特性,如io,pid,hugetlb等,这些用处不多,参见Cgroupv1。下面介绍下与系统性能相关的io和hugepage,cgroup的io介绍参考Cgroup - Linux的IO资源隔离
因为这是我被问的最频繁的问题,哎呀我的程序 OOM 了怎么办,我的程序内存超过配额被 k8s 杀掉了怎么办,我的程序看起来内存占用很高正常吗?
这是 os summer of code 2020 项目每日记录的一部分: 每日记录github地址(包含根据实验指导实现的每个阶段的代码):https://github.com/yunwei37/os-summer-of-code-daily
我是cloud3,前段时间有虚拟机出现内存问题,今天借着这个话题给大家介绍一下内存虚拟化,也就是MMU虚拟化。
在连续分配中,一个进程不可被分割,只能整体放入一块连续的内存空间中;但在基本分页存储管理中,允许把一个进程按照固定大小 X 分割为多个部分,同时把内存也按照固定大小 X 分割为多个部分,并把前者对应地放到后者中(不要求连续存放)。通常来说,一个进程的最后一部分会小于 X,这部分若放到内存的某个 X 空间中,则仍然会产生碎片(这种碎片称为页内碎片),要让这种碎片尽可能小,X 也必须尽可能小。
栈是编程中使用内存最简单的方式。例如,下面的简单代码中的局部变量 n 就是在堆栈中分配内存的。
在某些时候我们需要读写的进程可能存在虚拟内存保护机制,在该机制下用户的CR3以及MDL读写将直接失效,从而导致无法读取到正确的数据,本章我们将继续研究如何实现物理级别的寻址读写。
也就是我们实际中编码时遇到的内存地址并不是对应于实际内存上的地址,我们编码中使用的地址是一个逻辑地址,会通过分段和分页这两个机制把它转为物理地址。而由于linux使用的分段机制有限,可以认为,linux下的逻辑地址=线性地址。也就是,我们编码使用的是线性地址,之后只需要经过一个分页机制就可以把这个地址转为物理地址了。所以我们更重要的可能是去说明一下linux的分页模型。
操作系统确实是比较难啃的一门课,至少我认为比计算机网络难太多了,但它的重要性就不用我多说了。
前面已经分析过了Intel的内存映射和linux的基本使用情况,已知head_32.S仅是建立临时页表,内核还是要建立内核页表,做到全面映射的。下面就基于RAM大于896MB,而小于4GB ,切CONFIG_HIGHMEM配置了高端内存的环境情况进行分析。
/* * linux/mm/memory.c * * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds */ /* * demand-loading started 01.12.91 - seems it is high on the list of * things wanted, and it should be easy to implement. - Linus */ /* * Ok, demand-loading wa
CPU Cache学习 为什么需要Cache? CPU要从内存中直接读取数据都要花费几百个时间周期,在这几百个时间周期内,处理器除了等待什么都做不了,为了解决这个问题才提出Cache这个概念 Cach
从技术角度来说,一讲到TEE就会提到TrustZone,这是因为虽然TEE OS实现有多种多样,主芯片厂商也有好几种,但是大部分都是基于Arm的TrustZone架构。
页表是操作系统为每个进程提供私有地址空间和内存的机制。页表决定了内存地址的含义,以及物理内存的哪些部分可以访问。它们允许xv6隔离不同进程的地址空间,并将它们复用到单个物理内存上。
本文介绍了地址空间和二级页表、Linux下的线程、线程的优缺点以及线程与进程的关系等概念。
虚拟内存是一种操作系统提供的机制,用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上。通过使用虚拟内存,操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题。
操作系统可以使用页表硬件的技巧之一是延迟分配用户空间堆内存(lazy allocation of user-space heap memory)。
通用操作系统,通常都会开启mmu来支持虚拟内存管理,而页表管理是在虚拟内存管理中尤为重要,本文主要以回答几个页表管理中关键性问题来解析Linux内核页表管理,看一看页表管理中那些鲜为人知的秘密。
昨天下午,旁边的同事在学习Linux系统中的虚拟地址映射(经典书籍《程序员的自我修养-链接、装载与库》),在看到6.4章节的时候,对于一个可执行的ELF文件中,虚拟地址的值百思不得其解!
领取专属 10元无门槛券
手把手带您无忧上云