passing arguments to a syscall KLD with syscall()

Chris Pressey cpressey at catseye.mine.nu
Fri Dec 3 17:09:18 PST 2004


Hi all,

Apologies in advance if this is common knowledge and I missed it.

I'm writing a small SYSCALL_MODULE KLD, mainly for my own education.  I
can load the module and call the syscall absolutely fine, no problems. 
I'm having problems passing arguments to the syscall, though.

The code is attached - when the syscall is called, it doesn't seem to be
able to get the things I pass to it in syscall(), it gets something else
entirely when it looks at the stuff referenced by the uap pointer.

I noticed the following comment in src/sys/i386/i386/trap.c:

	/* We don't handle the syscall() syscall yet */

I have almost zero familiarity with this code, but if this comment means
what it appears to mean, it might explain why this doesn't work...? 
Anyway, any clarification about what's happening here would be greatly
appreciated.

Thanks,
-Chris
#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>

struct my_args {
	int x;
};

static int
my_syscall(struct my_args *uap)
{
	printf("*** I was passed the integer: %d\n", uap->x);
	return(0);
}

static struct sysent my_sysent = {
	1,				/* sy_narg */
	(sy_call_t *)my_syscall,	/* sy_call */
	NULL				/* sy_abort */
};

static int offset = NO_SYSCALL;

static int
load(struct module *module, int cmd, void *arg)
{
	int error = 0;
	
	switch (cmd) {
	case MOD_LOAD:
		printf("syscall loaded at %d\n", offset);
		break;
	case MOD_UNLOAD:
		printf("syscall unloaded from %d\n", offset);
		break;
	default:
		error = EINVAL;
		break;
	}
	
	return(error);
}

SYSCALL_MODULE(my_syscall, &offset, &my_sysent, load, NULL);

#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/module.h>

#include <stdio.h>
#include <sysexits.h>

int
main(int argc, char **argv)
{
	char *end_ptr;
	int syscall_num, retval;
	struct module_stat stat;

	stat.version = sizeof(stat);
	if (modstat(modfind("my_syscall"), &stat) != 0) {
		err(EX_UNAVAILABLE, "modstat");
	}
	syscall_num = stat.data.intval;
	retval = syscall(syscall_num, 100);
	printf("Return value was: %d\n", retval);
	exit(0);
}
SRCS	= mykld.c
KMOD	= mykld
KO	= ${KMOD}.ko
KLDMOD	= t

. include <bsd.kmod.mk>




More information about the Kernel mailing list