函数 ioremap 物理地址到内核映射空间的映射函数

为何要把物理内存地址映射到内核空间? http://blog.sina.com.cn/s/blog_3f0f794c0100ip2o.html 阅读详情

源代码:

/*
* Remap an arbitrary physical address space into the kernel virtual
* address space. Needed when the kernel wants to access high addresses
* directly.
*
* NOTE! We need to allow non-page-aligned mappings too: we will obviously
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*
* 'flags' are the extra L_PTE_ flags that you want to specify for this
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
void * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
{
void * addr;
struct vm_struct * area;
unsigned long offset, last_addr;

/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
if (!size || last_addr < phys_addr)
   return NULL;

/*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr) - phys_addr;

/*
* Ok, go for it..
*/
area = get_vm_area(size, VM_IOREMAP);
if (!area)
   return NULL;
addr = area->addr;
if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
   vfree(addr);
   return NULL;
}
return (void *) (offset + (char *)addr);
}

功能就是将I/O内存资源的物理地址映射到核心虚地址空间(3GB-4GB)中.

1、返回映射后的虚拟地址(get_vm_area获取)

2、对获取的虚拟空间进行页面映射(remap_area_pages)

下面是相关的函数:

struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
{
unsigned long addr, next;
struct vm_struct **p, *tmp, *area;

area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
if (!area)
   return NULL;

size += PAGE_SIZE;
if (!size) {
   kfree (area);
   return NULL;
}

addr = VMALLOC_START;
write_lock(&vmlist_lock);
for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
   if ((size + addr) < addr)
    goto out;
   if (size + addr <= (unsigned long) tmp->addr)
    break;
   next = tmp->size + (unsigned long) tmp->addr;
   if (next > addr)
    addr = next;
   if (addr > VMALLOC_END-size)
    goto out;
}
area->flags = flags;
area->addr = (void *)addr;
area->size = size;
area->next = *p;
*p = area;
write_unlock(&vmlist_lock);
return area;

out:
write_unlock(&vmlist_lock);
kfree(area);
return NULL;
}

static int remap_area_pages(unsigned long address, unsigned long phys_addr,
     unsigned long size, unsigned long flags)
{
int error;
pgd_t * dir;
unsigned long end = address + size;

phys_addr -= address;
dir = pgd_offset_k(address);
flush_cache_all();
if (address >= end)
   BUG();
spin_lock(&init_mm.page_table_lock);
do {
   pmd_t *pmd;
   pmd = pmd_alloc(&init_mm, dir, address);
   error = -ENOMEM;
   if (!pmd)
    break;
   if (remap_area_pmd(pmd, address, end - address,
      phys_addr + address, flags))
    break;
   error = 0;
   address = (address + PGDIR_SIZE) & PGDIR_MASK;
   dir++;
} while (address && (address < end));
spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
}

其中的一些映射关系参考内存管理的分页管理

 
【Linux驱动编程】mmap方法 mmap常规的应用是将普通文件映射到用户进程空间,提高文件读写效率。linux的思想是“一切皆文件”,对于设备文件而言,同样可以实现mmap映射。一个设备,一般涉及到帧缓存会考虑实现映射接口,常见的LCD<font color=cloor> framebuffer</font>设备的显存空间,经过映射后,用户进程可以直接操作进程内存空间将LCD显示数据写入,提高刷新效率,节省CPU拷贝内存开销。 阅读详情

相关推荐

边缘AI硬件风向:从专用芯片到端侧大模型

边缘AI硬件正呈现五大发展趋势:专用AI加速芯片(如华为昇腾、谷歌EdgeTPU)凭借高能效比成为主流;端侧大模型催生支持Transformer架构的新硬件需求;存算一体技术突破内存墙限制;FPGA和可重构计算提供灵活性;异构集成与Chiplet技术实现模块化设计。这些发展需要配套软件工具链支持,未来边缘设备将演变成具备本地智能的"智能体",竞争焦点转向算力、能效、易用性和成本的多维平衡。

qq_37027335的博客 348

windows内核情景分析笔记---虚存向物理页面的映射

既然懂了虚存和物理存储的管理,下面谈谈虚存向物理存储的映射 首先看第一个函数 NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process,                        PVOID Address,                        ULONG flProtect,                    

lycommand的专栏 1765

Android Settings 设置Preference置灰显示

使Preference置灰显示,不能点击。先调用Preference的setEnabled(false),再调用setShouldDisableView(true); 如果使置灰项恢复正常可点击,可调用setEnabled(true)。

随风而动 1048

Linux 字符设备驱动—— ioremap() 函数解析

一、ioremap() 函数基础概念 几乎每一种外设都是通过读写设备上的相关寄存器来进行的,通常包括控制寄存器、状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: a -- I/O 映射方式(I/O-mapped) 典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间...

weixin_30341745的博客 506

Bladed风电仿真软件新手必看:从界面操作到功率曲线计算的完整指南

本文为风电工程师提供Bladed仿真软件的完整入门指南,涵盖界面操作、功率曲线计算及动态仿真等核心功能。通过实战技巧和常见问题解决方案,帮助新手快速掌握这款全球领先的风电机组仿真工具,提升风电项目开发效率。

weixin_30839881的博客 102

STM32项目实战_基于STM32F103的智能药箱设计与实现(硬件详解+软件逻辑+调试要点)

本文详细介绍了基于STM32F103的智能药箱设计与实现,涵盖硬件设计、软件逻辑和调试要点。项目核心功能包括精准提醒、药品管理和远程监控,采用STM32单片机作为主控,结合光电开关、蓝牙模块等实现智能化管理。文章还分享了电路图设计、程序优化及常见问题解决方案,为嵌入式开发爱好者提供实用参考。

weixin_28717683的博客 303

linux函数地址偏移,linux2.4.19下__ioremap函数中remap_area_pages虚拟地址映射建立函数...

linux2.4.19下__ioremap函数中remap_area_pages虚拟地址映射建立函数的代码分析文章来源:http://gliethttp.cublog.cn接续前一篇文章《linux2.4.19下__ioremap和get_vm_area的粗略理解》未完成的部分-remap_area_pages,进行进一步阐述:虚拟内存vm技术,采用分页机制,使得进程可以使用比实际物理内存大甚多的...

weixin_33476149的博客 319

YOLOv11改进 | 细节涨点篇 | DySample一种最新的轻量化动态上采样算子(效果完爆CARAFE)

本文给大家带来的最新改进机制是一种号称超轻量级且有效的动态上采样器——DySample。与传统的基于内核的动态上采样器相比,DySample采用了一种基于点采样的方法,相比于以前的基于内核的动态上采样器,DySample具有更少的参数、浮点运算次数、GPU内存和延迟。此外,DySample在包括语义分割、目标检测、实例分割、全景分割和单目深度估计在内的五个预测任务中,性能均优于其他上采样器(截至目前最有效的上采样算子),

Snu77的博客 4210

论ioremap

ioremap   Linux在头文件include/linux/ioport.h中定义了三个对I/O内存资源进行操作的宏: (1)request_mem_region()宏,请求分配指定的I/O内存资源。 (2)check_mem_region()宏,检查指定的I/O内存资源是否已被占用。 (3)release_mem_region()宏,释放指定的I/O内存资源。        这三

wiserstar的专栏 2150

【系统分析师】2026年上半年真题:论文及解题思路

四篇论文围绕系统与开发实践展开: 安全架构设计强调数据加密(国密算法)、零信任访问控制及容灾架构,以某医疗云平台为例,实现RTO<5分钟的高可用保障。 架构风格应用解析微服务/事件驱动等风格选型,结合电商平台案例,通过服务拆分与异步通信提升扩展性。 需求评审机制提出正式评审与走查结合的方法,在金融系统中减少30%返工,解决业务规则二义性问题。 LLM测试生成利用大模型从需求/代码生成用例,辅以人工校验,使测试效率提升50%,覆盖边缘场景。 各篇均遵循“背景-理论-实践”结构,突出

数据知道的博客 783

Android13无重力感应系统修改触摸屏跟随屏幕显示旋转方向旋转

在实际产品中设计时会移除重力传感器。当设备缺少重力传感器时,系统无法使用该传感器提供的方向数据来确定屏幕旋转的方向。Android 系统中由于移除重力传感器导致的默认显示方向旋转引起触摸屏与屏幕显示不一致问题,主要是由于缺乏方向检测和触摸坐标的正确转换。通过使用替代传感器(如陀螺仪)、手动配置方向、调整触摸事件坐标和 UI 布局,可以解决这个问题。开发者需要确保在设备没有重力传感器的情况下,能够通过其他方法推测方向,并确保触摸事件和 UI 动作能够正确响应设备的旋转。

weixin_35723192的博客 803

关于ioremap

void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) phys_addr:要映射的起始的IO地址; size:要映射的空间的大小; flags:要映射的IO空间的和权限有关的标志; void *ioremap(unsigned long phys_addr, unsi

思维决定一切 1361

《网络安全自学教程》- MySQL脱库原理和步骤

MySQL脱库,脱库的原理,怎么脱库,脱库的步骤,一库三表六字段

wangyuxiang946的博客 1万+

create_mapping

本文描述的是关于MINI2440开发板上的SDRAM的内存映射(bootmem阶段) 硬件的基本参数为: 起始物理地址:0x30000000 物理内存大小:0x1000000 [16MB] 那么基于以上信息,在初始化过程中下面的变量已经被赋为如下的值: bank.start = 0x30000000  bank.size =  0x1000000[16MB] 通过阅读代码可以

zwmyxfbenet的专栏 1195

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

get-vm linux,linux2.4.19下__ioremap和get_vm_area的粗略理解

linux2.4.19下__ioremap和get_vm_area的粗略理解文章来源:http://gliethttp.cublog.cn对于提供了MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器而言,Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB.进程的4GB内存空间被人为的分为两个部分--用户空间与内核空间.用户空间地址分布从0到3GB(...

weixin_42398151的博客 290

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Linux内核中ioremap映射的透彻理解

几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器、状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址。根据CPU体系结构的不同,CPU对IO端口的编址方式有两种:   (1)I/O映射方式(I/O-mapped)   典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间"或者"I/O端口空间",CPU通过专门的I/O指令(如

独行者 403

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

linux64位ioremap函数,linux操作系统中的ioremap函数详解

在编写驱动程序的过程中,我们总免不了要使用ioremap函数来将我们的硬件的地址映射到系统的虚拟地址空间。ioramp函数原型:#define ioremap(cookie,size) __ioremap(cookie,size,0,1)这是一个宏来实现的,当然要进入__ioremap去看看究竟。void __iomem *__ioremap(unsigned long phys_addr, si...

weixin_31641077的博客 751

深入分析Linux内核源码——6.3 内存的分配和回收

6.3 内存的分配和回收    在内存初始化完成以后,内存中就常驻有内核映象(内核代码和数据)。以后,随着用户程序的执行和结束,就需要不断地分配和释放物理页面。内核应该为分配一组连续的页面而建立一种稳定、高效的分配策略。为此,必须解决一个比较重要的内存管理问题,即外碎片问题。频繁地请求和释放不同大小的一组连续页面,必然导致在已分配的内存块中分散许多小块的空闲页面。由此带来的问题是,即使这些小块的

bytxl的专栏 3123

【ARM Linux 内存管理入门及渐进5 - ioremap】

ARM Linux 引入设备树特性后,一些支持设备树的设备驱动不再使用直接 ioremap(),改用 drivers/of/address.c/of_iomap(),of_iomap() 的内部仍然会调用 ioremap()各字段具体含义可参照ARMv8手册中对内存属性的描述,内存可以分为DEVICE和NORMAL两大类型以及Device memory依据是否可合并等属性。​上面ioremap_xxx 接口中用到的属性参数主要是。从上面的接口定义看,除了addr和size外还有一个。

CodingCos的博客 4525

内存学习(三):物理地址空间

物理地址是处理器在系统总线上看到的地址。使用精简指令集(Reduced Instruction Set Computer, RISC)的处理器通常只实现一个物理地址空间,外围设备和物理内存使用统一的物理地址空间。有些处理器架构把分配给外围设备的物理地址区域称为设备内存。处理器通过外围设备控制器的寄存器访问外围设备,寄存器分为控制寄存器、状态寄存器和数据寄存器三大类,外围设备的寄存器通常被连续地编址。处理器对外围设备寄存器的编址方式有两种。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 786

Linux用户空间与内核空间

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。 Linux内核地址映射模型 x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。

5万+

Linux驱动虚拟地址和物理地址的映射

一般情况下,Linux系统中,进程的4GB内存空间被划分成为两个部分------用户空间和内核空间,大小分别为0~3G,3~4G。   用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核空间。   每个进程的用户空间都是完全独立、互不相干的,用户进程各自有不同的页表。而内核空间是由内核负责映射,它并不会跟着进程改变,是固定的。内核空间地址有自己对应的页表,内核的虚拟空间独立于其

David_xtd的专栏 1万+

每天理解一点Linux内核之地址映射

我们知道Linux内核对内存的管理主要都是通过分页来完成的,那么实际的物理页和虚拟页是怎样的对应的。这篇blog我们试图去聊着这个机制。 1.虚拟地址划分 32位地址意味着4G的虚存空间,Linux内核将这4G的空间分成两个部分,将高的1G字节(0xC00000000-0xFFFFFFFF)用于内核本身,成为系统空间。而较低的3G字节作为各个进程的用户空间,这样理论上各个进程都可以使用空间...

柳清风的专栏 1116

Kimi-k2.5如何重塑AI编程协作者能力边界

AI编程助手正从代码补全工具迈向深度协同伙伴,其核心在于大模型对工程语义的理解能力。长上下文(如200K tokens)是基础,但真正决定IDE场景实用性的,是代码语法保真度、技术栈精准识别与低延迟高置信输出——这正是Kimi-k2.5在Java/Python/TypeScript等主流语言中实现AST级建模与实时静态校验的价值所在。它不只生成代码,更理解Spring Boot配置、MyBatis映射逻辑或React组件契约,从而支撑遗留系统分析、跨语言转换、智能测试生成等高阶工程任务。本文聚焦Compos

weixin_33766168的博客 592

ioremap 函数映射操作已知的物理地址(寄存器、端口、IO)

ioremap 函数来映射到内核地址空间,然后修改虚拟地址空间达到控制寄存器的状态。 我用如下方法操作一个地址为0x56000020的端口

ZP1015 4857
上一篇: 内核驱动与文件创建读写
下一篇: ARM芯片的选型和应用
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值