• IO_ADDRESS()的实现【转】


    上面我们说了如何去在系统中自己实现一个设置系统寄存器的一个方法,上面归根到底要进行物理地址到虚拟地址的映射

    现在我们就说说IO_ADDRESS()的实现

    #define __REG32ALI(addr)  (*((volatile unsigned long *)((addr) - ALI_REGS_PHYS_BASE + ALI_REGS_VIRT_BASE))
    #define readl(IO_ADDRESS(addr))    (*(volatile unsigned int *)(addr))
    

    两个宏的功能都是一样的,所以对比可得:

    IO_ADDRESS(addr)  <==>  (addr) - ALI_REGS_PHYS_BASE + ALI_REGS_VIRT_BASE
    

    其中的addr都是物理地址,ALI_REGS_PHYS_BASE是System IO基地址,(addr) - ALI_REGS_PHYS_BASE

    就能得到偏移的地址,ALI_REGS_VIRT_BASE是虚拟地址的基地址,这里的虚拟地址其实是DRAM里面的地址,即我们要操作他映射到DRAM里面的地址,我们看看ALI_REGS_VIRT_BASE的定义:

    #define ALI_REGS_PHYS_BASE             	PHYS_SYSTEM 
    #define ALI_REGS_VIRT_BASE             	VIRT_SYSTEM 
    #define VMALLOC_END      0xfffffffff
    #define SIZE_ALIIO		0x60000
    #define VIRT_SYSTEM      (VMALLOC_END - SIZE_ALIIO)
    

    可以看出虚拟地址的基地址是人为划分出的,是VMALLOC_END - SIZE_ALIIO得到的,

    VMALLOC_END是cpu address mapping中给虚拟地址的内核空间划分出的地址区间的末端地址,这个末端地址根据不同cpu的不同而有所不同,SIZE_ALIIO为可以使用的空间大小

    这个宏只是一个工具,是操作静态映射后的宏的一种做法,在使用该宏前,必须已经对该IO地址所在的地址范围做了静态映射,即machine中对函数map_io中注册一下静态映射表,让系统可以知道这种映射关系,否则系统根据算出的虚拟地址是访问不到物理地址的,会出现异常。

  • 相关阅读:
    runloop源代码
    runloop的source
    How an Event Enters a Cocoa Application
    RunLoop主要处理以下6类事件
    NSRunloop总结
    performSelector与objc_msgSend
    iOSUI显示思想
    NSPort与NSRunloop的关系是流与消息调度的关系
    Core Animation 负责将bitmap绑定提交到 GPU-[CALayer _display]
    iOS构建流畅的交互界面--CPU,GPU资源消耗的原因和解决方案
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/10772813.html
Copyright © 2020-2023  润新知