首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏linux驱动个人学习

    ioremap_nocache() 函数的使用

    函数原型 void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); /* * ioremap - CPU space * @offset: bus address of the memory * @size: size of the resource to map * * ioremap The returned * address is not guaranteed to be usable directly as a virtual * address. */ 调用ioremap_nocache ioremap是为一段高端的物理内存建立映射(即增加相关的页表内容),驱动常用mmap为可能不连续的一系列逻辑上相关的(如整体是一个文件)物理内存段建立映射,并呈现一个连续的虚拟地址空间。 ioremap是kernel提供的函数,只能在kernel里用。 用法 以下示例以读写基地址为0x9C016000,offset为0x100的寄存器为例。

    1.7K20发布于 2019-05-25
  • 内存管理五大技术概念:MMU、IOMMU、MMIO、mmap、ioremap

    本文将围绕MMU、IOMMU、MMIO三大核心硬件技术,结合 mmap 与 ioremap 两大软件映射机制,拆解它们的功能、演进历程,以及在实际场景中的协同工作原理。 CPU 先通过ioremap把 MMIO 物理地址转为内核虚拟地址,再通过 MMIO 配置网卡的 DMA 参数,将DMA的目标地址填成Step2的物理地址。 mmap和ioremap是操作系统中用于将物理资源映射到虚拟地址空间的两个核心机制,但它们的目标、使用场景和调用者是不同的。 2.ioremap() ioremap是一个内核函数,仅由内核驱动程序调用,用于将设备的物理内存(MMIO区域) 映射到内核的虚拟地址空间。 (2)驱动在初始化时调用ioremap(phys_addr, size)。 (3)内核在其虚拟地址空间找一段空闲的虚拟地址,并建立该虚拟地址到设备物理地址的页表映射。 (4)函数返回一个内核虚拟地址。

    1.1K10编辑于 2025-12-16
  • 来自专栏linux驱动个人学习

    高端内存映射之kmap_atomic固定映射--Linux内存管理(二十一)

    start_kernel()->setup_arch()->early_ioremap_init() 然后arm和arm64上early_ioremap_init又是early_ioremap_setup 的前端 函数 x86 arm arm64 early_ioremap_init arch/x86/mm/ioremap.c? v=4.7, line 445 arch/arm/mm/ioremap.c?v=4.7, line 489 arch/arm64/mm/ioremap.c? v=4.7, line 110 early_ioremap_setup mm/early_ioremap.c? 由于对应于ioremap的内存空间是有限的, 所以对于ioremap空间的使用遵照使用结束马上释放的原则.

    2.9K40发布于 2019-01-03
  • 来自专栏linux驱动个人学习

    /proc/vmalloc

    =7000000 ioremap 0xffffff800800d000-0xffffff800800f000 8192 of_iomap+0x50/0x90 phys=7000000 ioremap +0x0/0x20c user 0xffffff800805a000-0xffffff800805c000 8192 devm_ioremap+0x5c/0xc8 phys=7022000 ioremap ioremap 0xffffff800806a000-0xffffff800806c000 8192 sunxi_i2c_probe+0x1cc/0xaa0 phys=5002000 ioremap =5200000 ioremap 0xffffff8008c22000-0xffffff8008c24000 8192 of_iomap+0x50/0x90 phys=5100000 ioremap 8192 devm_ioremap+0x5c/0xc8 phys=7020000 ioremap 0xffffff8008c46000-0xffffff8008c48000 8192 devm_ioremap

    42730编辑于 2023-11-10
  • 来自专栏LINUX阅码场

    Fixmap机制深入分析

    3.2 fixmap在early ioremap应用介绍 3.2.1 early_ioremap_setup() 该函数的比较简单,主要是依靠__fix_to_virt()给slot_virt[i]填入虚拟地址 3.2.2 __early_ioremap() 有三个数组需要说明: slot_virt[slot]:BTMAP区域各个区间虚拟地址; prev_map[slot]:__early_ioremap()映射后的虚拟地址 ; prev_size[slot]:__early_ioremap()要映射的size; 映射流程如下图6所示: ? Figure 6 early ioremap映射流程图 图7展示了early ioremap页表转换过程,还是比较简单的。 ? 3.3 fixmap在early console应用介绍 Early console的映射与early ioremap的映射类似,通过__fix_to_vit(FIX_EARLYCON_MEM_BASE

    2.2K41发布于 2021-05-31
  • 来自专栏linux驱动个人学习

    devm_xxx机制

    pcim_pin_device() : keep PCI device enabled after release IOMAP devm_ioport_map() devm_ioport_unmap() devm_ioremap () devm_ioremap_nocache() devm_iounmap() devm_ioremap_resource() : checks resource, requests memory region, ioremaps devm_request_and_ioremap() : obsoleted by devm_ioremap_resource() pcim_iomap()

    1.9K20发布于 2019-05-25
  • 来自专栏hank

    在linux内核映射物理地址的简单代码。

    使用request_mem_region和ioremap映射物理地址。 映射之后,可通过虚拟地址读写对应的寄存器。 p_device_info->dev, "xxx_map_mem request_mem_region successed\n"); p_device_info->map_virt_base = ioremap p_device_info->phy_base, XXX_REG_SPACE); return -ENOMEM; } dev_err(p_device_info->dev, "xxx_map_mem ioremap

    2.4K30编辑于 2022-05-09
  • 来自专栏码农爱学习的专栏

    【i.MX6ULL】驱动开发4——点亮LED(寄存器版)

    这就需要用到两个函数:ioremap和iounmap。 ioremap() ioremap函数用将物理地址映射为虚拟地址。 #define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) /** * paddr: 被映射的 IO 起始地址( (phys_addr_t phys_addr, size_t size, unsigned int mtype) { return arch_ioremap_caller(phys_addr, size , mtype, __builtin_return_address(0)); } iounmap() iounmap函数的作用是释放掉ioremap函数所做的映射,即反向操作,在卸载驱动的时候需要调用 = ioremap(SW_PAD_SNVS_TAMPER3_BASE, 4); GPIO5_DR = ioremap(GPIO5_DR_BASE, 4); GPIO5_GDIR = ioremap

    1.2K20发布于 2021-09-29
  • 来自专栏linux驱动个人学习

    Linux-3.14.12内存管理笔记【建立内核页表(3)

    前面已经分析了内核页表的准备工作以及内核低端内存页表的建立,接着回到init_mem_mapping()中,低端内存页表建立后紧随着还有一个函数early_ioremap_page_table_range_init __end_of_permanent_fixed_addresses, /* * 256 temporary boot-time mappings, used by early_ioremap (), * before ioremap() is functional early_ioremap_page_table_range_init()函数再往下的early_ioremap_reset()仅是对after_paging_init全局变量赋值。 最后退出early_ioremap_page_table_range_init()后,init_mem_mapping()调用load_cr3()刷新CR3寄存器,__flush_tlb_all()则用于刷新

    2K11发布于 2019-10-08
  • 来自专栏人人都是极客

    Linux内存初始化(上)

    当然这里固定映射还有些片面,因为在fixmap机制实现上,也有支持动态分配虚拟地址的功能,这个功能主要用于临时fixmap映射(这个临时映射就是用来执行early ioremap使用的。) fixmap区之early ioremap: 对于一些硬件需要在内存管理系统起来之前就要工作的,我们就可以使用这种机制来映射内存给这些硬件driver使用。 各个模块在使用完early ioremap的地址后,需要尽快把这段映射的虚拟地址释放掉,这样才能反复被其他模块继续申请使用。 early_ioremap_init会调用early_ioremap_setup: ? 可见它的实现是依赖fixmap的,所以它必须要在early_fixmap_init之后才能运行。 至此我们已经知道dtb和early ioremap都是在fixmap区的,如下图: ?

    3.1K31发布于 2020-06-29
  • 来自专栏人人都是极客

    Linux的内存初始化

    当然这里固定映射还有些片面,因为在fixmap机制实现上,也有支持动态分配虚拟地址的功能,这个功能主要用于临时fixmap映射(这个临时映射就是用来执行early ioremap使用的。) fixmap区之early ioremap: 对于一些硬件需要在内存管理系统起来之前就要工作的,我们就可以使用这种机制来映射内存给这些硬件driver使用。 各个模块在使用完early ioremap的地址后,需要尽快把这段映射的虚拟地址释放掉,这样才能反复被其他模块继续申请使用。 early_ioremap_init会调用early_ioremap_setup: ? 可见它的实现是依赖fixmap的,所以它必须要在early_fixmap_init之后才能运行。 至此我们已经知道dtb和early ioremap都是在fixmap区的,如下图: ?

    3.4K21发布于 2019-05-17
  • 来自专栏人人都是极客

    嵌入式Linux系统是如何管理IO端口以及IO内存的呢?老司机给你讲讲

    “ 六、Linux下访问IO内存请输入标题 IO内存的访问方法是:首先调用request_mem_region()申请资源,接着将寄存器地址通过ioremap()映射到内核空间的虚拟地址,之后就可以Linux 设备访问编程接口访问这些寄存器了,访问完成后,使用ioremap()对申请的虚拟地址进行释放,并释放release_mem_region()申请的IO内存资源。 要映射的空间的大小; flags:要映射的IO空间的和权限有关的标志; 功能:将一个I/O地址空间映射到内核的虚拟地址空间上(通过release_mem_region()申请到的) 流程如下: “ 七、ioremap 这样portio的64k空间就被映射到虚拟地址的64k~128k之间,而ioremap返回的虚拟地址则肯定在3G之上。ioport_map函数的目的是试图提供与ioremap一致的虚拟地址空间。 外设IO寄存器地址统一编址的CPU,这时应该称外设IO寄存器为IO内存,访问IO寄存器可通过ioremap将其映射到虚拟地址空间,然后再使用read/write接口访问。

    2.4K21发布于 2021-01-07
  • 来自专栏嵌入式与Linux那些事

    11.LCD驱动

    gpbcon = ioremap(0x56000010, 8); gpbdat = gpbcon+1; gpccon = ioremap(0x56000020, 4); gpdcon = ioremap (0x56000030, 4); gpgcon = ioremap(0x56000060, 4); *gpccon = 0xaaaaaaaa; /* GPIO管脚用于VD[7:0],LCDVF lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs)); /* bit[17:8]: VCLK = HCLK / [(CLKVAL+1) x 2

    92340发布于 2021-05-20
  • 来自专栏Linux驱动

    3.修改第一个程序来点亮LED

    在上一节中已经将驱动程序框架搭建好了 接下来开始写硬件的操作(控制LED): (1)看原理图,确定引脚 (2)看2440手册 (3)写代码(需要使用ioremap()函数映射虚拟地址,在linux中只能使用虚拟地址 volatile unsigned long *GPFcon=NULL; volatile unsigned long *GPFdat=NULL; 3.2 first_drv_init入口函数中使用ioremap ()映射虚拟地址: GPFcon = ioremap(0x56000050, 16); //ioremap:物理地址映射,返回虚拟地址 GPFdat=GPFcon+1; / minor=MINOR(inode->i_rdev); printk("first_drv_open\n"); //打印,在内核中打印只能用printk() GPFcon = ioremap (0x56000050, 16); //ioremap:物理地址映射,返回虚拟地址 GPFdat=GPFcon+1; //long:32位,所以GPFdat=

    1.1K50发布于 2018-01-03
  • 来自专栏嵌入式项目开发

    Linux下内存空间分配、物理地址与虚拟地址映射

    ioremap与phys_to_virt、virt_to_phys的区别: ioremap是用来为IO内存建立映射的, 它为IO内存分配了虚拟地址,这样驱动程序才可以访问这块内存。 三、​ IO地址空间映射 3.1 ioremap函数 ioremap将一个IO地址空间映射到内核的虚拟地址空间上去,便于访问。 void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) void *ioremap(unsigned 依靠 __ioremap实现,它只是在__ioremap中以第三个参数为0调用来实现. ioremap是内核提供的用来映射外设寄存器到主存的函数,我们要映射的地址已经从pci_dev中读了出来(上一步 3.2 iounmap函数 void iounmap(void *addr) 取消ioremap映射的空间。 3.3 补充说明 1、ioremap 按照页大小进行映射,而且是整页 。

    4.9K31编辑于 2023-01-18
  • 来自专栏linux驱动个人学习

    高端内存映射之vmalloc分配内存中不连续的页--Linux内存管理(十九)

    v=4.7#L14 /* bits in flags of vmalloc's vm_struct below */ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ #define VM_ALLOC 0x00000002 /* vmalloc() */ #define 0x00000080 /* has allocated kasan shadow memory */ /* bits [20..32] reserved for arch specific ioremap internals */ flag标识 描述 VM_IOREMAP 表示将几乎随机的物理内存区域映射到vmalloc区域中. 不同于上述的所有映射方法, ioremap是一个特定于处理器的函数, 必须在所有体系结构上实现. 它可以将取自物理地址空间、由系统总线用于I/O操作的一个内存块,映射到内核的地址空间中.

    3.6K10发布于 2019-01-03
  • 来自专栏菜菜的技术博客

    驱动GPIO操作总结

    resource_size_t n, const char *name, int flags) start: 起始物理地址 n: 映射的字节数 name: 名称字符串 返回值: 成功返回非NULL指针,失败返回NULL ioremap /* asm/io.h */ #define ioremap(cookie, size) __arm_ioremap(cookie, size, MT_DEVICE) void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) phys_addr: 起始物理地址 size: 映射的字节数 request_mem_region(GPJ0DAT_PA, 4, "GPJ0DAT")) return -EBUSY; GPJ0CON_VA = ioremap(GPJ0CON_PA , 4); GPJ0DAT_VA = ioremap(GPJ0DAT_PA, 4); // 销毁动态映射 iounmap(GPJ0CON_VA); iounmap(GPJ0DAT_VA

    1.4K20编辑于 2022-11-15
  • 来自专栏Linux知识

    i.MX283开发板MISC设备驱动——LRADC

    但MMU的另一个功能就是内存映射,就是将一段物理内存映射到一段虚拟内存上,这样实际上就间接的访问了真实的物理内存,这里需要用到两个函数:ioremap 和 iounmap。 #define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) void __iomem *__arm_ioremap(unsigned write_lock(&vmlist_lock); for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { if ((tmp->flags & VM_IOREMAP , tmp->size); } break; } } write_unlock(&vmlist_lock); #endif vunmap(addr); } ioremap (HSADC_CLKCTRL_BASE, 4); hsadc_base = ioremap(HSADC_BASE,0xC0*4);//地址映射 CLKCTRL_FRAC0_BASE = ioremap

    36300编辑于 2025-02-19
  • 来自专栏电子技术研习社

    Linux笔记(13)| 字符设备驱动基础入门

    关于地址映射,实际上有两种方法,一种是静态的,一种是动态的,这里直接调用ioremap函数来实现动态映射。静态映射的优点是效率高,因为在启动内核的时候就已经映射好了,缺点是映射好了就再也不能改变了。 }; int major = 0; static int __init led_init(void) { /* GPIO相关寄存器映射 */ IMX6U_CCM_CCGR1 = ioremap (0x20c406c, 4); SW_MUX_GPIO1_IO04 = ioremap(0x20e006c, 4); SW_PAD_GPIO1_IO04 = ioremap(0x20e02f8 , 4); GPIO1_GDIR = ioremap(0x0209c004, 4); GPIO1_DR = ioremap(0x0209c000, 4); /* 使能GPIO1时钟 */

    2.7K20发布于 2020-08-28
  • 来自专栏嵌入式大杂烩

    【Linux笔记】LED驱动

    我们从函数层面来看,内核给我们提供了ioremap 函数,这个函数可以把物理地址映射为虚拟地址。 这个函数在内核文件arch/arm/include/asm/io.h 中: void __iomem *ioremap(resource_size_t res_cookie, size_t size) 与ioremap函数相对应的函数为: void iounmap (volatile void __iomem *addr) addr:要取消映射的虚拟地址空间首地址。 用结构体进行管理之后,我们就可以用类似下面的方式进行映射: struct GPIO_RegDef *GPIO5 = ioremap(0x20AC000, sizeof(struct GPIO_RegDef

    10.1K32发布于 2020-03-17
领券