I would say call gates inside of the GDT might be
an optimal solution. Each module could have one
call gate, and this would be passed the function
name/number and any arguments. I agree that
interrupt gates would be rather inefficient, and
I would also say rather unpleasing from an
aesthetic point of view. The protected mode
allows for more integrated ways for modules to
communicate, which are the call gates and shared
memory space.
To maximize efficiency, I plan to implement
shared memory space. An initial function call
would set up this shared region. Both modules
would then have an LDT descriptor mapping the
same memory space. This would be extremely
efficient for file reading/writing, sound output
streaming, network communication, etc. This
address space could be written by both or only
one module.