OEMAddressTable里定義的映射關系是給ARM MMU用的,是在KernelStart(source code參考wince420private目錄)時建立的,只要WINCE還在跑,就不會解除. OEMAddressTable里的Virtual Addr和Physical Addr是對ARM來說的. 其實對于WINCE,就只能訪問到它的Virtual address. 也就是說,OEMAddressTable里的Virtual address對WINCE 系統來說才是Physical Address.
經過OEMAddressTable映射后的系統的物理地址,在0x80000000~0x9fffffff之間.是caching and buffering的地址,這個地址加上0x20000000,就是它的cache & buffering disabled地址.所有的硬件寄存器的地址都在這個地址段上,受MMU保護的.
上面講的系統的物理地址,從0x80000000~0xbfffffff,在Kernel Mode下都可以直接訪問. ISR是在KERNEL里,也就可以直接訪問這些系統的物理地址.無所謂"因為ISR只能訪問靜態映射的虛擬地址".
上面說過,對于ARM來說,有虛擬地址和物理地址之分,對于WINCE來說,也有虛擬地址和物理地址之分. 可以這么說,ARM的虛擬地址就是WINCE系統的物理地址. 32位的OS總共有4G的虛擬地址空間,WINCE也不例外. 其中,0x00000000~0x80000000是Application Space; 0x80000000~0xffffffff是System Reserved. 系統的物理地址就在System Reserved的這段,只能在KERNEL MODE訪問. 那么,當APPLICATION和DRIVER(都是運行在USER MODE)要訪問這些在System Reserved地址段的硬件寄存器或MEMORY怎么辦呢? 只好再建立一層映射關系,在Application Space里分配一段空間,把它映射到System Reserved里的地址上,這就是VirtualAlloc/Copy和MmMapIoSpace干的事情.
如果你的地址是這樣聲明的: #define RTC_COUNTER *((volatile unsigned *)0x91000000) 那么直接讀寫就可以了,比如: int nRtc = RTC_COUNTER; RTC_COUNTER = nRtc;
否則,可以用: int nRtc = READ_REGISTER_ULONG(0x91000000); WRITE_REGISTER_ULONG(0X91000000, nRtc);
其實這兩種方式的本質是一樣的,都是把地址聲明成某個數據類型,然后就可以直接讀寫了.下面是READ_REGISTER_ULONG()和WRITE_REGISTER_ULONG()的定義: #define READ_REGISTER_ULONG(reg) (*(volatile unsigned long * const)(reg)) #define WRITE_REGISTER_ULONG(reg, val) (*(volatile unsigned long * const)(reg)) = (val)
?
|