OS 专栏收录该内容
2 篇文章 0 订阅


           《MINIX on Linux/VMware》 Silvia Figueira – Fall 2007 Lab 3
           《How to Add a New System Call for Minix 3》 Karthick Jayaraman
                            Department of Electrical Engineering & Computer Science  Syracuse University, Syracuse, New York
           《System Call Implementation on Minix 3》  Felipe Caballero
                            Universidad Adolfo Ibá?ez, Santiago de Chile   Sistemas Operativos 2006-Segundo Semestre


Example Specifics

We want to add a system call int foo( long num ) to Minix. The specifics for foo are below:

Function: Print message 'syscall foo( <#> ) called! ' to screen, where <#> is the value of parameter num .
Returns: If num is a long integer greater than 0, do_foo returns 0 . Otherwise, foo fails and returns -1 .

Please note that foo is actually the interface to the system call do_foo that we will implement. Remember, the user calls a library function (in our case foo ). The library function then makes the actual system call (do_foo ).

Step 1: Kernel Modifications

All system calls in Minix correspond to a specific integer, as defined in /usr/include/minix/callnr.h . So, the first thing we should do is associate our new system call to an integer value.

  1. Open /usr/include/minix/callnr.h
  2. Increase the value of NCALLS by one
  3. At the bottom of the document, add the line '#define FOO 78 '. This assigns the value of 78 to our system call foo
  4. At the botton of /usr/src/include/minix/callnr.h, add '#define FOO 78'.
  5. Save changes and exit

Now we must modify the system call tables for FS and PM (file system, process manager).

Lets take care of the system call table in FS first. Since we want to implement this code in PM , we do not want FS to do anything for our system call. However, we will need to add an entry in the FS call table. This is done as follows:

  1. Open /usr/src/servers/fs/table.c
  2. Go to the end of the call_vec array
  3. Add the line no_sys, /* 78 = FOO */ at the end of call_vec
  4. Save and exit

Our new call_vec should look like this:

PUBLIC _PROTOTYPE( int (*call_vec[]), (void) ) = {
no_sys, /* 0 = unused */
do_exit, /* 1 = exit */

/* ... omitted code ... */

do_svrctl, /* 77 = SVRCTL */
no_sys, /* 78 = FOO */

Next we must modify the system call table in PM . Since this is where we want our system call to actually be implemented, we must do the following:

  1. Open /usr/src/servers/pm/table.c
  2. Go to the end of the call_vec array
  3. Add the line do_foo, /* 78 = FOO */ at the end of call_vec
  4. Save and exit

Our new call_vec should look like this:

PUBLIC _PROTOTYPE( int (*call_vec[]), (void) ) = {
no_sys, /* 0 = unused */
do_mm_exit, /* 1 = exit */

/* ... omitted code ... */

do_svrctl, /* 77 = SVRCTL */
do_foo, /* 78 = FOO */


Now that FS and PM know about our new system call, we should implement it. This can be done in a couple of ways, but only one is presented here:

  1. Open /usr/src/servers/pm/misc.c
  2. Add the line #include <stdio.h> with the other #include lines.
  3. Go to the bottom of the file, and add the following code:
PUBLIC int do_foo()
        long num;

      num = m_in.m4_l1;

        if( num > 0 )
printf( "syscall foo( %d ) called!/n", num );
return 0;
return -1;

Now, we should give PM the prototype for our new system call. This is done as follows:

  1. Open /usr/src/servers/pm/proto.h
  2. Go to the /* misc.c */ section (on line 41)
  3. Add the line _PROTOTYPE( int do_foo, (void) );
  4. Save changes and exit

The misc.c section should look like this:

/* misc.c */
_PROTOTYPE( int do_reboot, (void) );
_PROTOTYPE( int do_svrctl, (void) );
_PROTOTYPE( int do_foo, (void) );

At this point, we have made all the necessary kernel modifications. More information on the passing of parameter num from user space to kernel space can be found towards the bottom of this document.

Step 2: Library Modifications

Now we must make a library function call foo() , so that users can call our new do_foo system call. (This is just like how users call the fork() library function call to indirectly call the do_fork system call.) Again, there are multiple ways to do this, but only one is given here.

  1. Open /usr/include/unistd.h
  2. Add _PROTOTYPE( int foo, (long _num) ); at the end of the /* Function Prototypes*/ section (around line 126)
  3. Save and exit

The end of the /* Function Prototypes */ section should look like:

/* Function Prototypes. */
_PROTOTYPE( void _exit, (int _status) );

/* ... omitted code ... */

_PROTOTYPE( int foo, (long _num) );

Now we must create a small user library for our foo function call. This is done as follows:

  1. Create file /usr/src/include/foolib.h
  2. Add the following code:
#include <lib.h> 
#include <unistd.h>

PUBLIC int foo( long _num )
message m;

m.m4_l1 = _num;

return( _syscall( PM_PROC_NR, FOO, &m ) );

This completes all modifications we must make to add the do_foo system call. Please notice the underscores in the variable name!

Recompile Kernel

To compile the kernel, do the following commands in Minix (will take awhile):

  • cd /usr/src/tools/
  • make includes
  • make hdboot
  • sync

Finally, type shutdown and restart Minix. (Note: You might be able to find a faster way to compile the kernel.)

Testing New System Call

Here is some sample test code (foo.c ) that will test to make sure our new system call works properly.

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <foolib.h>
void main( int argc, char* argv )
        long rval1;
        long rval2;

rval1 = foo( -5 );
printf( "called foo( -5 )... rval was %d/n", rval1 );

rval2 = foo( 2 );
printf( "called foo( 2 )... rval was %d/n", rval2 );


This program should output the following:

called foo( -5 )... rval was -1
syscall foo( 2 ) called!
called foo( 2 )... rval was 0
  • 0
  • 0
  • 1
  • 扫一扫,分享海报

请先登录 后发表评论~
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
钱包余额 0