Now, path to the result becomes cleaner, but harder
The main thing to do now – install interrupt handler for NIC. Implemented by BTX vm86 monitor reflects interrupts to vm86 task. So user client application (BTX client) must find which interrupt number is needed (PXE API provides such information), and install handler for it in which call pxe_core_isr().
Installation phase is sophisticated, cause we need to change IDT and client code is executed not in ring 0 as I understand. So, there is SYS_EXEC system call (__exec() ), but according to assembler code there must not be return from code, run by this call, otherwise SYS_EXIT executed. In my case I only need to install handler, and that’s all. If I use __exec(), after IDT modification the only process flow is exit() , or stay forever in ring 0, while PXE related code will be running. The last case is not what I want, cause idea is to save as much boot functionality as possible (and thus to return control to BTX client code).
So, what I need to correctly install interrupt handler? That is the question. If I understand correctly – the one way is to modify btx.S and add another syscall, that allows to install interrupt handler (something like super2user_isr_install(), that installs handler, which calls user defined function in user space.).
Well, there is also another way – use reflected interrupts, and add handler (modify interrupt vector table) in vm86 space. In that case there must be some call to notify user code (not in vm86, but in ring 3) that interrupt occured. That is also needs system call (something like real2user() and user2real() . vm86int() does sequentially pseudocode user2real(), real_call(), real2user(), but it’s needed to be possible to make this code backwards).
I guess, if somebody ever needed installing interrupt handler in BTX client. If I’m understanding all correctly, then first variant with super2user_isr_install() seems better solution than second one.