《深入Linux内核架构》第4章 进程虚拟内存(1)

目录

4.1 简介

4.2 进程虚拟地址空间

4.2.1 进程地址空间分布

4.2.2 建立布局


第3章讲了两点:物理内存的管理,内核虚拟地址管理。

本章讲:用户进程的虚拟地址空间管理。

4.1 简介

一个进程的整个虚拟地址空间(0-3G)中只有少部分映射到物理页。其余虚拟地址在访问时通过缺页异常处理,分配物理页,并建立页表项。

MMU作用:将虚拟地址转换为物理地址。

        内部包含TLB硬件,用于缓存页表,加快转换速度。

4.2 进程虚拟地址空间

32位系统中,一个进程的虚拟地址空间范围:0 - 4G

TASK_SIZE:

        含义:用户的虚拟地址空间的大小。

        典型值:TASK_SIZE=3G。

PAGE_OFFSET:

        作用:划分内核空间和用户空间。

        典型值:0xC0000000,即3G用户空间,1G内核空间。

无论当前运行哪个进程,进程虚拟地址空间中内核部分的内容都相同。

解释:A/B两个进程的内核空间0xC0001000处会映射到相同物理内存。

        而两个进程的用户空间0xA0001000映射到不同物理内存。

4.2.1 进程地址空间分布

struct mm_struct:管理一个进程的虚拟地址空间。

struct task_struct {

        struct mm_struct         *mm;

}

虚拟内存区域:简称VMA。

一个进程空间有很多VMA,如:

        代码段,数据段,堆,栈,mmap映射区。

内核用struct vm_area_struct表示一个VMA。

struct mm_struct {         //部分成员如下

        ...

        unsigned long (*get_unmapped_area) (struct file *filp, addr, len, pgoff, flags);

                //在进程地址空间中寻找合适的mmap映射位置

        unsigned long         mmap_base;

                //mmap映射的起始位置

        

        unsigned long         task_size;

                //进程的虚拟空间长度

                //current->mm->task_size = TASK_SIZE;

        unsigned long         start_code, end_code, start_data, end_data;

                //代码段和数据段:开始和结束地址。

                //可执行文件映射到地址空间后,这些区域长度不变(只读)。

        unsigned long         start_brk, brk, start_stack;

                //start_brk:堆的起始地址。

                //brk:堆的结束地址。该值可变。(因为堆长度可变)

        unsigned long         arg_start, arg_end, env_start, env_end;

                //参数列表和环境变量。位于栈中最高位置。

        pgd_t *pgd;

                //该进程页全局目录表的起始位置。

};

task_struct中flags成员的PF_RANDOMIZE标志:

        作用:每次启动一个进程时,虚拟地址空间中mmap映射起点和栈起点进行随机偏移。

        好处:防止攻击,防止通过缓冲溢出而获得栈访问权。

        1. mmap映射起点:

                mm->mmap_base = TASK_SIZE/3 + 随机值。

        2. 栈起点:

                mm->start_stack = STACK_STOP - 随机值。

get_unmapped_area函数指针:

        作用:mmap函数以mmap_base为起始地址查找合适映射位置。

        体系架构可各自实现该函数指针。如ARM中arch_get_unmapped_area

宏CONFIG_STACK_GROWSUP:

        作用:可定义栈向上增长(默认向下增长)。

mmap增长方向也可以设置。

如何查找一个进程的虚拟地址address对应的物理地址?

        1. current -> task_struct -> mm_struct

        2. struct vm_area_struct *vma = find_vma(mm, address);

        3. 根据vma的起始地址和address,计算在vma中的偏移量。

                offset = address - vma->vm_start;

        4. 根据mm_struct的pgd成员和address得到PTE。

                三级/四级页表转换。

        5. 计算页帧号。

                pfn = pte_pfn(*pte);

        6. 加上偏移。

                物理地址 = pfn << PAGE_SHIFT | offset;

内核Linux 5.x为增加查找vma的cache hit,缓存了最近访问的vma

struct task_struct {

        struct vmacache         vmacache;

}

struct vmacache {

        struct vm_area_struct *vmas[4];

                //缓存最近访问的四个VMA

};

内核不能显式的将一个变量放入CPU cache。

访问变量后,其被硬件自动放入CPU cache中。

把VMA按访问时间先后顺序放入数组中,所以可得到最近访问的VMA,而该VMA大概率在CPU cache中。

4.2.2 建立布局

exec()调用load_elf_binary():

        作用:装载ELF二进制可执行文件,以创建进程的地址空间。

不同可执行文件有各自实现的struct linux_binfmt,如a.out。

struct linux_binfmt         elf_format = {

        .load_binary         = load_elf_binary,         //加载ELF格式的二进制文件

        .load_shlib           = load_elf_library,         //加载ELF格式的共享库

};

ELF文件启动过程:

        应用层:fork->exec,执行对应do_execve系统调用。

        内核:do_execve->do_execve_common -> search_binary_handler

                遍历所有struct linux_binfmt实例,执行load_binary函数指针,即ELF的load_elf_library。

/proc/sys/kernel/randomize_va_space:

        作用:设置地址空间随机化。默认开启,随机偏移量最大1M

load_elf_binary实现:

load_elf_binary -> setup_new_exec - > arch_pick_mmap_layout

void arch_pick_mmap_layout(struct mm_struct *mm)

{

        if ((current->flags & PF_RANDOMIZE)

                random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT;

        mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;

                //设置mmap区域起始位置

        mm->get_unmapped_area = arch_get_unmapped_area;

                //arch_get_unmapped_area为ARM中的实现

        mm->unmap_area = arch_unmap_area;

}

setup_arg_pages:

        设置mm->arg_start。

        设置mm->stack栈起始位置(加上随机偏移)。

get_unmapped_area什么时候调用?

        后续访问地址时,调用mmap来创建不同VMA,此时调用get_unmapped_area为新VMA选择合适位置。

        最终调用mm->get_unmapped_area或file->f_op->get_unmapped_area;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JKTECH柔性振动盘柔性上料机

柔性供料器&#xff1a;用途广泛与好处显著 在现代工业生产中&#xff0c;随着技术的不断进步和市场的多样化需求&#xff0c;对物料供应系统的要求也日益提高。柔性供料器&#xff0c;作为一种新型的物料供应装置&#xff0c;其用途广泛且好处显著&#xff0c;正逐渐受到各行…

苍穹外卖亮点再梳理 ||

一、项目整体亮点&#xff1a; 【注&#xff1a;基于每个亮点&#xff0c;均有整理的相关知识&#xff0c;可在博客中查看】 1.数据库的设计采用RBAC&#xff08;基于角色访问控制&#xff09;的权限设计。 RBAC将权限授予角色&#xff0c;然后将用户分配给角色&#xff0c;…

算法——倍增

. - 力扣&#xff08;LeetCode&#xff09; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#xff0c;其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径…

指针 基础知识

本笔记为观看56 指针-指针的定义和使用_哔哩哔哩_bilibili后的学习笔记 指针的定义和使用 1、定义指针 int main () {//1、定义指针int a 10;//指针定义的语法&#xff1a; 数据类型 * 指针变量名&#xff1b;int * p;//让指针记录变量a的地址p &a; //& 为取址符cou…

电商技术揭秘十六:电商中的实时分析与决策支持系统

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

如何部署上线项目

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 多环境多环境分类前端多环境实战请求地址启动方式项目配置 后端多环境实战 项目部署原始部署前端…

【项目】棋海争锋

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 项目介绍 WebSocket介绍 使用 项目创建 数据库设计 用户模块 登录接口 注册接口 获取用户信息接口 匹配模块 …

【Bing】开启代理后使用 Bing 搜索引擎总是: 没有与此相关的结果

【Bing】开启代理后使用 Bing 搜索引擎总是: 没有与此相关的结果 1 问题描述2 解决方法2.1 修改代理规则2.1.1 Clash Verge2.1.2 Clash Verge Rev2.1.3 V2RayN 1 问题描述 当我开了代理访问 Bing 时&#xff0c;经常会出现下面的页面: 2 解决方法 我所知的有三种方法: 手动关…

关于JVM-三色标记算法剖析

相关系列 深入理解JVM垃圾收集器-CSDN博客 深入理解JVM垃圾收集算法-CSDN博客 深入理解jvm执行引擎-CSDN博客 jvm优化原则-CSDN博客 jvm流程图-CSDN博客 三色标记产生的原因&#xff1f; 在并发标记的过程中&#xff0c;因为标记期间应用线程还在继续跑&#xff0c;对象间的引…

使用Matplotlib绘制打断图Broken Axis

使用Matplotlib绘制打断坐标轴Broken Axis 对于一批存在离群点的或者两极分化的数据&#xff0c;为了突出其值域差异&#xff0c;时常需要用到打断坐标轴效果。 使用Matplotlib绘制的效果如下&#xff1a; 对于同样的数据&#xff0c;使用brokenaxes库的绘制效果如下&#x…

Ubuntu20.04安装和编译运行lidar_align来联合标定lidar与imu的外参

硬件&#xff1a;树霉派4b 1、下载并安装lidar_align mkdir -p lidar_align/src cd lidar_align/src git clone https://github.com/ethz-asl/lidar_align.git 将 lidar_align/src/lidar_align/NLOPTConfig.cmake 文件移动到 lidar_align/src/ 下(与lidar_align同级) NLOP…

ShardingSphere-ShardingSphere读写分离和数据脱敏

文章目录 一、读写分离1.1 读写分离1.2 读写分离应用方案1.3 分表+读写分离1.4 分库分表+读写分离二、ShardingSphere-JDBC读写分离2.1 创建SpringBoot并添加依赖2.2 创建实体类2.3 创建mapper2.4 配置读写分离2.5 测试测试插入数据测试读测试事务一致性测试负载均衡一、读写分…

vue3+echarts:echarts地图打点显示的样式

colorStops是打点的颜色和呼吸灯、label为show是打点是否显示数据、rich里cnNum是自定义的过滤模板用来改写显示数据的样式 series: [{type: "effectScatter",coordinateSystem: "geo",rippleEffect: {brushType: "stroke",},showEffectOn: &quo…

【H3C】开启web管理页面H3C S5120V2 Series

配置步骤 1.创建对应vlan并放行通过 2.添加vlanfi的ip地址 3.开启http和https的服务 4.创建用户&#xff0c;配置密码&#xff0c;配置服务类型&#xff0c;赋予权限 假设终端连接在交换机的g1/0/1口 假设终端的ip地址为(Ubuntu)&#xff1a;192.168.200.11 /24 假设交换机vlan…

【Java 刷题记录】双指针

双指针 1. 移动零 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: n…

关于Ansible模块 ④

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》与《关于Ansible的模块 ③》之后&#xff0c;继续学习ansible常用模块之…

P3654 First Step (ファーストステップ) Python深搜

First Step (ファーストステップ) 题目背景 知らないことばかりなにもかもが&#xff08;どうしたらいいの&#xff1f;&#xff09; 一切的一切 尽是充满了未知数&#xff08;该如何是好&#xff09; それでも期待で足が軽いよ&#xff08;ジャンプだ&#xff01;&#xff09…

已解决:windows 下无法加载文件 xxx.ps1,因为在此系统上禁止运行脚本

目录 1&#xff0c;问题描述2&#xff0c;问题解决 1&#xff0c;问题描述 当通过 npm 全局安装依赖后&#xff08;比如 ts 对应的 tsc 命令&#xff0c;还有 pnpm&#xff09;&#xff0c;想直接使用安装的命令&#xff0c;就会报错&#xff1a; 2&#xff0c;问题解决 以管…

12+炫酷地图可视化效果,这次还真的有源码。

2023-09-17 22:35贝格前端工场 Hi&#xff0c;大家好&#xff0c;我是贝格前端工场&#xff0c;之前分享过各类UI图、动图、3D图、流程图&#xff0c;好多粉丝朋友给我要源文件&#xff0c;因为种种原因&#xff0c;无法提供。 本次分享12个炫酷的地图可视化效果&#xff0c;…

实现几何对象按照一定距离向外缓冲

1、首先&#xff0c;确保你已经引入了Turf.js库。你可以通过在HTML文件中添加以下代码来引入 <script src"https://cdn.jsdelivr.net/npm/turf/turf6.5.0/turf.min.js"></script>2、使用turf.buffer实现几何对象按照设定距离扩充 let originalCoordinat…