天天看點

建立核心線程

在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,如需轉載請自行聯系原作者

繼續閱讀