Mail Archives: djgpp/2001/09/24/22:04:00
Eli Zaretskii <eliz AT is DOT elta DOT co DOT il> wrote:
>On Mon, 24 Sep 2001, Chris Giese wrote:
>
>> Suppose I want to write a DOS (DPMI) program to run Linux apps.
>> This program must handle the Linux syscalls (INT 80h).
>
>You might wish to think again. You will need to emulate those system
>calls with the functionality available to DJGPP programs on DOS or
>Windows. However, some (many?) of the important calls have no
>equivalent, and cannot be emulated. For example, page-level
>protection, signals, threading, and other important components of a
>Linux executable--all these need system calls you have no hope
>emulating.
Then I will try to write an emulator for my own OS, which is
much more primitive than Linux. I can delete the parts of the
API that I can't emulate, put the tasks in relocatable format
(ld -r --no-undefined ...) so I don't have to worry about
paged memory management, etc.
>> I can write a DJGPP program that issues and handles software
>> interrupts, but how do I get the values of the registers
>> when the INT instruction occured?
>
>The way to do this with DJGPP programs is to install a handler for
>protected-mode software Int 80h. See the documentation of the library
>function __dpmi_set_protected_mode_interrupt_vector, and the related
>sections of the DPMI Spec.
I read through the DPMI 0.9 spec and a bunch of DJGPP demo code,
but I didn't find what I wanted. Maybe I have a mental block...
Here is a portion of my code:
/* For now, syscall_int() just does a hex dump of the stack.
I want to see 'A', 'B', 'C' etc. on the stack -- these are
the register values at the time of the INT instruction */
static void syscall_int(int the_stack)
{ dump((unsigned char *)&the_stack, 512); }
int main(void)
{ _go32_dpmi_seginfo old_syscall_vector, new_vector;
/* save old vector */
_go32_dpmi_get_protected_mode_interrupt_vector(SYSCALL_VECT,
&old_syscall_vector);
/* install new handler */
new_vector.pm_selector = _my_cs();
new_vector.pm_offset = (unsigned long)syscall_int;
_go32_dpmi_allocate_iret_wrapper(&new_vector);
_go32_dpmi_set_protected_mode_interrupt_vector(SYSCALL_VECT,
&new_vector);
/* make a system call */
__asm__ __volatile__(
"int %0\n"
:
: "i"(SYSCALL_VECT),
"a"(0x41), /* EAX='A' */
"b"(0x42), /* EBX='B' */
"c"(0x43), /* ECX='C' */
"d"(0x44), /* EDX='D' */
"S"(0x45), /* ESI='E' */
"D"(0x46)); /* EDI='F' */
...
This code doesn't segfault, and the handler gets called
(I can see the hex dump of the stack), but I don't see
the register values I'm looking for...
>The problem with this is that an interrupt handler might be limited in
>what it can and cannot do, including in the (DOS/Windows) system calls
>it can safely invoke, and the amount of stack it can depend upon.
So, unless I write my own DOS extender, I'm doomed?
--
geezer@ | http://www.execpc.com/~geezer/osd
execpc.com | http://www.execpc.com/~geezer/os
- Raw text -