天天看点

创建内核线程

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

引言:

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

"myKthread: Segmentation Fault!!!"

系统环境:

CentOS 5.5 i386 + 2.6.18 源码

设计原理:

(1)使用kthread_create创建线程:

struct task_struct *kthread_create(int (*threadfn)(void *data),  

                                         void *data,  

                                         const char *namefmt, ...);  

这个函数可以像printk一样传入某种格式的线程名 

线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。

 在arch/i386/mm/fault.c最前边添加函数

static int mykthread(void *data)  

{  

        for(;;)  

        {  

                 printk(KERN_ALERT "myKthread: Segmentation Fault!!!\n");  

                 set_current_state(TASK_INTERRUPTIBLE);  

                 schedule();  

        }  

}  

(2)不管是谁访问内存,都会调用到函数do_page_fault,如果是用户层程序,地址合法,就会允许访存,如果违法,就发送SIGSEGV。我们在发送发动信号前唤醒mykthread。

mykthread在第一次段错误时被创建。

在arch/i386/mm/fault.c的do_page_fault函数内添加一个静态变量

static struct task_struct *kt = NULL; 

在force_sig_info_fault(SIGSEGV, si_code, address, tsk);这个语句之前,添加下面的内容

if(!kt)  //first time  

     kt = kthread_create(mythread,NULL,"mykthread");  

     if(!kt)  

         printk(KERN_ALERT "create mykthread failed!\n");  

     else 

         wake_up_process(kt);  

else 

     wake_up_process(kt); 

OK.重新编译内核

程序运行结果:

没发生段错误之前

运行程序seg_fault

<a href="http://blog.51cto.com/attachment/201111/100451575.png" target="_blank"></a>

<a href="http://blog.51cto.com/attachment/201111/100511920.png" target="_blank"></a>

注:

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

seg_fault代码

int main()  

     *(int*)0 = 1;  

     return 0;  

本文转自nxlhero 51CTO博客,原文链接:http://blog.51cto.com/nxlhero/708885,如需转载请自行联系原作者

继续阅读