一、重点知识
1. linux内存管理机制
linux 2.6.29内核为每种cpu提供统一的界面,采用四级页面管理构架。来兼容二级、三级、四级管理架构的cpu。通过页式管理机制完成虚拟地址(线性地址)到物理地址的映射。一般每个页大小为4k。cr3寄存器中保存了创建进程时分配的值。
linux操作系统采用虚拟内存管理技术,使得每个进程都有独立的进程地址空间,该空间大小是3g,用户看到和接触的都是虚拟地址,无法看到实际的物理地址。利用这种虚拟地址不但能起到保护操作系统的作用,而且更重要的是用户程序可使用比实际物理内存更大的地址空间。
linux将4g的虚拟地址空间划分为两个部分——用户空间与内核空间。用户空间从0到0xbfffffff,内核空间从3g到4g。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间,例外是用户进程通过系统调用访问内核空间。
每个用户空间是完全独立的,互不想干的。用户空间对应进程,所有每当进程切换,用户空间就会跟着变化。
实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会由“请页机制”产生“缺页异常”,从而进入分配实际页框程序。
内核空间是由内核负责映射,它并不会跟着进程改变,是固定的。
物理内存896mb以上的部分称之为高端内存。
2. mmap方法
实现mmap方法,驱动程序只需要为该地址范围建立合适的页表,并将vma->ops替换成一系列的新操作就可以了。
void *mmap(void *addr, size_t len, intprot, int flags, int fd, off_t offset)
内存映射函数,负责把文件内存映射到虚拟内存空间,返回映射地址空间地址。
参数说明:
addr:指定映射的起始地址,通常设为null,由系统指定。
length:映射到内存的文件长度
prot:映射区的保护模式,可以是prot_exec(可执行)、prot_read(可读)、prot_write(可写)。
flag:映射区的特性,可以是
map_shared:写入映射区的数据会复制回文件,且允许其他映射该文件的进程共享。
map_private:对映射区的写入操作会产生一个映射区的复制,对此区域的修改不会写回原文件。
fd:要映射的文件描述符
offet:以文件开始出的偏移量,通常为0,从文件头开始映射。
int munmap(void *start, size_t length)
解除映射。
struct vm_area_struct
内核用来描述虚拟内存区域的结构。
int remap_pfn_range(structvm_area_struct *vma, unsigned long virt_add, unsigned long pfn, unsigned longpfn, unsigned long size, pgprot_t prot)
int io_remap_page_range(structvm_area_struct *vma, unsignde long virt_add, unsigned long phys_add, unsignedlong size, pgprot_t prot)
mmap的核心函数。他们映射了物理地址中从pfn表示的页号开始的size个字节到虚拟地址virt_add上。相关虚拟地址的保护位在port中指定。如果目标地址在i/o地址空间的话,使用io_remap_page_range函数。
二、驱动代码
staticintmem_mmap(structfile*filp,structvm_area_struct*vma)
{
intret=0;
structmem_dev*dev;
dev=filp->private_data;
ret=remap_pfn_range(vma,vma->vm_start,virt_to_phys(dev->data)>>page_shift,vma->vm_end-vma->vm_start,vma->vm_page_prot);//建立页表
if(ret)
return-eagain;
returnret;
}
staticconststructfile_operationsmem_fops={
.owner=this_module,
.open=mem_open,
.write=mem_write,
.read=mem_read,
.release=mem_release,
.llseek=mem_llseek,
.ioctl=mem_ioctl,
.poll=mem_poll,
.mmap=mem_mmap,
};
staticint mem_mmap(struct file *filp, struct vm_area_struct *vma){intret = 0;structmem_dev *dev;dev= filp->private_data;ret = remap_pfn_range(vma,vma->vm_start, virt_to_phys(dev->data)>>page_shift, vma->vm_end- vma->vm_start, vma->vm_page_prot); //建立页表if(ret)return-eagain;returnret;}static const struct file_operationsmem_fops = {.owner= this_module,.open= mem_open,.write= mem_write,.read= mem_read,.release= mem_release,.llseek= mem_llseek,.ioctl= mem_ioctl,.poll= mem_poll,.mmap= mem_mmap,};
iOS10.2和iOS10.3验证通道秒关内幕曝光!还不快升级到iOS10.3.1/iOS10.3.2
超威集团:铅酸蓄电池不会被锂电取代
韩国交易所Cashieres因内部系统出现错误影响了用户提币
陈清泰:前景可期,但中国电动汽车绝不能掉以轻心
没有技术的无奈!美光垄断案硬是成了晋华窃取技术案
驱动之路-内存管理机制及mmap方法
汇顶科技供货不及之困,供应资源之争
加密货币领域当今缺少的是分散式托管协议
某一资讯产品韩国KC市场准入辐射整改案例
工业控制系统是工业信息化中的“神经中枢”
支付宝dummy是什么意思
诺基亚前CEO讲述诺基亚的盛衰往事
汽车鲨鱼鳍气密性防水检测的案例
为什么要使用瘦肉精检测仪
浅析ADAS域控制器技术
关于国内的氮化镓供应商介绍
华北工控推出基于Intel Cedar Trail的嵌入式主板EMB-3930
谷歌云平台宣布了云AI平台管道的测试版推出
DIY设计高辐射X射线光机案例
奥运奖牌揭秘 伦敦奥运会铜牌成本价不到30块