总线地址、物理地址、虚拟地址相关概念澄清.doc_第1页
总线地址、物理地址、虚拟地址相关概念澄清.doc_第2页
总线地址、物理地址、虚拟地址相关概念澄清.doc_第3页
总线地址、物理地址、虚拟地址相关概念澄清.doc_第4页
总线地址、物理地址、虚拟地址相关概念澄清.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

总线地址、物理地址、虚拟地址相关概念澄清Now, on normal PCs the bus address is exactly the same as the physicaladdress, and things are very simple indeed. However, they are that simplebecause the memory and the devices share the same address space, and that isnot generally necessarily true on other PCI/ISA setups. Now, just as an example, on the PReP (PowerPC Reference Platform), theCPU sees a memory map something like this (this is from memory): 0-2 GB real memory 2 GB-3 GB system IO (inb/out and similar accesses on x86) 3 GB-4 GB IO memory (shared memory over the IO bus)Now, that looks simple enough. However, when you look at the same thing fromthe viewpoint of the devices, you have the reverse, and the physical memoryaddress 0 actually shows up as address 2 GB for any IO master.So when the CPU wants any bus master to write to physical memory 0, it has to give the master address 0x80000000 as the memory address.So, for example, depending on how the kernel is actually mapped on the PPC, you can end up with a setup like this:physical address:0virtual address: 0xC0000000bus address: 0x80000000where all the addresses actually point to the same thing.Its just seen through different translations.Similarly, on the Alpha, the normal translation isphysical address:0virtual address: 0xfffffc0000000000bus address: 0x40000000(but there are also Alphas where the physical address and the bus address are the same).Anyway, the way to look up all these translations, you do #include phys_addr = virt_to_phys(virt_addr); virt_addr = phys_to_virt(phys_addr); bus_addr = virt_to_bus(virt_addr); virt_addr = bus_to_virt(bus_addr);Now, when do you need these?there are actually _three_ different ways of lookingat memory addresses, and in this case we actually want the third, the so-called bus address.Essentially, the three ways of addressing memory are (this is real memory,that is, normal RAM-see later about other details):- CPU untranslated.This is the physical address.Physical address 0 is what the CPU sees when it drives zeroes on the memory bus.- CPU translated address. This is the virtual address, and is completely internal to the CPU itself with the CPU doing the appropriate translations into CPU untranslated.- bus address. This is the address of memory as seen by OTHER devices, not the CPU. Now, in theory there could be many different bus addresses, with each device seeing memory in some device-specific way, but happily most hardware designers arent actually actively trying to make things any more complex than necessary, so you can assume that all external hardware sees the memory the same way.You want the _virtual_ address when you are actually going to access that pointer from the kernel. So you can have something like this: /* * this is the hardware mailbox we use to communicate with * the controller. The controller sees this directly. */ struct mailbox _u32 status; _u32 bufstart; _u32 buflen; . mbox; unsigned char * retbuffer; /* get the address from the controller */ retbuffer = bus_to_virt(mbox.bufstart); switch (retbuffer0) case STATUS_OK: .on the other hand, you want the bus address when you have a buffer that you want to give to the controller: /* ask the controller to read the sense status into sense_buffer */ mbox.bufstart = virt_to_bus(&sense_buffer); mbox.buflen = sizeof(sense_buffer); mbox.status = 0; notify_controller(&mbox);And you generally _never_ want to use the physical address, because you cant use that from the CPU (the CPU only uses translated virtual addresses), and you cant use it from the bus master.So why do we care about the physical address at all? We do need the physical address in some cases, its just not very often in normal code.The physical address is needed if you use memory mappings, for example, because the remap_page_range() mm function wants the physical address of the memory to be remapped.This memory is called PCI memory or shared memory or IO memory or whatever, and there is only one way to access it: the readb/writeb and related functions. You should never take the address of such memory, because there is really nothing you can do with such an address: its not conceptually in the same memory space as real memory at all, so you cannot just dereference a pointer.物理地址与总线地址1)物理地址是与CPU相关的。在CPU的地址信号线上产生的就是物理地址。在程序指令中的虚拟地址经过段映射和页面映射后,就生成了物理地址,这个物理地址被放到CPU的地址线上。2) 总线地址,顾名思义,是与总线相关的,就是总线的地址线或在地址周期上产生的信号。外设使用的是总线地址。3) 物理地址与总线地址之间的关系由系统的设计决定的。在x86平台上,物理地址与PCI总线地址是相同的。在其他平台上,也许会有某种转换,通常是线性的转换。比如:CPU需要访问物理地址是0xfa000的单元,那么在x86平台上,会产生一个PCI总线上对0xfa000地址的访问。这个单元或者是内存中,或者是某个卡上的存储单元,甚至可能这个地址上没有对应的存储器。而在另外一个平台上,或许在PCI总线上产生的访问是针对地址为0x1fa000的单元。Device drivers use ddi_regs_map_setup(9F) to establish mappings between kernel virtual address (kvaddr) and device address space for PIO. A device address space may consist of multiple addressable memory regions. Each region is assigned a register set number, rnumber. ddi_dev_nregs(9F) gives the total number of register sets that a device has.The reg property shows the number of addressable regions exported by the device to the system. ddi_regs_map_setup(9F) uses rnumber to index into the array of registers in the reg property and returns a kvaddr mapped to the region corresponding to rnumber.As mentioned in IEEE 1275 PCI Binding, IEEE 1275 PCI binding makes no specific connection between the entries in the reg property and the configuration registers in PCI configuration space. Driver developers should check the reg property to ensure that the correct rnumber is used in ddi_regs_map_setup(9F).For example, the reg property of /pci1f,4000/scsi3 shown in the example of the PCI SCSI device node properties contains four register sets: one for configuration space, one for I/O space, and two for memory space.The assigned-addresses property has three register sets: one for I/O space, and two for memory space, as shown below. assigned-addresses 81001810 00000000 00000400 00000000 0000010082001814 00000000 00018000 00000000 0000010082001818 00000000 00019000 00000000 00001000reg 00001800 00000000 00000000 00000000 00000000 - rnumber 001001810 00000000 00000000 00000000 00000100 - rnumber 102001814 00000000 00000000 00000000 00000100 - rnumber 202001818 00000000 00000000 00000000 00001000 8); . /* * memp is the kernel virtual address that maps to the device memory space * register number 2, rnumber = 2. */ ddi_dev_regsize(dip, 2, &mem_size); ddi_regs_map_setup(dip, 2, &mem_reg1, 0, mem_size, &endian_attr, &handlep2); . In the example above, mem_reg1 and base_addr2 are referring to the same memory object on the device. mem_reg1 is the kvaddr mapped to the memory object and can be used by the driver to access that memory object.mem_reg1 is allocated from the kernel resources map (kernelmap) and has the value between SYSBASE and SYSEND, as shown in the kernel address map below.base_addr2 contains the value of the base address register for memory space 1. In this example, the value of base_addr2 is 18000. base_addr2 is the physical address of the memory object in the PCI bus address domain. The system uses base_addr2 in ddi_regs_map_setup(9F) to establish mapping between mem_reg1 and rnumber.In the ddi_regs_map_setup(9F) call, the system traverses the device tree all the way up to the root nexus driver to establish mapping between kernel virtual address (for example, mem_reg1) and the device register address space denoted by rnumber. On the way to the root nexus driver, the system calls the PCI nexus driver, the devices parent node, to convert rnumber to a generic register structure that can be used by the root nexus driver. The PCI nexus driver reads the values of the reg property of the device (if the address in the reg property is relocatable, the PCI nexus driver gets the values from the assigned-addresses property) and uses rnumber to index into the array to construct the register structure. Inside the register structure is a field that contains the physical address of the device register in the PCI bus address domain (for example, the value of base_addr2).The system passes the register structure to the root nexus driver. The root nexus driver does three things:Converts the address in the register structure into a physical address (paddr) in the system bus domainAllocates a kvaddr from kernelmapEstablishes a mapping between kvaddr and paddrThe root nexus driver then returns the kvaddr to the device driver. When the kvaddr is accessed, the system generates a memory fault to load the system MMU with the kvaddr-paddr translations. It should be noted that the IOMMU of the HPB is not involved in the translations.Map RegistersWindows Driver Kit: Kernel-Mode Driver ArchitectureMap RegistersDrivers that perform DMA use three different address spaces, as shown in the following figure.Physical, Logical, and Virtual Address MappingsOn any Windows platform, a driver has access to the full virtual address space supported by the processor. On a 32-bit processor, the virtual address space represents four gigabytes. The CPU translates addresses in the virtual address space to addresses in the systems physical address space by using a page table. Each page table entry (PTE) maps one page of virtual memory to a page of physical memory, resulting in a paging operation when necessary. An MDL (memory descriptor list) provides a similar mapping for a buffer associated with driver DMA operations.Devices vary in their ability to access the systems full virtual address space. A device uses addresses in logical (device) address space. Each HAL uses map registers to translate a device or logical address to a physical address (a location in physical RAM). For the device hardware, map registers perform the same function that the MDL (and page table) performs for the software (drivers): they translate addresses to physical memory.Because these address spaces are separately addressed, a driver cannot use a pointer in virtual address space to address a location in physical memory, and vice versa. The driver must first translate the virtual address to a physical address. Similarly, a driver cannot use a logical address to access physical memory. The driver must first translate the address.A HAL must set up adapter objects that support DMA for a wide variety of DMA devices and I/O buses on different computers. For example, most ISA DMA controllers, slave devices, and bus-master devices have insufficient address lines to access the full four-gigabyte system physical address space of a 32-bit processor (or the 64-gigabyte system physical address of an x86 processor running in 36-bit PAE mode). By contrast, PCI DMA devices generally have more than enough address lines to access the full system physical address space in 32-bit processors. Therefore, every HAL provides mappings between the logical address ranges that DMA devices can access and physical address ranges of each computer.Each adapter object is associated with one or more map registers, depending on the amount of data to be transferred and the amount of available memory. During DMA transfers, the HAL uses each map register to alias a device-accessible logical page to a page of physical memory in the CPU. In effect, map registers provide scatter/gather support for drivers that use DMA whether or not their devices have scatter/gather capabilities.The following figure illustrates such a physical-to-logical address mapping for the driver of an ISA DMA device that does not have scatter/gather capabilities.Address Mapping for a Sample ISA DMA DeviceThe previous figure shows the following types of mappings:Each map register maps a range of physical addresses (pointed to by solid lines) to low-order logical addresses (dotted lines) for an ISA DMA device.Here, three map registers are used to alias three paged ranges of data in system physical memory to three page-sized ranges of low-order logical addresses for an ISA DMA device.The ISA device uses the mapped logical addresses to access system memory during DMA operations.For a comparable PCI DMA device, three map registers would also be used for three page-sized ranges of data. However, the mapped logical address ranges would not necessarily be identical to the corresponding physical address ranges, so a PCI device would also use logical addresses to access system memory.Each entry in the MDL maps a location in virtual address space to a physical address.Note the correspondence between a map register and a virtual-to-physical entry in the MDL:Each map register and each virtual entry in an MDL maps at most a full physical page of data for a DMA transfer operation.Each map register and each virtual entry in an MDL might map less than a full page of data. For example, the initial virtual entry in an MDL can map to an offset from the physical page boundary, as shown earlier in the Physical, Logical, and Virtual Address Mappings figure.Each map register and each virtual entry in an MDL maps, at a minimum, one byte.In an IRP requesting a read or write operation, each virtual entry in the opaque-to-drivers MDL at Irp-MdlAddress represents a page boundary in the system physical memory for a user buffer. Similarly, each additional map register needed for a single DMA transfer represents a page boundary in the device-accessible logical address range aliased to system physical memory.On every Windows platform, each adapter object has an associated set of one or more map registers located at a platform-specific (and opaque-to-drivers) base address. From a drivers point of view, the map register base shown in the figure illustrating address mapping for a sample ISA DMA device is a handle for a set of map registers that could be hardware registers in a chip, in a system DMA controller, or in a bus-master adapter, or could even be HAL-created virtual registers in system memory.The number of map registers available with an adapter object can vary for different devices and Windows platforms. For example, the HAL can make more map registers available to drivers that use system DMA on some platforms than on other platforms because the DMA controllers on different Windows platforms have different capabilities.总线地址和物理地址例子分析对于ppc处理器而言,从CPU角度看到的memory和PCI设备角度看到的地址可能不一样,所以virt_to_bus和bus_to_virt定义为:391 /* the local DRAM has a different395* address from the PCI point of view, thus b

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论