日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

在實踐中學(xué)習kernel代碼

 richsky 2012-08-08

記得我在讀書的時候,雖然老師也教過操作系統(tǒng)的課程,但是自己的理解卻不是很充分,實踐部分的內(nèi)容就更少。對于課程中的內(nèi)容,比如說中斷、互斥、線程、IO等概念常常也是一知半解,沒有什么特別深刻的體會。等到畢業(yè)后,自己開始花錢買一些國外作者寫的書,認識上有了很大的改變,但是自己真正動手寫代碼、調(diào)試的部分還是太少。等到去年的時候,自己開始在pc上面仿真ucos系統(tǒng)的時候,對每一行代碼進行單步調(diào)試的時候,才真正從本質(zhì)上理解了系統(tǒng)本身。


    當然,我對很多計算機課程的認識,原來都是基本停留在書本上面。不管是計算機網(wǎng)絡(luò)、編譯原理還是人機界面,書本上的知識點雖然大概也知道些,但是你要說理解得有多透徹卻說不上來。等到自己真正閱讀了lwip、lua和ftk的相關(guān)代碼,你才會大呼一聲,原來是這么回事,好像也不是很復(fù)雜。所以,對于計算機的知識,要想把自己的認識提高一個層次的話,最好的方法就是實踐。


    在國內(nèi),喜歡研究linux的人很多,但是大多數(shù)朋友對linux kenel的理解只是停留在書本上面、視頻上面以及ppt上面。真正自己動手做實驗、把每一行代碼都弄懂弄明白的朋友卻不是那么多。其實,和以前相比,現(xiàn)在的linux版本更多、也更穩(wěn)定,資源也特別豐富。就我個人認為,linux系統(tǒng)是學(xué)習計算機最好的系統(tǒng)。因為在這么一個系統(tǒng)上面,沒有人幫你,很多的困惑都需要自己去解決,只有去克服一個一個難點,你才能感受到自己確實實在進步。這種進步不是停留在學(xué)會了某種配置、安裝了某種軟件、熟悉了某種環(huán)境,而在于你對系統(tǒng)本身的認識更高了,看問題的角度發(fā)生改變了。


    在書店里面,介紹linux基本軟件開發(fā)的書特別多,但是卻有很少的書介紹如何在linux進行kernel的學(xué)習、編譯、調(diào)試,哪些調(diào)試工具比較合適等等。他們做的就是直接把答案告訴你,至于為什么這樣設(shè)計,交代的內(nèi)容卻很少。一方面這方面的需求比較少,另外一方面這些知識點有點難度,不易被大家接受。實際上,這里大家存在一個誤區(qū),現(xiàn)在的linux kernel開發(fā)其實不是那么難,你所需要的其實就是一個pc、一根網(wǎng)線,這樣你就獲得了學(xué)習的全部資源。下面內(nèi)容主要是介紹給大家如何學(xué)習linux kernel,特別是如何在實踐中學(xué)習。


(1)選擇一個合適linux發(fā)行版本,我自身選用的版本是CentOS 6,使用非常方便


(2)從www.kernel.org下載kernel代碼,學(xué)習如何編譯linux 內(nèi)核,其實步驟也不復(fù)雜


    a)解壓linux內(nèi)核版本

    b)cd linux目錄

    c)cp /boot/config-2.6.32-220.el6.i686 .config

    d) make menuconfig

    e)保存,直接exit退出

    f)make bzImage

    g) make modules

    h) make modules_install

    i) make install


    (3) 重啟電腦,開機選用新的linux 內(nèi)核。開始編寫hello.c文件,生成模塊,利用模塊與linux內(nèi)核函數(shù)進行互動

  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3.   
  4. MODULE_LICENSE("GPL");  
  5. MODULE_AUTHOR("feixiaoxing");  
  6. MODULE_DESCRIPTION("This is just a hello module!\n");  
  7.   
  8. static int __init hello_init(void)  
  9. {  
  10.     printk(KERN_EMERG "hello, init\n");  
  11.         return 0;  
  12. }  
  13.   
  14. static void __exit hello_exit(void)  
  15. {  
  16.     printk(KERN_EMERG "hello, exit\n");  
  17. }  
  18.   
  19. module_init(hello_init);  
  20. module_exit(hello_exit);  

    (4)安裝elfutils-devel,systemtap安裝包,用stap -v *.stp開始分析內(nèi)核。你要做的就是插入調(diào)試點,編寫腳本文件,自由分析內(nèi)核的代碼內(nèi)容,


    a)基礎(chǔ)打印

  1. probe begin{  
  2.         printf("hello begin!\n")  
  3. }  
  4.   
  5. probe end{  
  6.         printf("hello end!\n")  
  7. }  

    b)定時打印

  1. global number  
  2.   
  3. probe begin  
  4. {  
  5.     number = 0  
  6. }  
  7.   
  8. probe timer.ms(5000)  
  9. {  
  10.     number ++  
  11.     printf ("%d\n", number)  
  12. }  
  13.   
  14. probe end  
  15. {  
  16.     number = 0  
  17. }  

    c)統(tǒng)計syscall調(diào)用

  1. global syscalls  
  2.   
  3. function print_top () {  
  4.   
  5.         cnt = 0  
  6.         log ("SYSCALL\t\t\tCOUNT")  
  7.         foreach ([name] in syscalls-) {  
  8.                 printf("%-20s  %5d\n",name, syscalls[name])  
  9.                 if (cnt++ == 20)  
  10.                         break  
  11.         }  
  12.   
  13.         printf("--------------------------------------\n")  
  14.         delete syscalls  
  15. }  
  16.   
  17. probe kernel.function("sys_*") {  
  18.         syscalls[probefunc()]++  
  19.   
  20. }  
  21.   
  22. # print top syscalls every 5 seconds  
  23. probe timer.ms(5000) {  
  24.         print_top ()  
  25. }  

    d)統(tǒng)計schedule函數(shù)被調(diào)用的次數(shù)

  1. global count  
  2.   
  3. probe kernel.function("schedule")  
  4. {  
  5.     count ++  
  6. }  
  7.   
  8. probe begin{  
  9.     count = 0  
  10. }  
  11.   
  12. probe end{  
  13.     printf("count = %d\n", count);  
  14. }  

    e)打印回調(diào)堆棧

  1. global count  
  2.   
  3. probe kernel.function("schedule").return  
  4. {  
  5.     if(!count)  
  6.         print_backtrace()  
  7.   
  8.     count ++  
  9. }  
  10.   
  11. probe begin{  
  12.     count = 0  
  13. }  
  14.   
  15. probe end{  
  16. }  


    f)記錄一次進程切換

  1. global count  
  2.   
  3. probe begin  
  4. {  
  5.     count = 0  
  6. }  
  7.   
  8. probe kernel.function("__switch_to")  
  9. {  
  10.     if(!count)  
  11.     {  
  12.         printf("from [%s] to [%s]\n", task_execname($prev_p), task_execname($next_p))  
  13.     }  
  14.   
  15.     exit()  
  16. }  
  17.   
  18. probe end  
  19. {  
  20. }  

    更多關(guān)于systemtap的范例,可以參考《systemtap language reference》這本手冊。    

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多