内核入门:较为基础的Linux系统设备

文章作者 100test 发表时间 2007:12:15 12:34:10
来源 100Test.Com百考试题网


驱动程序为:
 
  

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

static unsigned int major = 0.

static unsigned int minor = 0.

static unsigned int devno.

static char *filename = "mydevice".

static struct cdev *mycdev = NULL.

static int mycdevflg = 0.

static int devnoflg = 0.

static int adddevflg = 0.

MODULE_LICENSE("Dual BSD/GPL").

static int myopen(struct inode *inodep, struct file *flipl)

{ 

printk("my open is run\n").

return 0.

}

static ssize_t myread(struct file *flip, char __user *buf, size_t size, loff_t offset)

{

printk("myread is ok!\n").

static int i = 0.

///copy_to_user(buf,from,size).

*buf = i  .

return 0.

}

static int myrelease(struct inode *myindoe, struct file *flip)

{

printk("myrelease is run.\n").

return 0.

}

static struct file_operations myfops =

{

.owner = THIS_MODULE,

.open = myopen,

.read = myread,

.release= myrelease,

}.

/* 初始化设备的过程主要是三步:1,生成设备号.2初始化设备;3,添加到内核。

*/

static int __init myinit(void)

{

int result = -1.

if(major)

{

devno = MKDEV(major,minor). //生成设备号

result = register_chrdev_region(devno,1,filename).//注册设备号devno,1为设备的个数

devnoflg = 1.

}

else

{

result = alloc_chrdev_region(&.devno,minor,1,filename).//生成设备号兵注册,

mior为次设备号,这里注意的是指针devno?

major = MAJOR(devno).

devnoflg = 1.

}

if(result < 0)

{

printk("cant register the major num!\n").

devnoflg = 0.

return -1.

}

//mycdev = kmalloc(sizeof(struct cdev),GFP_KERNEL).

//如果采用cdev_init(struct cdev*,struct file *)方式的话,这个才需要。

mycdev = cdev_alloc().//申请cdev内存兵初始化设备cdev,不能在这之前申请内存,

否则要释放两次!

if(NULL == mycdev)

{

printk("cant request the memory!\n").

}

mycdevflg = 1.

//memset(mycdev,0,sizeof(mycdev)).

mycdev->owner = THIS_MODULE.//如果采用cdev_init(struct cdev*,struct file *)方式的话,

这两项可以去掉

mycdev->ops = &.myfops.//如果采用cdev_init(struct cdev*,struct file *)方式的话,

这两项可以去掉

result = cdev_add(mycdev,devno,1).//设备和设备号联系起来,

即通常说的添加设备到内核

if(result < 0)

{

printk("cant add cdev.2\n").

adddevflg = 0.

}

else

{

adddevflg = 1.

}

return 0.

}

/* 以和设备注册的次序"卸载",注意有的时候,当出错的时候,要注意是否用到这些操作,

所以要加上判断,否则比如对空指针free会导致系统崩溃!

*/

static void myexit(void)

{

printk("myexit begin.\n").

if(adddevflg) 

{

cdev_del(mycdev).

adddevflg = 0.

}

if(mycdev) 

{

kfree(mycdev).

mycdev = NULL.

}

if(devnoflg)

{

unregister_chrdev_region(devno,1).

devno = 0.

devnoflg = 0.

}

printk("exit over.\n").

}

module_init(myinit).

module_exit(myexit).


 
  应用程序为:
 
  

#include 

#include 

#include 

#include 

#include 

int main() 

{ 

int fd. 

int i=0. 

fd = open("/dev/mydevice", O_RDONLY). 

if (fd < 0) 

{ 

printf("error1\n"). 

return -1. 

} 

int j = 0.

while(j  <10000)

{

if (read(fd, &.i, sizeof(int)) < 0) 

{ 

printf("read error2\n"). 

return -1. 

} 

printf("i = %d\n",i).

}

close("/dev/mydevice").

return 0. 

}


 
  一定要注意register_chrdev_region(),alloc_chrdev_region(),cdev_init(),cdev_alloc(),cdev_add()这些函数的参数类型,不要把指针当成非指针,把int类型当作指针(或者&.)来使用!

相关文章


老手经验谈介绍UNIX高手的十大习惯(上)
Linux用防火墙伪装抵挡黑客攻击(2)
Linux内核编译菜单中各选项代表的含义(2)
内核入门:较为基础的Linux系统设备
Linux系统下ISO镜像文件的制作与刻录
不同版本的Linux操作系统下软件源设置
linux挂载U盘假死机现象解释
限制Linux用户过渡占用磁盘空间
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛