Linux内存访问(Liunx驱动3)
1 内存与IO访问
说明:
从操作系统角度内存可分为内存空间和IO空间,对于x86系统存在IO空间,但是对于arm系统只有内存空间.
内存空间,在linux系统中又分为用户内存和内核内存.用户内存在0~3G范围,内核内存在3G~4G范围.用户程序运行在用户内存中,各个用户具有自己的空间,互相不干扰.内核运行在内核内存中,具有固定分配.
内核内存从高向低分为几个部分:保留区,专用页面分配区,高端内存映射区,vmalloc分配区,物理内存映射区.vmalloc分配区与前后区之间有一定的间隔.物理映射区映射物理0~896M的内存,高于此地址的物理内存映射到高端内存映射区。
地址可分为物理地址,总线地址,虚拟地址.
高性能cpu一般具有mmu内存管理单元,其中包括tlb和ttw。tlb是转换旁路缓存,ttw是转换表漫游。当处理器给出地址后,具有mmu的cpu首先会查找tlb,如果没有找到会在ttw中查找,查找到后将地址放入tlb中。
变量:
kmem_cache_t slab缓存结构,用于slab缓存.
struct vma_area_struct vma结构,用于内存空间映射
成员:{
struct mm_struct *vm_mm;
unsigned long vm_strat;//虚拟空间起始地址
unsigned long vm_end;
pgprot_t vm_page_prot;
unsigned long vm_flags;
vm_operations_struct *vm_ops;//操作函数
…
}
struct map_spec 用于静态空间映射.
函数:
kmalloc (size_t size,int flags) flags一般有GFP_KERNEL,GFP_ATOMIC,GFP_DMA等.使用GFP_KERNEL标志会导致阻塞,而使用GFP_ATOMIC不会导致阻塞.
kfree
__get_free_pages(unsigned int flags,unsigned int order)
vmalloc (unsigned long size)
vfree
- slab相关函数,slab是为了提高内存的使用效率,为频繁分配小内存使用而提出的解决方案.kmalloc就是用slab实现的.
kmem_cache_create
kmem_cache_alloc
kmem_cache_free
kmem_cache_destory - 内存池相关函数
mem_pool_create
mem_pool_alloc
mem_pool_free
mem_pool_destory - 低端内存的物理地址与虚拟地址的转换
virt_to_phys
phys_to_virt
virt_to_page
virt_to_bus
bus_to_virt - IO空间访问函数
inb
outb
inw
outw
inl
outl
insb
outsb
insw
outsw
insl
outsl - IO内存空间访问函数
ioremap(unsigned long offset,unsigned long size) 将物理地址映射到虚拟地址
iounremap
ioport_map
ioport_unmap
ioread8 readb
iowrite8 writeb
ioread16 readw
iowrite16 writew
ioread32 readl
iowrite32 writel
request_region
release_region
request_mem_region
release_mem_region - 用于内核空间到用户空间内存映射函数
remap_pfn_range(struct vma_area_struct *,unsigned long start,unsigned long pfn,unsigned long size,pgprot_t prot)//创建页表
remap_page_range(unsigned long start,unsigned long page,unsigned long pagesize,pgprot_t prot)//
mem_map_reserve(unsigned long page)
pgprot_nocached(pgprot_t prot)//将page设置为no cache,一般io空间都要设置为no cache 用户侧:
mmap(void* addr,size_t len,int prot,int flags,int fd,off_t offset)prot:PROT_READ,PROT_WRITE,PROT_EXEC... flags:MAP_SHARE,MAP_PRIVATE,MAP_ANONYMOUS...
munmap(void *addr,int len)
用法:
- io空间
request_region
inb
outb
…
release_region - io内存
request_region
ioport_map
ioread8
iowrite8
….
ioport_unmap
release_region
request_mem_region
ioremap
ioread8
iowrite8
…
iounmap
release_mem_region
2内核空间映射
说明:
可以将内存中的保留页映射到用户空间,保留页是IO空间,或者通过程序设置.
用法:
用户端:
调用mmap函数
mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
…
munmap();内核:
- 实现fileoperations中mmap函数
xx_mmap(struct file *file,struct vm_area_struct *vm)
{
remap_pfn_range(vm,vm->vm_start,vm->vm_pgoff,vm-vm_end-vm->vm_start,vm->vm_page_prot);
vm->vm_ops=xx_vm_ops;
}
sturct vm_operations_struct xx_vm_ops={
.open=xx_open;
.close=xx_close;
}
- 实现fileoperations中mmap函数
实现kmalloc分配内存的映射
xx_init{
share_mem=kmalloc();
for(page=virt_to_page(share_mem);page<virt_to_page(share_mem+BUFFER_SIZE);page++)
mem_map_reserve(page);将mem设置为保留页
}
xx_mmap(struct file*file,struct vm_area_struct *vm)
{
pos=(unsigned long)sheare_mem;
start=vm->vm_start;
while(size>0){
page=virt_to_phys(pos);
remap_page_range(start,page,PAGE_SIZE,PAGE_SHARED);
pos+=PAGE_SIZE;
start+=PAGE_SIZE;
size-=PAGE_SIZE;}
}
xx_exit()
{kfree();
}
3 DMA操作
说明:
dma操作,可能导致cache不一致的情况,所以应当使用dma_alloc_coherent方法申请dma内存.dma的使用类似于中断.
变量:
struct scatterlist
函数:
void *dma_alloc_coherent(struct device*dev,size_t size,dma_addr_t *handler,gfp_t gfp)
dma_free_coherent(struct device*dev,size_t size,void *cpu_addr,gfp_t gfp)
request_dma(unsigned int dmanr,const char*device_id);
free_dma(unsigned int dmanr);
用法:
request_dma()
dma_alloc_coherent
read,write,ioctl
dma_free_coherent
free_dma
Linux内存访问(Liunx驱动3)相关推荐
- 《Linux驱动:DMA直接内存访问》
目录 一.前言 二.DMA传输主体 三.S3c2440上的DMA 3.1 DMA请求源 3.2 DMA状态机 3.3 DMA请求模式 3.4 DMA服务模式 3.5 DMA传输模式 3.6 DMA读写 ...
- Linux如何访问mmio空间,一文读懂Linux下如何访问I/O端口和I/O内存
虽然访问I/O端口非常简单,但是检测哪些I/O端口已经分配给I/O设备可能就不这么简单了,对基于ISA总线的系统来说更是如此.通常,I/O设备驱动程序为了探测硬件设备,需要盲目地向某一I/O端口写入数 ...
- Linux内存管理:NUMA技术详解(非一致内存访问架构)
图片来源:https://zhuanlan.zhihu.com/p/68465952 <Linux内存管理:转换后备缓冲区(TLB)原理> <内存管理:Linux Memory Ma ...
- 驱动开发:蓝屏BSOD 0x3B 内存访问错误
寻找错误的原因每次都是漫长而艰辛的 这次的0x3B错误是内存访问错误,通过windbg我们很容易定位到了错误语句 LONG search(UNICODE_STRING input) {if (path ...
- 内存访问顺序 - part2: 屏障及Linux kernel中屏障的使用
文章目录 屏障是什么 Linux Kernel 中的屏障 Linux 屏障 API 一般的屏障 强制性屏障 SMP 条件屏障 隐式屏障 其他屏障 屏障的开销 未来的文章 本文翻译自 Memory ac ...
- Linux内存技术分析(下)
Linux内存技术分析(下) 五. 内存使用场景 out of memory 的时代过去了吗?no,内存再充足也不可任性使用. 1.内存的使用场景 · page管理 · slab(kmalloc.内存 ...
- Linux内存管理【转】
转自:http://www.cnblogs.com/wuchanming/p/4360264.html 转载:http://www.kerneltravel.net/journal/v/mem.htm ...
- Linux内存管理Linux Memory Management Notes
Linux 内存基础 地址类型 linux内核中有许多种不同的地址类型 用户虚拟地址 用户空间看到的常规地址,通过页表可以将虚拟地址和物理地址映射起来 物理地址 用在cpu和内存之间的地址叫做物理地址 ...
- Linux内核访问外设I O资源的方式
首先介绍一下I/O端口和I/O内存. 1. I/O端口:当一个寄存器或内存位于I/O空间时,称其为I/O端口. 2. I/O内存:当一个寄存器或内存位于内存空间时,称其为I/O内存. 再来看一下I/O ...
最新文章
- python3 for mac_PyCharm for Mac-PyCharm Mac版下载 V2018.3.2-PC6苹果网
- 飞鸽传书下载2013
- python接口自动化(十九)--Json 数据处理---实战(详解)
- 富文本支持粘贴excel表格_Anki插件-OneNote importer(富文本批量导入)
- IBM X3650 M4 主板故障
- Linux Mint开发环境安装整理
- 编写WPF应用程序实现以下功能:定义一个RandomHelp类,该类提供一个静态的GetIntRandomNumber方法,一个静态的GetDoubleRandomNumber方法。
- 恶意软件及反病毒学习总结
- 外推法的matlab程序
- 各国语言名称英文简写对照表
- Linux固件开发 | 几分钟看透GPT分区
- 数据预处理:数据标准化
- 使用python提取所有word文件中的所有图片
- You have not agreed to the Xcode license agreements. You must agree to both license agreements below
- 服装内部条码和服装国标码的区别
- 世上根本没有什么感同身受,只有冷暖自知
- html基础、css基础(前端基础知识入门)
- 面试时如何做自我介绍
- php闭包(匿名函数)中的use用法
- Python学习之selenium库