My name is albert burbea, I am a driver programmer at my company and Iahve a nasty question
I would like to limit physical memory access to Windows, using the MAXMEM flag in boot.ini, and I would like then to access this memory mapping it as (for example) a PCI card. Do you have any ideas at how can I do it?
The question is : how do I know which is the maximum physical address windows is able to access?
albert again ....
As you may remember, I am trying to hide the upper physical memory from windows and then allocate it to my driver
I succeeded to obatin the top of memory by GlobalMemoryStatus, but now I do not really know how to go on. The problem is that I am working with windriver tools suite (www.jungo.com) and they sugget to do WD_CardRegister with the phys address of the memory and the size. I may obtain 10 Kbytes of memory this way, but if I try something serious (10MBytes), the code crashes
This is waht nalyze -v returns to me:
An attempt was made to access a pagable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 804e6617, address which referenced memory
***** Kernel symbols are WRONG. Please fix symbols to do analysis.
READ_ADDRESS: unable to get nt!MmPoolCodeEnd
unable to get nt!MmSpecialPoolEnd
unable to get nt!MmPagedPoolEnd
unable to get nt!MmNonPagedPoolEnd
unable to get nt!MmNonPagedPoolStart
unable to get nt!MmSpecialPoolStart
unable to get nt!MmPagedPoolStart
unable to get nt!MiSessionPoolStart
unable to get nt!MiSessionPoolEnd
unable to get nt!MmNonPagedPoolExpansionStart
unable to get nt!MmPoolCodeStart
(.reboot is mine)
What went wrong? and how can i bypass this ?
PS. To make is simpler: I need to allocate several tens of megabytes of memory, and have it accessible from kernel. The memory MUST be physically contiguous. If you have any ideas, I will be more than glad to hear
you can write me at firstname.lastname@example.org or email@example.com
From my kernel this is what the assembly looks like when I unassemble that location:
804e6610 8b0485d0065580 mov eax,[nt!MmPageLocationList (805506d0)+eax*4]
804e6617 8b4804 mov ecx,[eax+0x4]
Anyway, MmAllocateContiguousMemory/MmAllocateContiguousMemorySpecifyCache can allocate phyiscally continous memory. There are other APIs that allocate this memory "safe for DMA", AllocateCommonBuffer, which do the same but ensure that the memory can be accessed by both the processor and the DMA controler at the same time. Is there really a difference? Perhaps there could be, it could even just be ensuring that the memory is allocated in a physical address range accessible by DMA or even not consuming from non-paged pool (as the previous APIs do) but from a special pool for DMA buffers. I don't know I haven't looked at those APIs to see what the difference is, could be nothing.
In anycase, you mentioned before that you are reserving the memory above what the OS thinks is the physical limit for your operations. Did you also need to access that memory from the kernel or just the device? Is this the memory you are having a problem with or is it just that you're allocating 10 megabytes of standard non-paged pool and not continous memory?
you are really helpful, thanks
The problem I am trying to solve is as follow:
I need to allocate a HUGE contiguous buffer (> 50 MB< even 100MB sometimes), and I understood that operating system limits this. So, I decided to "hide" memory from it and try to use for my own purposes. So, how do I do this? Any ideas? I am not a device driver developer, I am using a toolkit (Jungo's windriver) that should help with this. The problem with the toolkit is that I am not neither able to allocate the memory I need nor to allocate the same amount all the time. I mean that sometimes my application tries to allocate say 16 MBytes, and succeeds, but nothing assures me that at the next run I will be able to get it.
THank you again for your time.
BTW, if you prefer to call me, or have me call you, send me an email at firstname.lastname@example.org
1. You can't use the memory above what you told the Operating System there was available.
You wanted to tell the OS that the memory above a certain address didn't exist so your device could use it. This is fine if your device is the only one using it. The OS won't map those physical addresses into the page tables if it doesn't know about it. Your driver can't access the memory if it's not mapped into the page tables, unlike the hardware you can't access physical memory directly.
2. Why do you need very large buffers?
Generally what happens is that the buffer sizes are negociated and they are usually several small buffers, say 5 buffers of 64k for example. These are then used in sequence between the hardware and the device drivers. The device driver can fill up 64k of memory and let the device use it while it fills up the next, or vice versa. Applications running in user mode don't access this memory directly either, they usually issue a request to the kernel to recieve these data buffers and the driver then takes the memory and fills up the user's request.
So you should be able to allocate small physically continous amounts of memory. What is the purpose of the large buffer?
we are using a standard network interface card as a frame grabber. We designed a camera with a GigE interface, and recevie the data using the NIC. The problem is that we send sometimes HUGE images (11 MBytes!) and we need it continuous. MOre, the image is preceeded or followed by data. Also, for other reasons, we need to configure the NIC in a way that it should be able to build correctly the image in memory. Of course , we may need SEVERAL buffers like this, and this is the reeason why I need such a huge buffer. I was wandering if I can map the hidden memory as a sort of a "card" in the PC, and then make reads and writes to it.
Anyway, I really need to know the base address of this hidden memory.
Since physical memory is linear, if Windows thinks there's 32 Meg on the system and there's really 64, then you just need to start at the physical offset of 32 megabytes. The following API can be used by devices to map their memory ranges into virtual memory:
I would attempt to give those a read and attempt to experiment with them. I usually don't work directly with hardware so I can't tell you what the pitfalls are going to be. The other alternative, it's just an idea I had, if those don't work would be to just simply create MDL's and modify them yourself to point to your physical memory and attempt to lock them. It may or may not work but MDL's generally just describe physical pages in memory.
Here are MDL functions which you may need to use them anyway for other purposes: MDL Functions[^]
There is something else you may want to know that different types of devices may have their own "API" for mapping device memory to physical memory. Certain drivers have a framework and most of the APIs available to them (such as video and ndis network drivers) are done through calls to functions that are basically wrappers around the system API. Some are direct call through while others do slightly different operation.
The following examples are how VideoPort drivers map AGP and Video memory to physical:
This is just an FYI if you start looking around for ways to map physical to virtual memory. If you are programming for a particular driver framework you may want to check it out to see if it supports physical to virtual memory mapping. Although, again it may not be best to use it if they do something "special" for that device since you are actually mapping RAM and not device memory.
Here's another thought though, if you have a device that requires 10 Megabytes of memory to perform transfers, why not just put 10 Megabytes of memory on that device and then you would have no problems mapping it or reserving it from RAM?
its Albert again...
About your questions:
1. Yes, I need access from both the kernel, the device and the user
2. I need the memory to be continuous - this is because of the data we are receiving.
3. Where is the memory really beginning? I mean, there must be place for PCI boards and other system peripherals in the PC. Where the phys. memory really begins ?
I wrote the Device Drivers for PCI Card in C Language.I used only I/O Mapping only.The driver is working fine.Now i want the same driver to be work in PCI Express Card.so i need to change the code to Memory Mapped I/O.
Can you suggest me how to solve this problem?I am using WindowsXP/Vista/7 Os
First of all i must say sorry about my bad english, but i'll try to mannage
I'm reading your article 4 the drivers.
I have a task to make a driver for a laser and i have problems.
First problem is that this is new 4 me and i've never wrote a driver before.
How do i prepare a picture 4 the driver to understand?
The laser should be able to burn a picture on wood or metal or stone, but how do i prepare the pictures information 4 the driver? How does the procedure go?
This I think is enough 4 the beginning
I'm new at this and may be commpletly ilogic, but i need all the help i can get
I hope that u can help me with this problem.
Looking forward to your reaplay.
Printer drivers are simmilar to display drivers. Most printer drivers these days run in user mode and call Eng* APIs (Which allows the driver to actually run in user mode or kernel mode since both sets of those APIs are available). You should visit MSDN:
I am finding you driver tutorial to be very well written and helpful. I have a question about your first tutorial. I was able to get the driver compiled and was able to load and test it withe the other programs. In order to compile the driver I had to replace the macro call TYPE_ALIGNMENT(char) with the constant 1. If I left the macro in I was getting the following errors:
error C4116: unnamed type definition in parentheses
I built the driver in the XP Free environment and I used the bld and the default makefile along with a simple Sources file.
So excited to talk to you.
Can I ask you some questions?
Since I want to replace the rdpdd.dll which worked well in windows terminal service, could you tell me how can I do and what will I?
I know the display device of one window is determined by the "default Desktop" of the windowstation. Can I change the Desktop's display device?
Or how Can I create a Desktop with special display device just like rdpdd.dll?
I met another problem:it cant work after installed.
Debugger shows (in appmonitor) hFile==NULL:
hFile = CreateFile("c:\\video.dat", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
Could you tell me how to let it work?
Last Visit: 31-Dec-99 18:00 Last Update: 15-Jul-18 11:29