news 2026/9/12 19:30:07

ARM64 Linux 6.10内核启动流程9-io.h —— readl、writel、ioremap实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ARM64 Linux 6.10内核启动流程9-io.h —— readl、writel、ioremap实现

§1.1include/linux/io.hreadl/writelioremap

平台:QEMUvirt+ ARM64。


1. 这条要明白什么

ioremap 笔记回答「为什么必须开窗」。本条回答「窗开好了,C 代码写哪几个接口」。

phys = DT reg(virt UART 常见 0x09000000) base = ioremap / devm_ioremap_resource() 开窗 → void __iomem * val = readl(base + OFFSET) 读 32 位 writel(val, base + OFFSET) 写 32 位

*(u32 *)base不行:编译器可能删/合并访问,乱序 CPU 上写控制、写数据可能在总线上颠倒,也不标明这是 MMIO。


2. 为什么linux/io.h里看不见这三个名字

include/linux/io.h是驱动的入口头,自己只多了devm_ioremap*memremap等。裸接口在第 14 行拉进来:

#include<asm/io.h>

ARM64 上这就是arch/arm64/include/asm/io.h。它先定义本架构积木,再包含通用层:

#include<asm-generic/io.h>/* 约第 294 行 */

驱动看到的名字在include/asm-generic/io.h

接口约行干什么
readl217便携读 32 位 MMIO
writel273便携写 32 位 MMIO
ioremap1058inline:ioremap_prot(addr, size, _PAGE_IOREMAP)

关联方式是编译期#include拼头文件,不是运行时函数表。generic 里用#ifndef readl:架构若自己提供了同名接口就跳过,否则用这套默认实现。ARM64 选择提供__raw_*+ barrier,让 generic 去搭readl

驱动 #include <linux/io.h> │ ▼ arch/arm64/include/asm/io.h │ __raw_readl / __raw_writel / __io_ar / __io_bw │ _PAGE_IOREMAP = PROT_DEVICE_nGnRE ▼ include/asm-generic/io.h │ readl / writel / ioremap ▼ ioremap_prot() → generic_ioremap_prot() (C,见 ioremap 笔记) __raw_readl() → ldr (汇编)

3.readl/writel:包装后的 load/store

CPU 访问 MMIO 本来就只有 load/store。包装层把架构差异藏起来。

3.1readl

readl(addr) asm-generic/io.h:217 __io_br() ARM64 上几乎为空 val = le32_to_cpu(__raw_readl(addr)) │ └── ldr Wt, [Xn] arch/arm64/include/asm/io.h (部分 CPU 用 ldar 规避 erratum) __io_ar(val) dma_rmb + 控制依赖,读完再让后面的指令排上去 return val

3.2writel

writel(value, addr) asm-generic/io.h:273 __io_bw() dma_wmb:先让前面的写对设备可见 __raw_writel(cpu_to_le32(value), addr) │ └── str Wt, [Xn] __io_aw() ARM64 上几乎为空

相对直接*,多了三件事:

  1. volatile+asm volatile:这次访问必须发生,不能被优化掉。
  2. barrier:多核乱序下保证「先写 A 再写 B」的程序顺序,对设备也成立。
  3. 小端:MMIO 按 little-endian 解释(le32_to_cpu/cpu_to_le32)。

宽度:readb/writeb(8)、readw/writew(16)、readl/writel(32)、readq/writeq(64)。
readl_relaxed/writel_relaxed少屏障、更快,顺序弱;默认用带屏障的版本。

x86 同一套readl会换成别的访存指令;驱动源码不用改。这就是「generic + asm 积木」的意义。


4.ioremap不是汇编

asm-generic/io.h里(CONFIG_GENERIC_IOREMAP,ARM64 已选):

staticinlinevoid__iomem*ioremap(phys_addr_taddr,size_tsize){returnioremap_prot(addr,size,_PAGE_IOREMAP);}

ARM64_PAGE_IOREMAP=PROT_DEVICE_nGnRE。之后整条是你已经梳过的 C 路径:门禁 → 占 vmalloc 窗口 → 填页表。返回的虚拟地址,才是上面ldr/strXn

两条线在__iomem *碰头:

ioremap(phys) 改页表,得到 vaddr (C) readl(vaddr) ldr [vaddr] → MMU → 物理寄存器

linux/io.h里驱动更该用的映射接口:

  • devm_ioremap()/devm_iounmap():绑在struct device上,卸载自动拆映射
  • 新代码优先devm_platform_ioremap_resource()(1.2 / 1.3),最后仍进ioremap_prot
  • virt PL011:amba-pl011.cdevm_ioremap_resource(dev, mmiobase)

ioremap必须自己iounmapprobe失败路径容易漏。

memremap是给「这段物理 RAM 要按指定缓存属性映射」用的,不是 UART 那种 Device MMIO。本条知道名字即可。


5. 用 virt UART 串起来

DT uart@9000000 { reg = <0x09000000 0x1000>; } │ ▼ probe:devm_ioremap_resource() → ioremap() → ioremap_prot() → generic_ioremap_prot() → 页表:某 vaddr → 0x09000000,Device 属性 │ ▼ readl(base + UARTDR) → ldr [base+UARTDR] → MMU → 物理 0x09000000 + UARTDR → PL011 数据寄存器

没有 ioremap,ldr没有合法内核虚拟地址。没有readl,开了窗也会被编译器/乱序搞错。清单把二者写在同一条,就是这套完整用法。


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

Green Hills工程文件管理与源文件注释实践

1. Green Hills工程文件管理基础在嵌入式开发领域&#xff0c;Green Hills Software&#xff08;简称GHS&#xff09;的集成开发环境被广泛应用于航空电子、汽车电子等高可靠性领域。其工程文件管理机制与常见的Visual Studio、Eclipse等IDE有着显著差异&#xff0c;这往往让初…

作者头像 李华
网站建设 2026/9/12 19:28:31

计算机中断处理机制:原理、流程与优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 19:27:56

源码深度解析,Spring 如何解决循环依赖?

1. 基础知识1.1 什么是循环依赖 &#xff1f;一个或多个对象之间存在直接或间接的依赖关系&#xff0c;这种依赖关系构成一个环形调用&#xff0c;有下面 3 种方式。我们看一个简单的 Demo&#xff0c;对标“情况 2”。Service public class Louzai1 {Autowiredprivate Louzai2…

作者头像 李华
网站建设 2026/9/12 19:27:17

246基于SpringBoot4+Vue3的南京旅游推荐系统、南京旅游平台、个性化旅游推荐、在线旅游预约系统、智慧旅游Web系统;协同过滤推荐算法、景点-线路-酒店一体化管理与预约、毕业设计、课程设计

✅博主简介&#xff1a;Java全栈开发工程师&#xff08;bishecoder&#xff09;&#xff0c;精通Java开发、系统设计、项目实战。 ✅技术栈&#xff1a;SpringBoot、Vue、React、Node.js、Nest.js、uni-app等 ✅技术擅长&#xff1a;定制项目、修改代码、编写文档、技术指导等。…

作者头像 李华
网站建设 2026/9/12 19:27:05

AI论文写作助手:提升效率与规范性的智能解决方案

1. 项目背景与核心价值"书匠策AI"这个名称本身就蕴含着双重隐喻——"书匠"代表传统学术写作的工匠精神&#xff0c;"策"则暗示AI技术的策略性辅助。作为一款面向毕业论文写作的智能导航系统&#xff0c;它本质上是在解决学术写作中的三大痛点&am…

作者头像 李华
网站建设 2026/9/12 19:26:18

Spring Boot异步编程实战:大文件上传并发瓶颈与分片合并方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华