all the memory it needs, and the plex86 kernel module uses
get_user_pages() from the Linux kernel to get at them and
pin the few that are needed statically (and later up to
a watermark of pages that are needed dynamically).
Guest physical memory pages are now dynamically pinned/unpinned.
For now, I use a hard limit of 4Megs of pinned pages and
a really primitive algorithm to decide which one to unpin
when the limit is reached and one needs to be bumped. Seems
to work. Though I haven't run into the limit yet since I'm using
just a small test program.
and pinning user pages from the plex86 kernel module. The
guest physical memory array is no longer mmap()'d from kernel
space where it used to be allocated.
in the plex86 module and mmap()'ing it into user space (bochs),
to letting bochs malloc() it normally and using the
Linux kernel facility get_user_pages() to get the associated
physical pages and pin them in memory. I only have code for
Linux kernel 2.4.20 and up, as that's the first version to
export the get_user_pages() symbol so modules can use it.
- add int75_handler, for msdos compatbility fpu exception
This handler calls int 2 (nmi). The NMI handler should really be aware
of this and should iret in case of FPU exception (to be implemented)
a region of virtual memory. Now the same one works for getting
the pages of the kernel driver and memory objects allocated via
vmalloc().
Converted to using Linux interfaces to walk the page tables to
get at the physical memory addresses above. The old code was
digging up this info starting with looking at CR3. Linux has
functions/macros to do this, which can handle 2/3-level cases.
Wrapped the page table walk with proper locks. A spin lock
for new Linuxes, a big kernel lock for old ones.
- implementation of the UIP bit using a new timer handler. The one_second_timer()
function only sets the UIP bit and starts the UIP timer. The uip_timer()
function handles the date / time update, the alarm check and finally clears
the UIP bit.
- writing to control register A doesn't change the UIP bit
Here are comments from the anonymous patch author :
I found bug when using the FPU in 16 bit protected
mode. When using the fsave command the 32bit
structures were used instead of the 16bit ones.
It now distinguishes between 16 and 32 bit protected mode
which wasn't the case before.
Now Ultima8 runs fine:)
new experimental stripped-down version of plex86, which is now
a user-code-only VM. I ripped out all the fancy stuff in plex86,
such that under that right conditions, user-code (protection level 3)
can run at near native speeds inside the plex86 VM.
The general idea is that bochs emulates all the initial real-mode code,
and guest kernel code (protection level 0). When it senses the
right conditions (like the context switches to user-code), a shim
is called to execute the guest inside the plex86 VM. All guest-generated
faults/exceptions are then forwarded back to bochs to be handled in
the emulator.
Actually, I'm not yet adding the mods to the bochs code (other than
the shim code which is in a separate file), until I hear that we're
back in a more development mode with bochs after the 2.0 release.
The plex86 subdirectory is really a separate project. It's just more
convenient to co-develop it with bochs for now. Both projects are
currently LGPL, but each should be taken to be a separate project,
and have their own license file. Plex86 (it's only a kernel driver
now) could ultimately be used with other projects, as it's modular.
I talked with Bryce, and we both agreed it's OK to keep plex86 as
a subdir in bochs for now.