From: NoEmailAds AT execpc DOT com (Chris Giese) Newsgroups: comp.os.msdos.djgpp Subject: Re: Handle software interrupts with DPMI Date: Tue, 25 Sep 2001 01:50:24 GMT Organization: PROPULSION GROUP References: X-Newsreader: Forte Free Agent 1.11/32.235 Lines: 81 Message-ID: <3bafe2de$0$1528$272ea4a1@news.execpc.com> NNTP-Posting-Host: ebd62d9d.news.execpc.com X-Trace: DXC=^4:E951`Xb:`4SX<0Yf]73ao5L3]O5Wd00ICGTaT\Bl==EV;d7?Dn`=_md?7I3`fA9:\YZeYBnTH 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