Hi all
these days I'm trying to add 4 new func() to kernel,I use RedHat 8 (Kernel 2.4.18-14) and here is what I did:
Add new syscalls,in /usr/src/linux-2.4.18-14/arch/i386/kernel/entry.S added the names of new sys_calls:
Code:
.long SYMBOL_NAME(sys_evntopen)
.long SYMBOL_NAME(sys_evntclose) 
.long SYMBOL_NAME(sys_evntwait)    
.long SYMBOL_NAME(sys_evntsig)
Then in /usr/src/linux-2.4.18-14/include/asm-i386/unistd.h added sys_calls Number:
Code:
#define __NR_evntopen      259 
#define __NR_evntclose      260
#define __NR_evntwait       261
#define __NR_evntsig         262
of course in this version of kernel, the max number of syscall defined in
/usr/src/linux-2.4.18-14/include/linux/sys.h is 256,so, I edit it as:
Code:
#define NR_syscalls 270
Then is code:

In/usr/src/linux-2.4.18-14/include/linux/wait.h ,added:
Code:
struct evnt_queue   /*define a struct*/
{
  struct evnt_queue *next_event; 
  wait_queue_head_t waitq;
  int eid;
};

extern struct evnt_queue *eq;   /*should it like this be ? the *eq is used below*/
In /usr/src/linux-2.4.18-14/init/main.c added init func():
Code:
#include </linux/wait.h>    /*added #include files*/
#include </linux/mm.h>
#include </linux/slab.h>
......
......

struct evnt_queue *eq;  /*defined in wait.h*/

static void __init event_init(void)  /*init, alloc mem and set the struct-members*/
{
  eq=(struct evnt_queue *)kmalloc(
    sizeof(struct evnt_queue), GFP_KERNEL);
  eq->next_event=NULL;
  eq->eid=0;
  init_waitqueue_head(&(eq->waitq));
}
......
......
asmlinkage void __init start_kernel(void)  
/*this func() is already existed, added the init func() above in the last line*/
{
    ......
     event_init();      /*last line*/
}

In /usr/src/linux2.4.18-14/kernel/sys.c , added 4 new func():
Code:
#include </linux/wait.h>    /*added include*/
#include </linux/mm.h>
#include </linux/slab.h>
......
......
asmlinkage int sys_evntopen(int eid)  /*open an event*/
{
  int newid=-1;
  struct evnt_queue *temp;

 printk("here event opens");
   if (eq==NULL)
  {
    eq=(struct evnt_queue *)kmalloc(
      sizeof(struct evnt_queue), GFP_KERNEL);
    eq->next_event=NULL;
    eq->eid=0;
    init_waitqueue_head(&(eq->waitq));
  }

  temp=eq->next_event;
  if (eid>0)
  {
    while ((temp!=NULL)&&(temp->eid!=eid))
    {
      temp=temp->next_event;
    }
    if ((temp!=NULL)&&(temp->eid==eid)) newid=eid;
  }
  else if (eid==0)
  {
    while (temp!=NULL)
    {
      if (newid<temp->eid) newid=temp->eid;
      temp=temp->next_event;
    }
    newid++;
    if (newid<1) newid=1;
    temp=(struct evnt_queue *)kmalloc(
      sizeof(struct evnt_queue), GFP_KERNEL);
    if (temp==NULL) newid=-1;
    else
    {
      temp->eid=newid;
      temp->next_event=eq->next_event;
      eq->next_event=temp;
      init_waitqueue_head(&(temp->waitq));
    }
  }

  return(newid);
}

asmlinkage int sys_evntclose(int eid)  /*close an event*/
{
  int result=-1;
  struct evnt_queue *prev, *temp;

  printk("here event closes");    /*the error when excecuting comes from here? Why is a NULL pointer ?*/
  prev=eq;
  temp=prev->next_event;
  while ((temp!=NULL)&&(temp->eid!=eid))
  {
    prev=temp;
    temp=prev->next_event;
  }

  if ((temp!=NULL)&&(waitqueue_active(&(temp->waitq))))
    wake_up_interruptible(&(temp->waitq));
  if (temp!=NULL)
  {
    result=0;
    prev->next_event=temp->next_event;
    kfree(temp);
  }

  return(result);
}

asmlinkage int sys_evntwait(int eid)  /*event wait*/
{

  int result=-1;
  struct evnt_queue *temp;

 printk("here event waits");
   temp=eq->next_event;
  while ((temp!=NULL)&&(temp->eid!=eid))
  {
    temp=temp->next_event;
  }

  if (temp!=NULL)
  {
    result=0;
    interruptible_sleep_on(&(temp->waitq));
  }

  return(result);
}

asmlinkage int sys_evntsig(int eid)  /*event signaling*/
{

  int result=-1;
  struct evnt_queue *temp;

  printk("event sig");
  temp=eq->next_event;
  while ((temp!=NULL)&&(temp->eid!=eid))
  {
    temp=temp->next_event;
  }

  if (temp!=NULL)
  {
    result=0;
    wake_up_interruptible(&(temp->waitq));
  }

  return(result);
}
well, re-compile the kernel, and no error appeared, ......
edit a tester named test.c:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <linux/unistd.h>
#include <linux/wait.h>


_syscall1(int, evntopen, int, eid);
_syscall1(int, evntclose, int, eid);
_syscall1(int, evntwait, int, eid);
_syscall1(int, evntsig, int, eid);


void *task_wait(void *eid) /* eventwait */
{
  printf("event %d waiting\n", eid);
  evntwait((int)eid);
  printf("event %d waked up\n", eid);
}


void *task_signal(void *eid) /* eventsig */
{
  printf("event %d signaling\n", eid);
  evntsig((int)eid);
}


int main(int arg, char ** argv)
{
  int i, k, n;
  int eids[10];
  pthread_t tasks[10];

  n=3;  /* open 3 threads */

  for (i=0; i<n; i++)
  {
    eids[i]=evntopen(0);   /* open events */
    if (eids[i]>0) printf("event %d opened\n", eids[i]);
    else printf("event #%d could not open\n", i);
  }

  for (i=0; i<n; i++)
  {
    /* creat threads */
    pthread_create(&tasks[i], NULL, task_wait, (void *)eids[i]);
    sleep(2);
  }

  for (i=n-1; i>=0; i--)
  {
    pthread_create(&tasks[i], NULL, task_signal, (void *)eids[i]);
    sleep(2);
  }

  for (i=0; i<n; i++)
  {
    k=evntclose(eids[i]); /* test eventclose */
    if (k==0) printf("event %d closed\n", eids[i]);
    else printf("event %d could not close\n", eids[i]);
  }

  for (i=0; i<n; i++)
  {
    pthread_join(tasks[i], NULL);
  }

  return(0);
}
compile and excecute:
#cc -o test test.c -lpthread
#./test

error: Segmentation fault
in system log:
Code:
Feb  9 11:30:54 localhost kernel: here event closes<1>Unable to handle 
kernel NULL pointer dereference at virtual address 00000000
Feb  9 11:30:54 localhost kernel:  printing eip:
Feb  9 11:30:54 localhost kernel: c0127de2
Feb  9 11:30:54 localhost kernel: *pde = 00000000
Feb  9 11:30:54 localhost kernel: Oops: 0000
Feb  9 11:30:54 localhost kernel: autofs pcnet32 mii ipt_REJECT 
iptable_filter ip_tables mousedev keybdev input
Feb  9 11:30:54 localhost kernel: CPU:    0
Feb  9 11:30:54 localhost kernel: EIP:    0010:[<c0127de2>]    Not tainted
Feb  9 11:30:54 localhost kernel: EFLAGS: 00010286
Feb  9 11:30:54 localhost kernel:
Feb  9 11:30:54 localhost kernel: EIP is at sys_evntclose [kernel] 0x22 
(2.4.18-2418-14-new-2)
Feb  9 11:30:54 localhost kernel: eax: 00000011   ebx: ca152000   ecx: 
00000001   edx: 00000082
Feb  9 11:30:54 localhost kernel: esi: 00000000   edi: 00000000   ebp: 
ffffffff   esp: ca153fac
Feb  9 11:30:54 localhost kernel: ds: 0018   es: 0018   ss: 0018
Feb  9 11:30:54 localhost kernel: Process test_proj8 (pid: 849, 
stackpage=ca153000)
Feb  9 11:30:54 localhost kernel: Stack: c02510cd ca152000 40012020 bffffb54 
bffffa78 c010910f 00000000 421261e8
Feb  9 11:30:54 localhost kernel:        4212aa68 40012020 bffffb54 bffffa78 
000000f4 0000002b 0000002b 000000f4
Feb  9 11:30:54 localhost kernel:        08048499 00000023 00010282 bffffa70 
0000002b
Feb  9 11:30:54 localhost kernel: Call Trace: [<c010910f>] system_call 
[kernel] 0x33 (0xca153fc0))
Feb  9 11:30:54 localhost kernel:
Feb  9 11:30:54 localhost kernel:
Feb  9 11:30:54 localhost kernel: Code: 8b 1e 85 db 74 2f 39 7b 0c 74 10 8d 
76 00 89 de 8b 1b 85 db
why only evntclose info ?......excecuted evntclose only ?My C is not good and just started Kernel learning......

thanks for any help and info, thanks!!