I need a 200MB image buffer for a data acquisition program running in a KVM-QEMU virtual machine under Centos. However, both CWSDPMI and HDPMI report only 64MB physical memory available. Is this a known problem, or can any DPMI gurus here point me to my next step to resolve this?
Thanks in advance,
Jerry
DPMI in Virtual Machine reports wrong physical memory size?
-
- Posts: 20
- Joined: Jul 17, 2012 18:51
Re: DPMI in Virtual Machine reports wrong physical memory si
Did you double check QEMU is setup to give the vm more than 64MB? This is a good (ubuntu) guide that should also work for CentOS: https://help.ubuntu.com/community/KVM/Managing
Re: DPMI in Virtual Machine reports wrong physical memory si
FWIW
EDIT: Added code to capture the DS and ES selector values on return from the DPMI Get Free Memory Information function and display them. In my tests under the Windows XP NTVDM, HDPMI32, and CWSDPMI both selectors had the same value, indicating that what I refer to as the host buffer is in the program data/stack segment. This makes the copy operation unnecessary, and makes it possible to use the returned EDI value as a pointer to a MEMORY_INFO structure. But since I can’t find any statement in the DPMI spec that requires this to be so, the conservative, simple approach is to do the copy operation.
Edit2: Modified the code to use the SizeOf operator to get the structure size.
Running under the Windows XP NTVDM (on a system with 512MB of memory):
Running under MS-DOS 6.22 + HDPMI32 (same system):
Running under MS-DOS 6.22 + CWSDPMI (same system, from a diskette so no swap file):
http://tenberry.com/dpmi/13.html#02
EDIT: Added code to capture the DS and ES selector values on return from the DPMI Get Free Memory Information function and display them. In my tests under the Windows XP NTVDM, HDPMI32, and CWSDPMI both selectors had the same value, indicating that what I refer to as the host buffer is in the program data/stack segment. This makes the copy operation unnecessary, and makes it possible to use the returned EDI value as a pointer to a MEMORY_INFO structure. But since I can’t find any statement in the DPMI spec that requires this to be so, the conservative, simple approach is to do the copy operation.
Edit2: Modified the code to use the SizeOf operator to get the structure size.
Code: Select all
type MEMORY_INFO
largestAvailableFreeBlockInBytes as integer
maximumUnlockedPageAllocation as integer
maximumLockedPageAllocation as integer
linearAddressSpaceInPages as integer
totalUnlockedPages as integer
freePages as integer
physicalPages as integer
freeLinearAddressSpaceInPages as integer
sizeOfPagingFileInPages as integer
end type
dim as MEMORY_INFO meminfo
dim as integer errorFlag
dim as ushort dataSel, hostSel
asm
push edi
push esi
'' Call the DPMI Get Free Memory Information function.
mov ax, 0x500
int 0x31
jnc 0f
inc DWORD PTR [errorFlag]
jmp 1f
0:
'' ES:EDI = selector:offset of host buffer
mov [dataSel], ds
mov [hostSel], es
push ds
push es
mov ax, ds
push es
pop ds
mov es, ax
push edi
pop esi
lea edi, [meminfo]
''mov ecx, 0x24
mov ecx, sizeof(MEMORY_INFO)
'' ES:EDI = selector:offset of meminfo structure
'' DS:ESI = selector:offset of host buffer
'' Copy host buffer to meminfo structure
rep movsb
pop es
pop ds
1:
pop esi
pop edi
end asm
if errorFlag then
print "ERROR"
else
with meminfo
print "largestAvailableFreeBlockInBytes :";.largestAvailableFreeBlockInBytes
print "maximumUnlockedPageAllocation :";.maximumUnlockedPageAllocation
print "maximumLockedPageAllocation :";.maximumLockedPageAllocation
print "linearAddressSpaceInPages :";.linearAddressSpaceInPages
print "totalUnlockedPages :";.totalUnlockedPages
print "freePages :";.freePages
print "physicalPages :";.physicalPages
print "freeLinearAddressSpaceInPages :";.freeLinearAddressSpaceInPages
print "sizeOfPagingFileInPages :";.sizeOfPagingFileInPages
end with
end if
print
print hex(dataSel,4);"h",hex(hostSel,4);"h"
sleep
Code: Select all
largestAvailableFreeBlockInBytes : 15728640
maximumUnlockedPageAllocation : 3840
maximumLockedPageAllocation : 2913
linearAddressSpaceInPages : 524256
totalUnlockedPages : 2920
freePages : 64278
physicalPages : 130952
freeLinearAddressSpaceInPages : 511929
sizeOfPagingFileInPages : 320143
01AFh 01AFh
Code: Select all
largestAvailableFreeBlockInBytes : 533839872
maximumUnlockedPageAllocation : 130332
maximumLockedPageAllocation : 130332
linearAddressSpaceInPages : 1046256
totalUnlockedPages : 130463
freePages : 130463
physicalPages : 130800
freeLinearAddressSpaceInPages : 1045936
sizeOfPagingFileInPages : -1
00B7h 00B7h
Code: Select all
largestAvailableFreeBlockInBytes : 534446080
maximumUnlockedPageAllocation : 130480
maximumLockedPageAllocation : 130746
linearAddressSpaceInPages : -1
totalUnlockedPages : 130800
freePages : 130746
physicalPages : 130800
freeLinearAddressSpaceInPages : -1
sizeOfPagingFileInPages : 0
00AFh 00AFh
Last edited by MichaelW on Feb 03, 2014 15:48, edited 1 time in total.
-
- Posts: 20
- Joined: Jul 17, 2012 18:51
Re: DPMI in Virtual Machine reports wrong physical memory si
Thanks for that, MichaelW. The results from your code agree with the results from the DPMI.EXE test program that comes with HDPMI:
Booting into MSDOS natively, the total physical memory returned by INT15h is correct, whether using CWSDPMI or HDPMI.
Booting MSDOS inside a QEMU virtual machine, the total physical memory returned by INT15h always tops out at 62.9 MB, regardless of how much memory I have allocated to the VM.
Interestingly, the INT15h Query System Address Map subfunction (AX=E820h) returns a memory map showing the full allocated memory of 320MB, even while subfunction AX=E801h reports a physical memory limit of 62.9MB!
Given that this occurs with either DPMI server, is it reasonable to assume that it is the VM BIOS (SeaBIOS) reporting a physical memory limit of 64MB that is the problem?
My plan at the moment is to write an interrupt handler to intercept the INT15h calls, chain to the existing INT15h handler, and fix the physical memory reported on the fly, unless my queries to the SeaBIOS folks yields some answers. I'll add to this topic with anything I learn.
Booting into MSDOS natively, the total physical memory returned by INT15h is correct, whether using CWSDPMI or HDPMI.
Booting MSDOS inside a QEMU virtual machine, the total physical memory returned by INT15h always tops out at 62.9 MB, regardless of how much memory I have allocated to the VM.
Interestingly, the INT15h Query System Address Map subfunction (AX=E820h) returns a memory map showing the full allocated memory of 320MB, even while subfunction AX=E801h reports a physical memory limit of 62.9MB!
Given that this occurs with either DPMI server, is it reasonable to assume that it is the VM BIOS (SeaBIOS) reporting a physical memory limit of 64MB that is the problem?
My plan at the moment is to write an interrupt handler to intercept the INT15h calls, chain to the existing INT15h handler, and fix the physical memory reported on the fly, unless my queries to the SeaBIOS folks yields some answers. I'll add to this topic with anything I learn.
Re: DPMI in Virtual Machine reports wrong physical memory si
Have you tried probing the memory beyond this 62.9MB limit to see if doing so triggers an exception?
-
- Posts: 20
- Joined: Jul 17, 2012 18:51
Re: DPMI in Virtual Machine reports wrong physical memory si
When I probe the VM memory without DPMI, I get 382MB. No errors of any kind.
I have a protected mode assembly routine that tests all memory locations by setting a flat memory model (not using DPMI), and it has no problems reading and writing all 382MB, and it doesn't change speed as it does so. Using a Freebasic routine to do the same thing, it is fast out to 64MB, then slows down by an order of magnitude. I believe the DPMI is swapping to disk when it hits the erroneous 64MB limit. And given that INT15h is incorrectly reporting 64MB of physical memory, the culprit must be the VM BIOS.
I have a protected mode assembly routine that tests all memory locations by setting a flat memory model (not using DPMI), and it has no problems reading and writing all 382MB, and it doesn't change speed as it does so. Using a Freebasic routine to do the same thing, it is fast out to 64MB, then slows down by an order of magnitude. I believe the DPMI is swapping to disk when it hits the erroneous 64MB limit. And given that INT15h is incorrectly reporting 64MB of physical memory, the culprit must be the VM BIOS.
-
- Posts: 20
- Joined: Jul 17, 2012 18:51
Re: DPMI in Virtual Machine reports wrong physical memory si
Problem solved! The KVM/QEMU virtual machine that comes with Centos 6.4 uses an old version of SEABios (v 0.6). I upgraded it to the latest version (v 1.7) and I'm now getting the correct information from INT15h for the physical memory, and no more swapping by either DPMI.