Welcome to Linux Forums! With a comprehensive Linux Forum, information on various types of Linux software and many Linux Reviews articles, we have all the knowledge you need a click away, or accessible via our knowledgeable members.
Write an article for LinuxForums Today! Win Great Prizes!
Find the answer to your Linux question:
New to Linux Forums? Register here for free!
    Linux Forums > GNU Linux Zone > The Linux Kernel > Problems in Adding new kernel func()--Segmentation fault

Forgot Password?
 The Linux Kernel   Compiling, theory, programming or other discussion about the linux kernel

Site Navigation
Linux Articles
Linux Forums
Linux Downloads
Linux Hosting
Free Magazines
Job Board
IRC Chat
RSS Feeds
Linux Forum Topics
Linux Forums
Your Distro
Linux Resources
GNU Linux Zone
The Community
Reply
 
Thread Tools Display Modes
Old 02-09-2006   #1 (permalink)
Just Joined!
 
Join Date: Feb 2006
Posts: 1
Problems in Adding new kernel func()--Segmentation fault

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!!
redlar is offline  



Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Free Magazines
A Newbie's Getting Started Guide to Linux
Learn the basics of the Linux operating systems. Get to know what it is all about, and familiarize yourself with the practical side. Basically, if you're a complete Linux newbie and looking for a quick and easy guide to get you started this is it.
subscribe
Run Your Own Web Server Using Linux & Apache - Free 191 Page Preview
Learn about everything you'll need to build and maintain your Linux servers, and to deploy Web applications to them.
subscribe
Open Source Security Myths Dispelled
Dispel the five major myths surrounding Open Source Security and gain the tools necessary to make a truly informed decision for your IT organization
subscribe
InformationWeek
InformationWeek is the only newsweekly you'll need to stay on top of the latest developments in information technology.
subscribe



All times are GMT. The time now is 03:45 AM.






© 2000 - - All Rights Reserved - Property of  MAS Media

Content Relevant URLs by vBSEO 3.3.1