创建内核线程

在Linux中,有一些进程完全运行在内核空间,比如ksoftirqd等等,这些进程称为内核线程。今天,我们就动手创建一个内核线程。

引言:

如果用户层的进程违规访问内存,内核会发送一个SIGSEGV信号给进程。我们的目标就是,创建一个内核线程,如果发生了段错误,就在控制台打印

"myKthread: Segmentation Fault!!!"

系统环境:

CentOS 5.5 i386 + 2.6.18 源码

设计原理:

(1)使用kthread_create创建线程:

  
  
  
  
  1. struct task_struct *kthread_create(int (*threadfn)(void *data),  
  2.  
  3.                                          void *data,  
  4.                                          const char *namefmt, ...);  

这个函数可以像printk一样传入某种格式的线程名
线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。

 在arch/i386/mm/fault.c最前边添加函数
  
  
  
  
  1. static int mykthread(void *data)  
  2. {  
  3.         for(;;)  
  4.         {  
  5.                  printk(KERN_ALERT "myKthread: Segmentation Fault!!!\n");  
  6.                  set_current_state(TASK_INTERRUPTIBLE);  
  7.                  schedule();  
  8.         }  
  9. }  
   

(2)不管是谁访问内存,都会调用到函数do_page_fault,如果是用户层程序,地址合法,就会允许访存,如果违法,就发送SIGSEGV。我们在发送发动信号前唤醒mykthread。
mykthread在第一次段错误时被创建。
 
在arch/i386/mm/fault.c的do_page_fault函数内添加一个静态变量
 
  
  
  
  
  1. static struct task_struct *kt = NULL; 
在force_sig_info_fault(SIGSEGV, si_code, address, tsk);这个语句之前,添加下面的内容
  
  
  
  
  1. if(!kt)  //first time  
  2. {  
  3.      kt = kthread_create(mythread,NULL,"mykthread");  
  4.      if(!kt)  
  5.          printk(KERN_ALERT "create mykthread failed!\n");  
  6.      else 
  7.          wake_up_process(kt);  
  8. }  
  9. else 
  10.      wake_up_process(kt); 

OK.重新编译内核

程序运行结果:

没发生段错误之前

 

运行程序seg_fault

注:

我原先编译的,内容是打印SIGSEGV sent和Segment Fault!

seg_fault代码

  
  
  
  
  1. int main()  
  2.  
  3. {  
  4.  
  5.      *(int*)0 = 1;  
  6.  
  7.      return 0;  
  8.  

 

本文出自 “牛哥的博客” 博客,转载请与作者联系!

你可能感兴趣的:(休闲,SIGSEGV,段错误,内核线程,kthread_create)