A.我们首先在内核根目录下添加myDriver驱动目录。
-
root@book-desktop:/opt/linux-2.6.32.9.1/drivers# mkdir myDriver
B.如何将此驱动目录与上一级目录连接起来?那么就需要我们来做一些修改。在驱动目录的上一级目录中,我们找到Makefile文件,然后在在此文件中添加下面代码(最好在自己添加的代码前后加上注释,以便与原有代码区别):
-
#
-
# Makefile for the Linux kernel device drivers.
-
#
-
# 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
-
# Rewritten to use lists instead of if-statements.
-
#
-
#myDriver's staring
-
obj-y += myDriver/
-
#myDriver's ending
-
........
C.下面修改驱动目录子目录的Kconfig文件:
-
#myDriver's staring
-
source "drivers/myDriver/Kconfig"
-
#myDriver's ending
-
endmenu
这条脚本是将myDriver目录中的Kconfig加入到上级目录中的Kconfig中。这样上级目录的Kconfig会引用到myDriver通过这条语句我们也可以体会Kconfig的另一个作用:Kconfig文件将分布在当前目录下各个子目录的Kconfig都集中在自己的Kconfig当中。
通过上述两步修改就会让父目录感知到edsionteDriver的存在了。接下来我们来编写myDriver目录以及其子目录下的各个Kconfig和Makefile文件。首先是myDriver目录下的两个文件配置:
Makefile文件如下:
-
#drivers/myDriver/Makefile
-
#just a test
-
-
obj-$(CONFIG_MYDRIVER) += mydriver.o
-
mydriver-objs := testdelay.o kn_common.o
-
obj-$(CONFIG_MYDRIVER_USER) +=mydriver_user.o
上面的Makefile文件这里必须注意一点:比如obj
-$(CONFIG_MYDRIVER
) += mydriver
.o这条语句(+=、:=)之间不能有空格,如果有空格的话会有问题,不能生成相应的.o文件。
D.我们需要用户来选择是否编译mydriver.c,所以需要用CONFIG_MYDRIVER变量来保存选项值。下面两句类似我们一开始在父目录下增加myDriver目录。
Kconfig文件如下:
-
#drivers/myDriver/Kconfig
-
-
menu "Test myDriver"
-
-
config MYDRIVER
-
tristate "mydriver test!"
-
config MYDRIVER_USER
-
bool "user-space test"
-
depends on MYDRIVER
-
-
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、目录结构
-
|– myDriver
-
| |– Kconfig
-
| |– Makefile
-
| |– testdelay.c
-
| |– kn_common.c
-
| |– kn_common.h
Kconfig
-
#drivers/myDriver/Kconfig
-
-
menu "Test myDriver"
-
-
config MYDRIVER
-
tristate "mydriver test!"
-
config MYDRIVER_USER
-
bool "user-space test"
-
depends on MYDRIVER
-
-
endmenu
Makefile
-
#drivers/myDriver/Makefile
-
#just a test
-
-
obj-$(CONFIG_MYDRIVER) += mydriver.o
-
mydriver-objs := testdelay.o kn_common.o
-
obj-$(CONFIG_MYDRIVER_USER) +=mydriver_user.o
testdelay.c
-
#include <linux/sched.h>
-
#include <linux/timer.h>
-
#include <linux/jiffies.h>
-
#include <asm/param.h>
-
#include <linux/delay.h>
-
#include "kn_common.h"
-
-
MODULE_LICENSE("Dual BSD/GPL");
-
-
static void test_short_delay(void);
-
static void test_delay(void);
-
static void test_schedule_timeout(void);
-
static void my_delay_function(unsigned long);
-
-
static int testdelay_init(void)
-
{
-
printk(KERN_ALERT "HZ in current system: %dHz loops_per_jiffy=%lu\n", HZ,loops_per_jiffy);
-
-
/* test short delay */
-
test_short_delay();
-
-
/* test delay */
-
test_delay();
-
-
/* test schedule timeout */
-
test_schedule_timeout();
-
-
return 0;
-
}
-
-
static void testdelay_exit(void)
-
{
-
printk(KERN_ALERT "*************************\n");
-
print_current_time(0);
-
printk(KERN_ALERT "testdelay is exited!\n");
-
printk(KERN_ALERT "*************************\n");
-
}
-
-
static void test_short_delay()
-
{
-
printk(KERN_ALERT "jiffies [b e f o r e] short delay: %lu\n", jiffies);
-
ndelay(5);
-
printk(KERN_ALERT "jiffies [a f t e r] short delay: %lu\n", jiffies);
-
}
-
-
static void test_delay()
-
{
-
/* ????¨?? */
-
struct timer_list my_timer;
-
init_timer(&my_timer);
-
-
/* ????? */
-
my_timer.expires = jiffies + 1*HZ; /* 2??ó±????? */
-
my_timer.data = jiffies;
-
my_timer.function = my_delay_function;
-
-
/* ?¤???? */
-
add_timer(&my_timer);
-
}
-
-
static void my_delay_function(unsigned long data)
-
{
-
printk(KERN_ALERT "This is my delay function start......\n");
-
printk(KERN_ALERT "The jiffies when init timer: %lu\n", data);
-
printk(KERN_ALERT "The jiffies when timer is running: %lu\n", jiffies);
-
printk(KERN_ALERT "This is my delay function end........\n");
-
}
-
-
static void test_schedule_timeout()
-
{
-
printk(KERN_ALERT "This sample start at : %lu\n", jiffies);
-
-
unsigned int i,j,k;
-
for(i=1000;i>0;i--)
-
for(j=110;j>0;j--);
-
-
/* ??2? */
-
set_current_state(TASK_INTERRUPTIBLE);
-
printk(KERN_ALERT "sleep 2s ....\n");
-
schedule_timeout(2*HZ);
-
-
printk(KERN_ALERT "This sample end at : %lu\n", jiffies);
-
}
-
-
module_init(testdelay_init);
-
module_exit(testdelay_exit);
kn_common.c
-
#include "kn_common.h"
-
-
void print_current_time(int is_new_line)
-
{
-
#if 0
-
struct timeval *tv;
-
struct tm *t;
-
tv = kmalloc(sizeof(struct timeval), GFP_KERNEL);
-
// t = kmalloc(sizeof(struct tm), GFP_KERNEL);
-
-
do_gettimeofday(tv);
-
time_to_tm(tv->tv_sec, 0, t);
-
-
printk(KERN_ALERT "%ld-%d-%d %d:%d:%d",
-
t->tm_year + 1900,
-
t->tm_mon + 1,
-
t->tm_mday,
-
(t->tm_hour + 8) % 24,
-
t->tm_min,
-
t->tm_sec);
-
-
if (is_new_line == 1)
-
printk(KERN_ALERT "\n");
-
-
kfree(tv);
-
kfree(t);
-
#endif
-
}
kn_common.h
-
#include<linux/init.h>
-
#include<linux/slab.h>
-
#include<linux/module.h>
-
#include<linux/kernel.h>
-
#include<linux/kfifo.h>
-
#include<linux/time.h>
-
-
void print_current_time(int);
2、编译
-
root@book-desktop:/opt/linux-2.6.32.9.1# make menuconfig
配置
Device Drivers --->
Test myDriver --->
mydriver test!
Exit退出保存
make
在drivers/myDriver目录下面是不是可以看到ko文件:
-
root@book-desktop:/opt/linux-2.6.32.9.1/drivers/myDriver# ls -l
-
total 52
-
-rw-r--r-- 1 root root 8 2014-09-17 15:43 built-in.o
-
-rw-r--r-- 1 root root 167 2014-09-17 14:26 Kconfig
-
-rwxr-xr-x 1 root root 587 2014-09-17 15:05 kn_common.c
-
-rw-r--r-- 1 root root 175 2014-09-17 14:37 kn_common.h
-
-rw-r--r-- 1 root root 711 2014-09-17 15:43 kn_common.o
-
-rw-r--r-- 1 root root 165 2014-09-17 15:42 Makefile
-
-rw-r--r-- 1 root root 36 2014-09-17 15:49 modules.order
-
-rw-r--r-- 1 root root 3314 2014-09-17 15:49 mydriver.ko
-
-rw-r--r-- 1 root root 444 2014-09-17 15:43 mydriver.mod.c
-
-rw-r--r-- 1 root root 1372 2014-09-17 15:43 mydriver.mod.o
-
-rw-r--r-- 1 root root 2560 2014-09-17 15:49 mydriver.o
-
-rwxr-xr-x 1 root root 2150 2014-09-17 15:49 testdelay.c
-
-rw-r--r-- 1 root root 2480 2014-09-17 15:49 testdelay.o
将上面的ko文件烧到目标主机上加载驱动:
-
root@Phoenix /root#insmod mydelay.ko
-
[ 60.200000] HZ in current system: 100Hz loops_per_jiffy=997376
-
[ 60.210000] jiffies [b e f o r e] short delay: 4294943317
-
[ 60.220000] jiffies [a f t e r] short delay: 4294943318
-
[ 60.220000] This sample start at : 4294943318
-
[ 60.230000] This sample end at : 4294943319
到处整个过程结束。
阅读(5228) | 评论(0) | 转发(2) |