syscall/sysmsg overview

Joe Talbott josepht at cstone.net
Thu Jun 22 17:46:05 PDT 2006


I've been digging around in the code here:

/usr/src/share/examples/kld/syscall/module

trying to learn more about the new syscall messaging infrastructure.
I realize the code is old and outdated.  I have read the information
available at www.dragonflybsd.org with regard to the new sysmsg work.
I don't quite understand how a sysmsg is constructed or where exactly.
Could someone give me as detailed as possible overview of the code
path from a userland system call to a sysmsg to a kernel function
call.  Any pointers to places in the code I can read to learn more
would also be helpful.  I've looked at /sys/i386/i386/trap.c and the
sys{msg,union,proto}.h header files.

Also any information with regard to adding syscalls via KLD would be a
boon as well.  I have a hacked up version of the example that passes
data from userland to the kernel and back again but I feel this isn't
quite right.  

Joe

Here's a bit of the code:


struct sc_example_args {
#ifdef _KERNEL
        struct sysmsg sysmsg;
#endif
        char *str;
        int val;
        int val2;
        char *ret;
};

int
/*sc_example(struct proc *p, struct sc_example_args *uap)*/
sc_example(struct sc_example_args *uap)
{
        char kstr[1024+1];      /* Holds kernel land copy of uap->str
*/
        char *ret = "from the kernel";
        int err = 0;            /* Generic return(err) */
        int size = 0;

        /*
        * _IMPORTANT_:
        *
        * When one has a contiguous set of data and wish to copy this from
        * userland to kernel land (or vice versa) the copy(9) functions 
        * are recommended for doing this.
        */

        /*
        * Copy the string located at the user land address uap->str to
        * the kernel land address of &kstr.
        */

        uprintf("DEBUG: uap: %p, str: %p, val: %d, val2: %d, ret: %p\n",
                uap, uap->str, uap->val, uap->val2, uap->ret);

#ifdef _KERNEL
        uprintf("DEBUG: uap->sysmsg: %p\n", uap->sysmsg);
#endif

        err = copyinstr(uap->str, &kstr, 1024, &size);
        if (err == EFAULT) 
        {
                uprintf("copyinstr failed\n");
                return(err);
        }


        err = copyout(ret, uap->ret, strlen(ret) + 1);
        uprintf("uap->ret: %p, uap->str: %p, uap->val: %d, uap->val2: %d\n",
                uap->ret, uap->str, uap->val, uap->val2);
        if (err == EFAULT)
        {
                uprintf("copyout failed\n");
                return(err);
        }

        /*
        * Print out the values we have gathered.
        *
        * uprintf() is a kernel land function that acts like printf().
        * When using the printf() in kernel land, it uses the dmesg
        * facility.. uprintf() on the other hand will output directly to 
        * the currently used tty.
        */

        uprintf("The string passed was: %s\n", kstr); 
        uprintf("The value passed was: %d\n", uap->val);
        uprintf("The value passed was: %d\n", uap->val2);
        return(0);
}







More information about the Kernel mailing list