cfm5538 阅读(27) 评论(0)
    A.我们首先在内核根目录下添加myDriver驱动目录。

点击(此处)折叠或打开

  1. root@book-desktop:/opt/linux-2.6.32.9.1/drivers# mkdir myDriver
    B.如何将此驱动目录与上一级目录连接起来?那么就需要我们来做一些修改。在驱动目录的上一级目录中,我们找到Makefile文件,然后在在此文件中添加下面代码(最好在自己添加的代码前后加上注释,以便与原有代码区别):

点击(此处)折叠或打开

  1. #
  2. # Makefile for the Linux kernel device drivers.
  3. #
  4. # 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
  5. # Rewritten to use lists instead of if-statements.
  6. #
  7. #myDriver's staring
  8. obj-y += myDriver/
  9. #myDriver's ending
  10. ........
   C.下面修改驱动目录子目录的Kconfig文件:

点击(此处)折叠或打开

  1. #myDriver's staring
  2. source "drivers/myDriver/Kconfig"
  3. #myDriver's ending
  4. endmenu

这条脚本是将myDriver目录中的Kconfig加入到上级目录中的Kconfig中。这样上级目录的Kconfig会引用到myDriver通过这条语句我们也可以体会Kconfig的另一个作用:Kconfig文件将分布在当前目录下各个子目录的Kconfig都集中在自己的Kconfig当中。

通过上述两步修改就会让父目录感知到edsionteDriver的存在了。接下来我们来编写myDriver目录以及其子目录下的各个Kconfig和Makefile文件。首先是myDriver目录下的两个文件配置:

Makefile文件如下:

点击(此处)折叠或打开

  1. #drivers/myDriver/Makefile
  2. #just a test

  3. obj-$(CONFIG_MYDRIVER) += mydriver.o
  4. mydriver-objs := testdelay.o kn_common.o
  5. obj-$(CONFIG_MYDRIVER_USER) +=mydriver_user.o


上面的Makefile文件这里必须注意一点:比如obj-$(CONFIG_MYDRIVER) += mydriver.o这条语句(+=、:=)之间不能有空格,如果有空格的话会有问题,不能生成相应的.o文件。
    D.我们需要用户来选择是否编译mydriver.c,所以需要用CONFIG_MYDRIVER变量来保存选项值。下面两句类似我们一开始在父目录下增加myDriver目录。
Kconfig文件如下:

点击(此处)折叠或打开

  1. #drivers/myDriver/Kconfig

  2. menu "Test myDriver"

  3. config MYDRIVER
  4.         tristate "mydriver test!"
  5. config MYDRIVER_USER
  6.         bool "user-space test"
  7.         depends on MYDRIVER

  8. endmenu
首先menu和endmenu之间代码创建了一个菜单Test myDriver,然后第一条config语句会建立一个名为”mydriver test”的配置菜单,用户在尽享此项目的配置时输入的配置信息(Y,N或M),会存储在config后面的MYDRIVER变量中。而这个变量会直接关系到Makefile文件中是否编译相应的文件。第二个config语句还是创建一个配置菜单的条目,只不过比较特殊的是这个菜单依赖于上面我们创建的菜单“mydriver test”(语法上是MYDRIVER_USER依赖于MYDRIVER)。具体含义是,只有当用户选择配置“mydriver test”时,才会出现下级菜单”user-sapce test”;否则这个下级菜单是不会出现的。

     E.测试
             1、目录结构
           

点击(此处)折叠或打开

  1. |– myDriver
  2. | |– Kconfig
  3. | |– Makefile
  4. | |– testdelay.c
  5. | |– kn_common.c
  6. | |– kn_common.h
Kconfig

点击(此处)折叠或打开

  1. #drivers/myDriver/Kconfig

  2. menu "Test myDriver"

  3. config MYDRIVER
  4.         tristate "mydriver test!"
  5. config MYDRIVER_USER
  6.         bool "user-space test"
  7.         depends on MYDRIVER

  8. endmenu
Makefile

点击(此处)折叠或打开

  1. #drivers/myDriver/Makefile
  2. #just a test

  3. obj-$(CONFIG_MYDRIVER) += mydriver.o
  4. mydriver-objs := testdelay.o kn_common.o
  5. obj-$(CONFIG_MYDRIVER_USER) +=mydriver_user.o

testdelay.c

点击(此处)折叠或打开

  1. #include <linux/sched.h>
  2. #include <linux/timer.h>
  3. #include <linux/jiffies.h>
  4. #include <asm/param.h>
  5. #include <linux/delay.h>
  6. #include "kn_common.h"

  7. MODULE_LICENSE("Dual BSD/GPL");

  8. static void test_short_delay(void);
  9. static void test_delay(void);
  10. static void test_schedule_timeout(void);
  11. static void my_delay_function(unsigned long);

  12. static int testdelay_init(void)
  13. {
  14.     printk(KERN_ALERT "HZ in current system: %dHz loops_per_jiffy=%lu\n", HZ,loops_per_jiffy);

  15.     /* test short delay */
  16.     test_short_delay();

  17.     /* test delay */
  18.     test_delay();

  19.     /* test schedule timeout */
  20.     test_schedule_timeout();

  21.     return 0;
  22. }

  23. static void testdelay_exit(void)
  24. {
  25.     printk(KERN_ALERT "*************************\n");
  26.     print_current_time(0);
  27.     printk(KERN_ALERT "testdelay is exited!\n");
  28.     printk(KERN_ALERT "*************************\n");
  29. }

  30. static void test_short_delay()
  31. {
  32.     printk(KERN_ALERT "jiffies [b e f o r e] short delay: %lu\n", jiffies);
  33.     ndelay(5);
  34.     printk(KERN_ALERT "jiffies [a f t e r] short delay: %lu\n", jiffies);
  35. }

  36. static void test_delay()
  37. {
  38.     /* ????¨?? */
  39.     struct timer_list my_timer;
  40.     init_timer(&my_timer);

  41.     /* ????? */
  42.     my_timer.expires = jiffies + 1*HZ; /* 2??ó±????? */
  43.     my_timer.data = jiffies;
  44.     my_timer.function = my_delay_function;

  45.     /* ?¤???? */
  46.     add_timer(&my_timer);
  47. }

  48. static void my_delay_function(unsigned long data)
  49. {
  50.     printk(KERN_ALERT "This is my delay function start......\n");
  51.     printk(KERN_ALERT "The jiffies when init timer: %lu\n", data);
  52.     printk(KERN_ALERT "The jiffies when timer is running: %lu\n", jiffies);
  53.     printk(KERN_ALERT "This is my delay function end........\n");
  54. }

  55. static void test_schedule_timeout()
  56. {
  57.     printk(KERN_ALERT "This sample start at : %lu\n", jiffies);

  58.     unsigned int i,j,k;
  59.     for(i=1000;i>0;i--)
  60.         for(j=110;j>0;j--);
  61. #
  62.     /* ??2? */
  63.     set_current_state(TASK_INTERRUPTIBLE);
  64.     printk(KERN_ALERT "sleep 2s ....\n");
  65.     schedule_timeout(2*HZ);
  66. #endif
  67.     printk(KERN_ALERT "This sample end at : %lu\n", jiffies);
  68. }

  69. module_init(testdelay_init);
  70. module_exit(testdelay_exit);

kn_common.c

点击(此处)折叠或打开

  1. #include "kn_common.h"

  2. void print_current_time(int is_new_line)
  3. {
  4.     #if 0
  5.     struct timeval *tv;
  6.     struct tm *t;
  7.     tv = kmalloc(sizeof(struct timeval), GFP_KERNEL);
  8. // t = kmalloc(sizeof(struct tm), GFP_KERNEL);

  9.     do_gettimeofday(tv);
  10.     time_to_tm(tv->tv_sec, 0, t);

  11.     printk(KERN_ALERT "%ld-%d-%d %d:%d:%d",
  12.            t->tm_year + 1900,
  13.            t->tm_mon + 1,
  14.            t->tm_mday,
  15.            (t->tm_hour + 8) % 24,
  16.            t->tm_min,
  17.            t->tm_sec);

  18.     if (is_new_line == 1)
  19.         printk(KERN_ALERT "\n");
  20.     
  21.     kfree(tv);
  22.     kfree(t);
  23. #endif
  24. }

kn_common.h

点击(此处)折叠或打开

  1. #include<linux/init.h>
  2. #include<linux/slab.h>
  3. #include<linux/module.h>
  4. #include<linux/kernel.h>
  5. #include<linux/kfifo.h>
  6. #include<linux/time.h>

  7. void print_current_time(int);

        2、编译
            

点击(此处)折叠或打开

  1. root@book-desktop:/opt/linux-2.6.32.9.1# make menuconfig
配置
         Device Drivers  --->    
                Test myDriver  --->
                      mydriver test!
Exit退出保存
make
在drivers/myDriver目录下面是不是可以看到ko文件:

点击(此处)折叠或打开

  1. root@book-desktop:/opt/linux-2.6.32.9.1/drivers/myDriver# ls -l
  2. total 52
  3. -rw-r--r-- 1 root root 8 2014-09-17 15:43 built-in.o
  4. -rw-r--r-- 1 root root 167 2014-09-17 14:26 Kconfig
  5. -rwxr-xr-x 1 root root 587 2014-09-17 15:05 kn_common.c
  6. -rw-r--r-- 1 root root 175 2014-09-17 14:37 kn_common.h
  7. -rw-r--r-- 1 root root 711 2014-09-17 15:43 kn_common.o
  8. -rw-r--r-- 1 root root 165 2014-09-17 15:42 Makefile
  9. -rw-r--r-- 1 root root 36 2014-09-17 15:49 modules.order
  10. -rw-r--r-- 1 root root 3314 2014-09-17 15:49 mydriver.ko
  11. -rw-r--r-- 1 root root 444 2014-09-17 15:43 mydriver.mod.c
  12. -rw-r--r-- 1 root root 1372 2014-09-17 15:43 mydriver.mod.o
  13. -rw-r--r-- 1 root root 2560 2014-09-17 15:49 mydriver.o
  14. -rwxr-xr-x 1 root root 2150 2014-09-17 15:49 testdelay.c
  15. -rw-r--r-- 1 root root 2480 2014-09-17 15:49 testdelay.o
将上面的ko文件烧到目标主机上加载驱动:

点击(此处)折叠或打开

  1. root@Phoenix /root#insmod mydelay.ko
  2. [ 60.200000] HZ in current system: 100Hz loops_per_jiffy=997376
  3. [ 60.210000] jiffies [b e f o r e] short delay: 4294943317
  4. [ 60.220000] jiffies [a f t e r] short delay: 4294943318
  5. [ 60.220000] This sample start at : 4294943318
  6. [ 60.230000] This sample end at : 4294943319
到处整个过程结束。