Friday, November 04, 2005

System call in FreeBSD

Kernel programming is considered a dark art, but writing a system call is in FreeBSD is incredibly simpler than Linux. So here's my quick and dirty, 5 minutes to fame, system call implementation on FreeBSD 4.1. This system call just print Pico Rocks on the terminal :)

Edit /usr/src/sys/kern/syscall.master: I wont explain why i am doing certain things... cuz the code does a wonderful job in doing that. So just go to the end of the file. You will see a lot of system call defined. The first column gives you the system call number. The last sys call on my machine had a syscall number of 363. So add the following line at the end

364 STD POSIX { int sys_pico(void); }

STD means that your system call will always be included in the kernel, which was necessary in my case as I had to enter asynchonously from the top half of the kernel. The function within the curly brackets give you the syscall signature. Also if you system call is named pico(), the signature here has to be sys_pico(). POSIX means that its is POSIX option, well i din really care abt that I just wanted it on my PC and not ported to others... u cud have used BSD or any other options available.

Next run
#make init_sysent.c
in /usr/src/sys/kern directory. This automatically updates init_sysent.c, syscalls.c and syscalls.h.

Now add the following file in /usr/src/sys/kern directory under the name of sys_pico.c:

#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/mount.h>

/*
*The whole BSD kernel is littered with K&R type formatting.
* so i used it too just for uniformity sake...
*/
int
sys_pico(p, v, retval)
struct proc *p;
void *v;
register_t *retval;
{

printf("Pico Rocks\n");
return (0);
}


Now go to /usr/src/sys/conf/files and add the line
kern/sys_pico.c   standard
anywhere u like... since the whole file was arranged in alphabetical order so I inserted it in its correct ordered position. Now recompile the kernel and reboot the machine.

Now the following code snippet calls our sysetm call:

/*test.c*/
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
syscall(364);
return(0);
}

compile the above program using gcc -I /usr/src/sys/sys.
o/p: Pico Rulz ....hoooray
Now of course you might be thinking that why cant i call pico() normally like other system calls. well for that u have to modify a syscall.mk file(or whatever way ur libc's Makefile.inc includes them) and recompile libc. I tried to do it but my libc crashed and I had to reinstall the whole damn thing. The result of reinstallation was so gross that i ended up re-installing my BSD.

Update: Sorry i almost forgot.... dont forget to remake the config file too in the i386/conf directory
 #config GENERIC

No comments:

Post a Comment