news 2026/7/15 5:58:21

Linux 内核学习(16) --- linux x86-64 虚拟地址空间和区域

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 内核学习(16) --- linux x86-64 虚拟地址空间和区域

目录

      • x86_64 的虚拟地址空间
      • 直接映射区和 vmalloc 区域
      • I/O 统一编址与 ioremap
      • alloc_pages 内存

x86_64 的虚拟地址空间



直接映射区和 vmalloc 区域

内核虚拟地址空间直接映射区:

  • 直接映射区是内核虚拟地址空间中一段连续的区域,将物理内存按固定偏移(通常是PAGE_OFFSET)线性地映射到虚拟地址空间
  • x86_64架构上,物理地址0x0对应的内核虚拟地址通常是0xffff888000000000(即PAGE_OFFSET

设计内核直接映射区原则:

  • 高效访问物理内存:通过简单的加/减偏移即可完成物理地址 ↔ 虚拟地址的转换,无需查页表
  • 用于大块连续物理内存的管理:内核初始化时会将大部分物理内存(如低端内存)通过直接映射区映射,便于快速分配(如伙伴系统分配的页)
  • 性能优化:避免频繁创建/销毁页表项,提高内存访问速度

局限性:
要求物理内存连续:直接映射区只能映射物理上连续的内存页
地址空间有限:在 32 位系统上,直接映射区大小受限(如896MB),无法覆盖全部物理内存(尤其在大内存系统中)
无法处理不连续物理内存:当需要大块虚拟连续但物理不连续的内存时,直接映射区无能为力

vmalloc内存区域:

  • vmalloc是内核提供的一个函数,它分配的内存在虚拟地址上连续,但物理地址可以不连续
  • 这些内存通过页表动态映射到vmalloc区域,通常位于直接映射区之上(在 64 位系统中位于较高地址)

设计原则
解决物理内存碎片问题:当系统运行一段时间后,物理内存可能碎片化,难以分配大块连续物理内存,vmalloc允许用多个不连续的物理页拼成一个虚拟连续区域
支持大内存分配:适用于需要大块虚拟地址空间(如模块加载、I/O 映射、某些驱动缓冲区)但不要求物理连续的场景

局限性
性能开销:每次访问都需要查页表;分配时需修改页表,可能触发TLB刷新
地址空间碎片:频繁的vmalloc/free可能导致vmalloc区域本身碎片化
不能用于原子上下文:因为可能睡眠(需分配页表等)

举例说明:

  1. kmalloc: 小内存分配通常使用直接映射区(slab/slob/slub分配器基于伙伴系统,返回直接映射的页)
  2. vmalloc: 加载内核(代码/数据可能较大而且无法保证物理连续)、某些 GPU/设备驱动的缓冲区
  3. ioreamp: 将设备I/O内存映射到vmalloc区域,因为设备地址不属于普通物理内存

I/O 统一编址与 ioremap

ARM架构处理器中,I/O地址通常是与内存统一编址的(memory-mapped I/O,简称MMIO

ARM架构 没有 为I/O操作提供独立的I/O地址空间(不像x86架构那样有专门的in/out指令和独立的I/O端口地址空间,
相反,ARM使用 内存映射 I/O(Memory-Mapped I/O, MMIO) 的方式

外设的寄存器(如UARTGPIO、定时器等)被映射到系统的物理内存地址空间中
CPU通过普通的加载(load) 和 存储(store) 指令(如LDRSTR)来访问这些地址,从而读写外设寄存器
这些地址通常位于系统地址空间的特定区域(例如,SoC厂商会指定外设寄存器位于0x400000000x5FFFFFFF等范围)

  1. 如何在内核空间读写 I/O 地址

ioremap(phys_addr, size)将一段物理I/O地址映射到内核的虚拟地址空间;
返回一个虚拟地址(void __iomem* 类型),后续通过readl()writel()ioread32()iowrite32()等专用函数访问;
这些函数确保正确的内存访问语义(如禁止编译器优化、保证访问顺序、处理弱内存模型等)

举例如下:

// 使用 ioremap 的情况void__iomem*reg=ioremap(0xFED40000,4);// 映射4字节writel(0x12345678,reg);// 正确!通过虚拟地址访问

使用的物理空间如下:

物理地址空间:[0x00000000 - 0x3FFFFFFF]:系统 RAM(已线性映射)[0xFED40000 - 0xFED40FFF]:PCI 设备配置空间[0xFEC00000 - 0xFEC00FFF]:APIC 寄存器[0xFEE00000 - 0xFEE00FFF]:IOAPIC 寄存器 虚拟地址空间(内核部分):[0xffff888000000000]:直接映射区(RAM)[0xffffc90000000000]:vmalloc/ioremap 区域 ← ioremap 在这里分配虚拟地址 │ ↓ 建立页表映射[0xFED40000]物理 I/O 地址

alloc_pages 内存

alloc_pages()分配的物理内存,其对应的内核虚拟地址位于直接映射区(Direct Mapping Region),也叫线性映射区

alloc_pages()系列函数(包括__get_free_pageskmalloc的底层也用它)的主要目的是分配连续的物理页面

为了能让内核代码访问这些物理内存,必须将它们映射到内核的虚拟地址空间

直接映射是一种最简单的映射方式:在系统启动早期,内核会建立一个从物理地址到虚拟地址的固定偏移映射。在大多数架构(如 x86-64)上,这个偏移是固定的(例如0xffff888000000000)

它在内核虚拟地址空间中的典型起始地址是__PAGE_OFFSET(例如0xffff888000000000

地址转换:
当你调用alloc_pages(GFP_KERNEL, order) 并获得一个struct page*指针后,可以通过page_to_virt(page)宏来获取这块内存对应的内核虚拟地址

虽然alloc_pages()默认返回直接映射区的虚拟地址,但通过使用不同的标志,可以改变其行为,使其映射到其他区域:

  • GFP_HIGHUSER:当用于用户空间内存分配时(例如通过page fault处理程序),分配的物理页面最终会被映射到用户进程的虚拟地址空间,而不是内核的直接映射区。

  • __GFP_HIGHMEM(在 32 位系统上重要):在 32 位系统上,直接映射区大小有限(通常约896MB),无法映射所有物理内存超出部分称为“高端内存”,使用此标志分配的页面,其物理地址可能没有固定的内核虚拟地址。内核需要通过 kmap 等临时映射机制来访问它们
    但在 64 位系统上,由于虚拟地址空间极其庞大,已经废除了高端内存的概念,所有物理内存都可以线性映射

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 2:41:29

Multisim14.2安装教程:防病毒软件冲突解决方法

Multisim 14.2 安装卡住?别急,先让杀毒软件“闭嘴”!你是不是也遇到过这种情况:好不容易找到Multisim 14.2的安装包,兴冲冲地双击setup.exe,结果刚解压一半就弹出一个红色警告——“此程序可能有害&#xf…

作者头像 李华
网站建设 2026/7/11 5:11:33

软著撰写要点

一、什么样的内容可以写软著并申请成功?软著不查重,只要具备一定实用性功能且软件运行界面不同就可以申请软件著作权。二、申请软著需包含的核心文件软件著作说明书源代码计算机软件著作权登记信息表软件合作开发协议三、说明书说明书分为两种&#xff0…

作者头像 李华
网站建设 2026/7/14 9:06:35

Hive与Kylin整合:构建企业级OLAP解决方案

Hive与Kylin整合:构建企业级OLAP解决方案 一、引言:企业级OLAP的痛点与解决方案 1.1 痛点:当Hive遇到“慢查询”困境 在企业数据架构中,Hive作为经典的数据仓库工具,承担着原始数据存储、ETL(抽取-转换-加载)和批量计算的核心角色。它通过类SQL的HQL语言,让分析师无…

作者头像 李华
网站建设 2026/7/14 21:44:34

常见的垃圾回收器

目录 常见的垃圾回收器 串行垃圾收集器 并行垃圾收集器 并发垃圾收集器 总结 CMS的介绍 G1的介绍 特点 四个阶段 常见的垃圾回收器 并行(Parallel) :指多条垃圾收集线程并行工作,但此时用户线程处于STW状态。 并发&…

作者头像 李华
网站建设 2026/6/26 17:50:18

基于Java+SpringBoot+SSM办公管理系统(源码+LW+调试文档+讲解等)/办公系统/管理系统/办公自动化系统/企业办公管理系统/智能办公管理系统/协同办公管理系统

博主介绍 💗博主介绍:✌全栈领域优质创作者,专注于Java、小程序、Python技术领域和计算机毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 2025-2026年最新1000个热门Java毕业设计选题…

作者头像 李华
网站建设 2026/7/11 1:01:15

**发散创新:AI寻路算法的设计与实现**随着人工

发散创新:AI寻路算法的设计与实现 随着人工一、引言 随着机器学习、深度学习等技术的不断进步,AI在路径规划、寻路算法等领域的应用逐渐显现。本文将介绍一种新型的AI寻路算法,该算法能够自动学习并优化寻路策略,提高寻路效率。 三…

作者头像 李华