From owner-freebsd-questions Tue Sep 26 14: 1:14 2000 Delivered-To: freebsd-questions@freebsd.org Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) by hub.freebsd.org (Postfix) with ESMTP id 151F137B43E for ; Tue, 26 Sep 2000 14:01:02 -0700 (PDT) Received: (from bright@localhost) by fw.wintelcom.net (8.10.0/8.10.0) id e8QKxVV19173; Tue, 26 Sep 2000 13:59:31 -0700 (PDT) Date: Tue, 26 Sep 2000 13:59:31 -0700 From: Alfred Perlstein To: "Yonny Cardenas B." Cc: questions@FreeBSD.ORG Subject: Re: Add a system call Message-ID: <20000926135931.B9141@fw.wintelcom.net> References: <39D10614.9ECD8635@yahoo.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.4i In-Reply-To: <39D10614.9ECD8635@yahoo.com>; from ycardena@yahoo.com on Tue, Sep 26, 2000 at 03:24:52PM -0500 Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG * Yonny Cardenas B. [000926 13:22] wrote: > Hi, > > I have been trying to insert a new system call (very simple), > I have used the steps in the bottom without problems, > but I don't understand the behavior of the program: > > :::::::::::::: > mysyscall.c > :::::::::::::: > int mysyscall( int *n ) { > printf("In the kernel!\n"); > *n = ( *n + 1000); > return 0; > } > > :::::::::::::: > myprog.c > :::::::::::::: > int mysyscall (int * ); > > int main (void){ > int x = 500; > mysyscall(&x); > printf("x= %i\n",x); > } > > The kernel syscall apparently run but it doesn't modify the variable. > > $cc -o miprog miprog.c > $ ./miprog > x= 500 > > In the kernel! <--- is showed in the console. > > If I compile with the function (syscall), it works apparently correctly. > > $cc -o miprog miprog.c mysyscall.c > $ ./miprog > In the kernel! > x= 1500 You can't do that, the kernel and userland address spaces are sorta seperate, you must use copyin/copyout (there's some other stuff like suword and SCARG). Here's what mysyscall needs to look like: int mysyscall(struct proc *p, struct mysyscall_args *uap) { int x; printf("In the kernel!\n"); /* * copy the value from userspace, SCARG just pulls the * field out of the struct pointer (same as uap->x) */ error = copyin(SCARG(uap, x), &x, sizeof(x)); /* * did they give us a messed up pointer that caused us to fail * the copy? (maybe NULL? or just invalid?) */ if (error) return (error); printf("Incrementing!\n"); /* ok they didn't increment what we just got */ x++; printf("Copying back to userland!\n"); /* now try to write it back over the int they gave us */ error = copyout(&x, SCARG(uap, x), sizeof(x)); /* not likely, same thing as copyin, but you never know. */ if (error) return (error); printf("We made it!\n"); /* ok, we're good! */ return (0); } You need to make sure your entry in syscalls.master looks like this: 172 STD BSD { int mysyscall(int *x); } Btw, your code allows the user to specify an arbitrary kernel address that's going to be incremented, if you want to blow the machine up, have your application pass in a NULL pointer and watch the kernel panic.. :) -- -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] "I have the heart of a child; I keep it in a jar on my desk." To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message