您的位置:首页 > 运维架构 > Linux

Linux Driver with new kernel-3.8

2013-04-29 14:00 323 查看
今天首次接触Linux字符设备的编程,花了很长的时间,针对所发现的问题进行整理如下:

有以下注意点:

1,编译模块不需要编译内核。按照如下的Makefile的方式即可在ubuntu下进行设备模块编译

2,insmod后,需要使用mknod进行设备映射。此时,需要在cat /proc/devices中确认好主设备值

例如:mknod /dev/tfs 250 0

3,编写测试代码时,需要注意权限的使用,因为映射到/dev/tfs中的权限只有root权限才可以进行rw。其他的权限为只读。

先附上字符设备驱动的源码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <linux/slab.h>

MODULE_LICENSE("Dual BSG/GPL");

unsigned int fs_major = 0;
static char *data;

static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_pos);
static ssize_t test_write(struct file *file, const char *buffer, size_t count, loff_t *f_pos);
static int test_open(struct inode *inode, struct file *file);
static int test_release(struct inode *inode, struct file *file);
int init_module(void);
void cleanup_module(void);

static struct file_operations chr_fops = {
read:	test_read,
write:	test_write,
open:	test_open,
release:test_release
};

static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_pos)
{
int len;
if (count<0)
return -EINVAL;
len = strlen(data);
if (len<count)
count = len;
copy_to_user(buf, data, count+1);
return count;
}

static ssize_t test_write(struct file *file, const char *buffer, size_t count, loff_t *f_pos)
{
if (count < 0 )
return -EINVAL;
kfree(data);
data = (char *) kmalloc(sizeof(char)*(count+1), GFP_KERNEL);
if (!data)
return -ENOMEM;
copy_from_user(data, buffer, count+1);
return count;
}

static int test_open(struct inode *inode, struct file *file)
{
try_module_get(THIS_MODULE);
printk("This is open \n");
return 0;
}

static int test_release(struct inode *inode, struct file *file)
{
module_put(THIS_MODULE);
printk("This is released\n");
return 0;
}

int init_module(void)
{
int res;
res = register_chrdev(0, "tfs", &chr_fops);
if (res<0)
{
printk("Can't get major name\n");
return 0;
}

if (fs_major == 0)
fs_major=res;

printk("Major name is %d", fs_major);

return 0;
}

void clean_module(void)
{
unregister_chrdev(fs_major, "tfs");
printk("tfs has removed");
}


附上Makefile的源码(注意Makefile的大小写,不能为makefile)

obj-m +=memrw_drv.o

all:
make -C /lib/modules/`uname -r`/build M=$(PWD) modules

clean:
make -C /lib/modules/`uname -r`/build M=$(PWD) clean


附上字符设备的测试源码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#define DEVPATH	"/dev/tfs"

int main(int argc, char **argv)
{
int fd, i, nwrite, nread, len;
char *buf = "String to Driver\n";
char read_buf[18] = { 0 };
fd = open(DEVPATH, O_RDWR);
if (fd<0)
{
perror("open");
exit(1);
}else
printf("device opened!\n");

fflush(stdout);

len = strlen(buf);
nwrite = write(fd, buf, len);
if(nwrite<0)
{
perror("write");
exit(1);
}

nread = read(fd, read_buf, 18);
if(nread<0)
{
perror("read");
exit(1);
}else
printf("Read String is from driver -> %s" , read_buf);

fflush(stdout);
close(fd);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: