Re: Mach RPCs between user space and a kext
On May 18, 2004, at 9:38 PM, Sam Vaughan wrote:
What's not clear to me is how my kext would register the RPC services
it provides with the part of the kernel that accepts the calls from
user space.
There are two methods in which Mach IPC/RPC operates in the kernel. The first method, I'll call it the "active listener method," behaves much like user-state Mach IPC. A kernel thread can wait on a Mach port for a message to arrive, handle it, and reply with a reply message. This method isn't used much in today's kernel (the ux_exception handler thread in BSD behaves this way). The disadvantage of this method is that it requires a thread switch between client and server. But the advantages are that port rights and memory are managed just like at user-space, and it requires "no hookup" into the kernel's IPC object dispatch mechanism. The second method, I'll call it the "passive invocation method," hooks into the middle the Mach IPC implementation for faster (but less "cooked") invocation. Under this method, the Mach IPC implementation determines that the destination is an "IPC kernel object." breaks off its processing of the message just after the "copyin" phase, and invokes the server in the context of the calling thread. As I said, the primary advantage of this method is speed. Only half of a typical IPC operation has been performed (there was a send, but no receive). But for many, the passive nature (tying up and using the user thread to invoke the kernel server) of the call is also an advantage. The disadvantages include having to deal with an "uncooked (e.g. un-received) message. The out-of-line memory is stored in short-hand form (and must be manually "copied-in" to the kernel before you can look at it). The port rights contained in the message are "naked" (i.e. there is no port name, with a set of associated, but managed, rights). Instead, you get a raw pointer to the port and you must manage any rights associated with those ports implicitly. But the biggest disadvantage from your question's perspective is that you must get the port defined as an "IPC kernel object" in the first place. You must "hook it up." There is no mechanism in place for random kernel extensions to "hook up" new IPC kernel objects (they are statically referenced in xnu/osfmk/kern/ipc_kobject.c). So, you must leverage one of the existing IPC kernel objects, or you must use the active listener model. The extensible IPC kernel objects are the IOKit io_connect() and io_service() objects. IOKit provides methods for exporting services using these. But short of using IOKit, there is no way to hook up a "passive" Mach port in a KEXT. That being said - how do you export a port to user-space? Again, IOKit provides a mechanism for doing this (the registry).
Also, what port should the user space code use when it issues the RPC?
The Kernel Programming doc says to look in bootstrap.h, but this file
is empty in Darwin 7.3.0.
What they should have said (I haven't looked it up to be sure), is to look in <servers/bootstrap.h>. But these services aren't available IN the kernel, only outside.
Can anyone point me to some sample code that uses Mach RPC to cross
the user-kernel boundary? The examples in Darwin such as
upl_commit_range() and friends simply call Mach from BSD, which isn't
really relevant to the issues I'm seeing.
Actually, upl_commit_range() is defined in <mach/upl.h> and is published to user-space - although currently unused as a kernel-user boundary interface (until the EMMI gets re-published to user-space, there's not much use for a UPL out there). --Jim [demime 0.98b removed an attachment of type application/pkcs7-signature which had a name of smime.p7s] _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Jim Magee