随想录(在实践中学习kernel代码)

【声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

http://blog.csdn.net/feixiaoxing/article/details/7831852


    记得我在读书的时候,虽然老师也教过操作系统的课程,但是自己的理解却不是很充分,实践部分的内容就更少。对于课程中的内容,比如说中断、互斥、线程、IO等概念常常也是一知半解,没有什么特别深刻的体会。等到毕业后,自己开始花钱买一些国外作者写的书,认识上有了很大的改变,但是自己真正动手写代码、调试的部分还是太少。等到去年的时候,自己开始在pc上面仿真ucos系统的时候,对每一行代码进行单步调试的时候,才真正从本质上理解了系统本身。


    当然,我对很多计算机课程的认识,原来都是基本停留在书本上面。不管是计算机网络、编译原理还是人机界面,书本上的知识点虽然大概也知道些,但是你要说理解得有多透彻却说不上来。等到自己真正阅读了lwip、lua和ftk的相关代码,你才会大呼一声,原来是这么回事,好像也不是很复杂。所以,对于计算机的知识,要想把自己的认识提高一个层次的话,最好的方法就是实践。


    在国内,喜欢研究linux的人很多,但是大多数朋友对linux kenel的理解只是停留在书本上面、视频上面以及ppt上面。真正自己动手做实验、把每一行代码都弄懂弄明白的朋友却不是那么多。其实,和以前相比,现在的linux版本更多、也更稳定,资源也特别丰富。就我个人认为,linux系统是学习计算机最好的系统。因为在这么一个系统上面,没有人帮你,很多的困惑都需要自己去解决,只有去克服一个一个难点,你才能感受到自己确实实在进步。这种进步不是停留在学会了某种配置、安装了某种软件、熟悉了某种环境,而在于你对系统本身的认识更高了,看问题的角度发生改变了。


    在书店里面,介绍linux基本软件开发的书特别多,但是却有很少的书介绍如何在linux进行kernel的学习、编译、调试,哪些调试工具比较合适等等。他们做的就是直接把答案告诉你,至于为什么这样设计,交代的内容却很少。一方面这方面的需求比较少,另外一方面这些知识点有点难度,不易被大家接受。实际上,这里大家存在一个误区,现在的linux kernel开发其实不是那么难,你所需要的其实就是一个pc、一根网线,这样你就获得了学习的全部资源。下面内容主要是介绍给大家如何学习linux kernel,特别是如何在实践中学习。


(1)选择一个合适linux发行版本,我自身选用的版本是CentOS 6,使用非常方便


(2)从www.kernel.org下载kernel代码,学习如何编译linux 内核,其实步骤也不复杂


    a)解压linux内核版本

    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 内核。开始编写hello.c文件,生成模块,利用模块与linux内核函数进行互动

  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);  
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("feixiaoxing");
MODULE_DESCRIPTION("This is just a hello module!\n");

static int __init hello_init(void)
{
    printk(KERN_EMERG "hello, init\n");
        return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_EMERG "hello, exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

    (4)安装elfutils-devel,systemtap安装包,用stap -v *.stp开始分析内核。你要做的就是插入调试点,编写脚本文件,自由分析内核的代码内容,


    a)基础打印

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

probe end{
        printf("hello end!\n")
}

    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. }  
global number

probe begin
{
    number = 0
}

probe timer.ms(5000)
{
    number ++
    printf ("%d\n", number)
}

probe end
{
    number = 0
}

    c)统计syscall调用

  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. }  
global syscalls

function print_top () {

        cnt = 0
        log ("SYSCALL\t\t\tCOUNT")
        foreach ([name] in syscalls-) {
                printf("%-20s  %5d\n",name, syscalls[name])
                if (cnt++ == 20)
                        break
        }

        printf("--------------------------------------\n")
        delete syscalls
}

probe kernel.function("sys_*") {
        syscalls[probefunc()]++

}

# print top syscalls every 5 seconds
probe timer.ms(5000) {
        print_top ()
}

    d)统计schedule函数被调用的次数

  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. }  
global count

probe kernel.function("schedule")
{
    count ++
}

probe begin{
    count = 0
}

probe end{
    printf("count = %d\n", count);
}

    e)打印回调堆栈

  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. }  
global count

probe kernel.function("schedule").return
{
    if(!count)
        print_backtrace()

    count ++
}

probe begin{
    count = 0
}

probe end{
}


    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. }  
global count

probe begin
{
    count = 0
}

probe kernel.function("__switch_to")
{
    if(!count)
    {
        printf("from [%s] to [%s]\n", task_execname($prev_p), task_execname($next_p))
    }

    exit()
}

probe end
{
}

    更多关于systemtap的范例,可以参考《systemtap language reference》这本手册。     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值