Re: Getting Physical address of a buffer
Re: Getting Physical address of a buffer
- Subject: Re: Getting Physical address of a buffer
- From: Terry Lambert <email@hidden>
- Date: Fri, 6 Aug 2010 20:43:42 -0700
This question gets asked every once in a while: "why do I have to use OS routines to talk to hardware?".
The basic answer is that there's virtual memory, there's wired memory, and then there's physical memory, and all three aren't the same thing.
There are several reasons that an OS that runs its kernel in a virtual address space doesn't want to give you physical address information directly; let's briefly hit the top four on my personal top ten list:
(1) It doesn't want you to depend on the physical page backing a virtual page not being moved on you
Hypothetical situation: suppose you had a device that needed access to a contiguous region of physical memory; for our example, we'll use a Buslogic/Bustek-848 video capture card, which effectively needs to stream into a contiguous region of physical memory because it not only doesn't have enough memory on board for this, it also doesn't have the memory to manage a descriptor pool for your memory in order to do scatter/gather, and it's simpler if it forces you to a page alignment, and so on.
Now you want the video capture card to have that memory, but over time, physical memory in computers becomes fragmented due to how long an allocation can live being wildly variant per memory consumer. What are your choices? Most OS's pick option (A):
(a) Load the/a driver at boot time, and allocate a large physical chunk before memory becomes fragmented; make that memory unavailable for use by the OS, even though you only actually use your BT-848 card but one in 10 times you boot. Everyone suffers.
(b) A hypothetical OS has the ability to defragment physical memory. It does this by taking the physical pages that haven't actually been allocated to physical memory descriptors given to peripheral memory bus devices, including main memory in the kernel, locking out use of the physical page, and moving the virtual mapping to point to a different physical page. For pages for in use data (including kernel data), it copies the data from the old page to the new page; for not-in-use I/O descriptors, it just points to the new page. Virtual memory is the same, but actual physical memory has been defragmented. A large chunk of physically contiguous memory is now available, and can be allocated and deallocated at need. No one suffers.
This is an OS function because the mapping from virtual to physical is an OS function, and because the OS arbitrates who gets to run when, and (hopefully) intermediates the visibility of data between I/O descriptors in the OS, and physical memory buffer descriptors on the device.
(2) You have a device with an insufficient number of address lines
For these devices, you want to preferrentially allocate the physical memory so that it's reachable by the device. The classic example here from the IBM PC world is plugging 16 bit AT bus cards into a 32 bit system, and wanting them to work. For the card to reach the memory it's being asked to DMA to/from, that memory has to be in the low memory (how low depends on how few address lines the card actually has).
The solution in this case is what's called a "bounce buffer": if the memory is in range,it's accessed directly; if not, the communication is "bounced" through a buffer in low memory which *is* reachable by the device.
This is an OS function because there is a very limited range of memory in which you can place a bounce buffer and have it reachable by the device, but you must share this scarce resource with other devices, and the OS must be able to decide whether or not it needs to use the buffer.
(3) You have a device with enough address lines
This is a variant of case 2: instead of allocating bounce buffers, you preferentially place allocations in high memory so that when/if you have another device of type #2 competing for resources, you can stay out of its limited view.
This is an OS function for the same reason #2 is an OS function.
(4) The OS likes to be kept informed of information for its own reasons so it can play tricks behind your back
The tricks themselves don't matter, what matters is that you enable performance and power management winds by following the rules; if you don't follow the rules, and try to avoid the OS interfaces, you also avoid the OS signaling mechanisms that are used to implement these optimization. Unfortunately for you, this is like declaring a variable that is modified out of scope, and not marking it volatile: failure to notify the OS of the nature of your access means the OS gets to do any optimization it wants. For a volatile variable, that may mean not exiting the work loop when the signal handler fires. For a device driver, it generally means a panic in the driver.
-- Terry
On Aug 6, 2010, at 7:02 PM, shailesh jain wrote:
> Thank y'all! Let's see how things work out. ;)
>
> On Fri, Aug 6, 2010 at 12:36 PM, Terry Lambert <email@hidden> wrote:
>> What Shantonu and Mike said.
>>
>> -- Terry
>>
>> On Aug 6, 2010, at 1:47 AM, shailesh jain wrote:
>>> terry ?
>>>
>>> On Thu, Aug 5, 2010 at 11:10 AM, shailesh jain
>>> <email@hidden> wrote:
>>>> Hello again!
>>>> I have a kernel extension (which is not an IOKit driver) that uses
>>>> OSMalloc_ KPI to allocate buffer. I pass in OSMT_DEFAULT so that
>>>> buffers that it returns are wired to memory. I have a use case where
>>>> in I would like
>>>> to get physical address of the first byte of the buffer. I understand
>>>> that buffer will not be contiguous in Physical memory and I am fine
>>>> with that. Do we have such an interface ---
>>>>
>>>> something like: physAddr = virt_to_phys(buffer); // Gives physical
>>>> address of first byte of the buffer
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden