zoukankan      html  css  js  c++  java
  • request_mem_region,ioremap 和phys_to_virt()

    转载:

    request_mem_region,ioremap 和phys_to_virt()  

    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内存资源。
           这三个宏的定义如下: 
    #define request_mem_region(start,n,name)   __request_region(&iomem_resource, (start), (n), (name)) 
    #define check_mem_region(start,n)              __check_region(&iomem_resource, (start), (n)) 
    #define release_mem_region(start,n)           __release_region(&iomem_resource, (start), (n)) 
    其中,参数start是I/O内存资源的起始物理地址(是CPU在RAM物理地址空间中的物理地址),参数n指定I/O内存资源的大小。在请求IO内存资源成功后,开始用ioremap进行映射操作。

      

          void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 将一个IO地址空间映射到内核的虚拟地址空间上去,便于访问。入口:phys_addr是要映射的起始的IO地址;size是要映射的空间的大小;flag是要映射的IO空间的和权限有关的标志; 
          实现:对要映射的IO地址空间进行判断,低PCI/ISA地址不需要重新映射,也不允许用户将IO地址空间映射到正在使用的RAM中,最后申请一个 vm_area_struct结构,调用remap_area_pages填写页表,若填写过程不成功则释放申请的vm_area_struct空间;根据虚拟地址和欲映射的物理地址修改页表,之后内核就可以用这个虚拟地址来访问映射的物理地址了。
          对于直接映射的I/O地址ioremap不做任何事情(比如不带MMU的Uclinux中就直接返回物理地址) 。有了ioremap(和iounmap),设备就可以访问任何I/O内存空间,不论它是否直接映射到虚拟地址空间。但是,这些地址永远不能直接使用(像kmalloc返回的地址那样用),而要用readb这种函数。

    /***********************************************************************/

          同样是从物理地址分配得到虚拟地址,还有以下这个函数:phys_to_virt()实际地址转换成虚拟地址,两者是有区别的。ioremap  phys_to_virt 做物理地址于虚拟地址转换发现:

    addr = (unsigned int volatile *)ioremap(0x56000088,12);
    printk(KERN_ALERT"%x ",addr);
    addr = (unsigned int volatile *) phys_to_virt(0x56000088);
    printk(KERN_ALERT"%x ",addr);
    两个函数返回addr值不一样。原因在于:
    (1)在内核中phys_to_virt只是给地址减去一个固定偏移 :
    #ifndef __virt_to_phys
    #define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
    #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
    #endif
    注意:PHYS_OFFSET =0x50000000,在带MMU内核中,PAGE_OFFSET是0xc0000000;不带MMU内核中,与PHYS_OFFSET 同。
    (2)而ioremap()原则就是内核会根据指定物理地址新建映射页表,物理地址虚拟地址关系就由这些页表来搭建!:
    这个从ioremap函数体可以看出来。

    参考原文:http://blog.csdn.net/fuyjlu/archive/2009/12/20/5039782.aspx
    参考原文:http://blog.csdn.net/xdicac/archive/2009/10/30/4743708.aspx

    参考原文:http://blog.csdn.net/unbutun/archive/2009/08/28/4488768.aspx

  • 相关阅读:
    SQL Server设置登录验证模式
    怎样更改SQL Server 2008的身份验证方式
    sqlserver服务器名称改成本地IP地址登录
    零基础学python-2.2 输入 input()
    零基础学python-2.1 输出 print()
    零基础学python-1.7 第二个程序 猜数字小游戏
    零基础学python-1.6 错误的程序
    零基础学python-1.5 第一个程序
    零基础学python-1.4 hello world
    零基础学python-1.3 通过idle启动python
  • 原文地址:https://www.cnblogs.com/FarmPick/p/5629731.html
Copyright © 2011-2022 走看看