Yet another week where I have been slowly trying to get Windows 3.11 to progress further. The progress just seems to get slower and slower, this time all the progress I have managed to get done fits within a few lines of ASM code! Here is the part of the code (in the KRNL386.EXE of Windows 3.11) I have been working on, with the problem locations numbered (1., 2. and 3.):
Here are the problems I have been having listed, with the numbers corresponding to the source code above:
- The "system halted" problem I mentioned in the previous blog post happened within the call to the DPMI entry point. I finally found that the problem was caused by Windows 3.11 having the LDT (Local Descriptor Table) in virtual memory. When I some time ago fixed my IDT and GDT tables to support having their base address in virtual memory, I of course should have also fixed the LDT table at the same time, but for some reason I did not. So, what goes around comes around (and bites you!).
- After I implemented the LDT virtual memory support, I got a drop to debugger with an "IRET to lower priviledge!" error message. This was simply a sort of assertion in my protected mode IRET routine, as I had not yet encountered a program that would return from a higher priority level (ring 0) code to lower priority level (ring 3) code using an IRET operation. Windows 3.11 seems to do that, in the built-in DPMI mode change routine. Supporting that needed some coding into the IRET handler, and I also combined my 16-bit and 32-bit IRET handlers into a single routine while I did this. I have been wanting to do that for some time now, as both of those routines are practically the same, they just load either 16-bit or 32-bit values from the emulated x86 stack.
- The next (and current) problem is that Windows 3.11 exits with a message KERNEL: Inadequate DPMI Server. It took me a while to debug where this happens, but in the end I found that it is inside the call numbered 3. above. Windows manages to create an alias descriptor for CS (code segment), and after that it tries to get a vendor-specific DPMI entry point (in this case it wants to make sure it uses Windows' own DMPI code instead of 386Max or Borland 32RTM or some other possibly installed DPMI server). It gives a string "MS-DOS" as input to the DPMI call, but the call returns an error (call not supported). The DMPI server it calls is indeed Windows' own server, so at first I was pretty much at loss as to why it reports it does not support it's own server. After quite a bit of debugging I found out that even though KRNL386.EXE contains the "MS-DOS" string, and it gets loaded to RAM into a correct position, the DPMI server still does not find the string in RAM. For some so far unclear reason the virtual memory page mapping tables have an invalid address for the page where that RAM address should be. I have not yet been able to determine why the page tables change suddenly, as I have determined that initially the value is correct. This is the problem I am currently fighting with.
Rather discouraging seeing that I have only progressed about a dozen ASM opcodes within KRNL386.EXE during the whole week. But I guess I just need to keep debugging the code to see where the problem is, fix that, and then just continue to the next problem...