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中注冊一下靜態映射表,讓系統可以知道這種映射關系,否則系統根據算出的虛擬地址是訪問不到物理地址的,會出現異常。
轉載于:https://www.cnblogs.com/linhaostudy/p/10772813.html
總結
以上是生活随笔為你收集整理的IO_ADDRESS()的实现【转】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux控制主机风扇转速,怎么调整cp
- 下一篇: java.lang.IllegalSta