驱动开发过程中可能遇到以下几种与内在访问相关的情况:
1.CPU访问设备寄存器:
在ARM中可以直接将设备的寄存器映射到ARM的存储空间中,我们需要使用几个函数将硬件寄存器地址映射到系统空间:
如果已知硬件的虚拟地址,可以使用VirtualAlloc,VirtualCopy,
如果已知硬件的物理地址,需要使用MmMapIoSpace映射.
2.CPU与DMA或其它硬件交换数据。
DMA需要使用物理地址,因为DMA访问内存时不会向CPU一样先经过MMU,所以它使用物理地址。如果硬件需要与CPU交互数据,比如CPU需要将图像画到LCD控制器使用的内存中,LCD才会将其显示出来。我们在设置硬件硬件时需要将CPU使用的虚拟地址转换成物理地址,再告诉硬件物理地址。通常有以下几种办法:
<!--[if !supportLists]-->1. <!--[endif]-->为该硬件保留一块内存空间。一般用于内存使用量比较大的,且地址不再改变的设备,例如LCD控制器。
记录下该块内存的物理地址给硬件使用,计算出该块内存的虚拟地址地址给CPU使用。
<!--[if !supportLists]-->2. <!--[endif]-->当驱动需要访问硬件时才将虚拟地址转换成物理地址,一般用在内存空间经常变化的场合。例如块设备的驱动,文件系统或者其它上层程序读写数据时并不会保证每次使用同一段地址。这种情况下,可以使用LockPages函数将虚拟地址转换成物理地址。
<!--[if !supportLists]-->3. <!--[endif]-->分配一块物理地址,这可以用在内存地址不需要变化,且用量不大的情况,这时可以用AllocPhysMem分配一块地址,同时得到物理地址与虚拟地址。