今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

内核编译和嵌入式产品的设计与开发
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#1

帖子 cnkilior » 2009-10-31 20:06

源代码:

代码: 全选

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/fs.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangn1985@gmail.com");

#define DEVICE_NAME "mychrdev"
#define NUM 8
char men[NUM];
int lenth=0;
static struct mutex mutex;
ssize_t my_write(struct file *fp, const char __user *buf,size_t count,loff_t *offp){
    int i=(NUM>=count)?count:NUM;
    mutex_lock(&mutex);
    copy_from_user(men,buf,i);
    lenth=i;
	printk (KERN_ALERT "men is %s",men);
	printk (KERN_ALERT "lenth is %d",lenth);
    mutex_unlock(&mutex);
    return i;
}

ssize_t my_read(struct file *fp, char __user *buf,size_t count,loff_t *offp){
    int i=(NUM>=count)?count:NUM;
    mutex_lock(&mutex);
+	if(*offp >= lenth) {
+         goto FALL;
+     }
    i=(lenth>=i)?i:lenth;
    copy_to_user(buf,men,i);
+   *offp+=i;
    mutex_unlock(&mutex);
    return i;
+ FALL:
+	mutex_unlock(&mutex);
+	return 0;
}

static int my_open(struct inode *inod, struct file *fp){
    if (!try_module_get(THIS_MODULE))return -EBUSY;
    return 0;
}
static int my_release(struct inode *inod,struct file *fp){
    module_put(THIS_MODULE);
    return 0;
}

static struct file_operations fileop={
    .read = my_read,
    .write = my_write,
    .open = my_open,
    .release = my_release,
};

static struct cdev *dev;
static dev_t devt;

static int my_init(void){
    int ret;
	printk(KERN_ALERT "mymodule init...\n");

    if ((ret=alloc_chrdev_region(&devt,0,1,DEVICE_NAME))<0){
	printk(DEVICE_NAME "\ncan't register major number");
	return ret;
    }else{
	printk(KERN_ALERT "mymodule get majmun %d\n",MAJOR(devt));
}
    if ((dev=cdev_alloc())==NULL){
	printk(DEVICE_NAME "\ncdev_alloc error");
	ret=-1;
	goto FALL1;
    }
    cdev_init(dev,&fileop);
    if ((ret=cdev_add(dev,devt,1))<0){
	printk(DEVICE_NAME "\ncdev_add error");
	goto FALL2;
    }
    mutex_init(&mutex);
    return 0;
FALL2:
    cdev_del(dev);
FALL1:
    unregister_chrdev_region(devt,1);
    return ret;
}

static void my_exit(void){
	printk (KERN_ALERT "mymodule exit...\n");
    cdev_del(dev);
    unregister_chrdev_region(devt,1);
    mutex_destroy(&mutex);
}
module_init(my_init);
module_exit(my_exit);

Makefile:

代码: 全选

obj-m := mychrdev.o
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	rm *.o;rm *.ko
测试方法:
在kern.log中模块会打印自己的主设备号,或者从/proc/modules中看这个设备的设备号major,设备名为mychrdev
一般分配成250 //真杯具
用mknod /dev/NAME_YOU_WANT c $major 0 生成设备节点。
用echo xxxxx > /dev/NAME_YOU_WANT 写入
用cat /dev/NAME_YOU_WANT 读出
上次由 cnkilior 在 2009-11-03 16:39,总共编辑 2 次。
lakewalker
帖子: 7
注册时间: 2007-12-05 18:37

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#2

帖子 lakewalker » 2009-11-01 13:24

我也在向内核这方面学习,先看赵炯老师的经典~~
头像
daf3707
论坛版主
帖子: 12731
注册时间: 2007-06-13 15:57
来自: 在他乡

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#3

帖子 daf3707 » 2009-11-01 13:40

会写内核对我来说就是神 :em09 :em03
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#4

帖子 cnkilior » 2009-11-01 22:00

修改了一下代码,明白了

代码: 全选

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
中loff_t *的含义了:由内核维护的偏移量,但偏移量的更新要通过read函数手动更新。
头像
wangdu2002
帖子: 13284
注册时间: 2008-12-13 19:39
来自: 物华天宝人杰地灵

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#5

帖子 wangdu2002 » 2009-11-01 22:02

难道杀手佛太也学习装嫩了。。。佛太写的某全看不明白。。。 :em20
行到水穷处,坐看云起时。
海内生明月,天涯共此夕。
--------------------吾本独!
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#6

帖子 cnkilior » 2009-11-01 22:03

lakewalker 写了:我也在向内核这方面学习,先看赵炯老师的经典~~

我先从驱动入手,来了解内核,如果可能就看看0.11内核代码和那本书。

这个帖子我会持续,间断更新。
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#7

帖子 cnkilior » 2009-11-02 15:02

内核为每个文件创建一个inode结构,多次打开同一个文件会创建多个file结构,但它们都指向同一个inode结构,当文件关闭时,这个打开实例的file结构被注销。

不知道这样理解是否正确。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#8

帖子 eexpress » 2009-11-02 15:29

你装嫩吧。我连内核模块是啥都不明白。
● 鸣学
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#10

帖子 cnkilior » 2009-11-02 15:36

文件结构代表一个打开的文件. (它不特定给设备驱动; 系统中每个打开的文件有一个关联的 struct file 在内核空间). 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的关闭. 在文件的所有实例都关闭后, 内核释放这个数据结构.
我对这段话不理解。

直到最后的关闭,是不是说,关闭的时候会销毁掉这个实例的file结构。
如果这样理解,那么下一句话又是什么意思呢?说的是所有的file结构会在全部实例关闭之后会全部释放掉?
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#11

帖子 cnkilior » 2009-11-03 23:05

理解file结构

今天做的实验,刚开始都是错误,后来发现了错误的原因,终于得到了正确的结果,也发现了file的一部分性质。

具体看我的代码和测试用例。
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#12

帖子 cnkilior » 2009-11-04 10:50

cnkilior 写了:
文件结构代表一个打开的文件. (它不特定给设备驱动; 系统中每个打开的文件有一个关联的 struct file 在内核空间). 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的关闭. 在文件的所有实例都关闭后, 内核释放这个数据结构.
我对这段话不理解。

直到最后的关闭,是不是说,关闭的时候会销毁掉这个实例的file结构。
如果这样理解,那么下一句话又是什么意思呢?说的是所有的file结构会在全部实例关闭之后会全部释放掉?

新的测试终于明白了这句话的意思了,并不是说close函数执行后file结构就会被释放,而是全部的实例都关闭之后才会被释放。
metalord666
帖子: 4
注册时间: 2009-08-23 15:51

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#13

帖子 metalord666 » 2009-11-05 9:45

cnkilior 写了:
cnkilior 写了:
文件结构代表一个打开的文件. (它不特定给设备驱动; 系统中每个打开的文件有一个关联的 struct file 在内核空间). 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的关闭. 在文件的所有实例都关闭后, 内核释放这个数据结构.
我对这段话不理解。

直到最后的关闭,是不是说,关闭的时候会销毁掉这个实例的file结构。
如果这样理解,那么下一句话又是什么意思呢?说的是所有的file结构会在全部实例关闭之后会全部释放掉?

新的测试终于明白了这句话的意思了,并不是说close函数执行后file结构就会被释放,而是全部的实例都关闭之后才会被释放。
有引用计数呢~引用计数为0就释放了~
头像
cnkilior
论坛版主
帖子: 4984
注册时间: 2007-08-05 17:40

Re: 今天被逼无奈,写了一个内核模块,可以运行。和我一样的新手可以来看看,老鸟就别来了。

#14

帖子 cnkilior » 2009-11-06 8:59

哇,楼上的处女贴。。。鸡冻啊。

-----
是的,引用计数不为零的时候就不会释放了。
回复