最简单的内核字符设备驱动
时间:2006-04-18 来源:tx-cary
这是参考《Linux设备驱动程序》第三版写的一个简单的字符设备驱动程序,简直简单得无与伦比,不过也算是2.6内核风格的了。实现的功能是当应用程序读此设备时,返回26个英文字母。
第一步,建立一个字符设备文件:
mknod /dev/scull c 200 0
chmod 666 /dev/scull
以下是驱动源码,scull.c
/****************************Begin**************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#define DEV_MAJOR 200
#define DEV_MINOR 0
MODULE_LICENSE("Dual BSD/GPL");
char *buffer = "abcdefghijklmnopqrstuvwxyz";
static int scull_open( struct inode *scull_inode, struct file *scull_file );
static int scull_release( struct inode *scull_inode, struct file *scull_file );
static ssize_t scull_read( struct file *p_file, char *u_buffer, size_t count, loff_t *ppos );
dev_t scull_dev;
struct cdev *scull_cdev;
struct file_operations scull_fops = {
owner : THIS_MODULE,
read : scull_read,
// .write = scull_write,
open : scull_open,
release : scull_release,
};
static int scull_open( struct inode *p_inode, struct file *p_file )
{
return( 0 );
}
static int scull_release( struct inode *p_inode, struct file *p_file )
{
return( 0 );
}
static ssize_t scull_read( struct file *p_file, char *u_buffer, size_t count, loff_t *ppos )
{
int rc;
rc = copy_to_user( u_buffer, buffer, count );
return( rc );
}
static int scull_init( void )
{
scull_dev = MKDEV( DEV_MAJOR, DEV_MINOR );
register_chrdev_region( scull_dev, 1, "scull" );
scull_cdev = cdev_alloc();
scull_cdev->owner = THIS_MODULE;
scull_cdev->ops = &scull_fops;
cdev_init( scull_cdev, &scull_fops );
cdev_add( scull_cdev, scull_dev, 1 );
return( 0 );
}
static void scull_exit( void )
{
cdev_del( scull_cdev );
unregister_chrdev_region( scull_dev, 1 );
}
module_init(scull_init);
module_exit(scull_exit);
/***************************END*****************************/
以下是Makefile:
/***************************Begin*****************************/
KERNELDIR := /usr/src/linux-2.6.16-beyond/
obj-m := scull.o
default:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules
/***************************END*****************************/
以下是测试程序:
/***************************Begin*****************************/
#include <linux/fs.h>
#include <stdio.h>
int main()
{
char buffer[64];
int count;
int fd;
fd = open( "/dev/scull", 0 );
read( fd, buffer, 20 );
printf( "%s", buffer );
close( fd );
return( 0 );
}
/***************************END*****************************/
完成了,是不是简单得令人发指啊?
第一步,建立一个字符设备文件:
mknod /dev/scull c 200 0
chmod 666 /dev/scull
以下是驱动源码,scull.c
/****************************Begin**************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#define DEV_MAJOR 200
#define DEV_MINOR 0
MODULE_LICENSE("Dual BSD/GPL");
char *buffer = "abcdefghijklmnopqrstuvwxyz";
static int scull_open( struct inode *scull_inode, struct file *scull_file );
static int scull_release( struct inode *scull_inode, struct file *scull_file );
static ssize_t scull_read( struct file *p_file, char *u_buffer, size_t count, loff_t *ppos );
dev_t scull_dev;
struct cdev *scull_cdev;
struct file_operations scull_fops = {
owner : THIS_MODULE,
read : scull_read,
// .write = scull_write,
open : scull_open,
release : scull_release,
};
static int scull_open( struct inode *p_inode, struct file *p_file )
{
return( 0 );
}
static int scull_release( struct inode *p_inode, struct file *p_file )
{
return( 0 );
}
static ssize_t scull_read( struct file *p_file, char *u_buffer, size_t count, loff_t *ppos )
{
int rc;
rc = copy_to_user( u_buffer, buffer, count );
return( rc );
}
static int scull_init( void )
{
scull_dev = MKDEV( DEV_MAJOR, DEV_MINOR );
register_chrdev_region( scull_dev, 1, "scull" );
scull_cdev = cdev_alloc();
scull_cdev->owner = THIS_MODULE;
scull_cdev->ops = &scull_fops;
cdev_init( scull_cdev, &scull_fops );
cdev_add( scull_cdev, scull_dev, 1 );
return( 0 );
}
static void scull_exit( void )
{
cdev_del( scull_cdev );
unregister_chrdev_region( scull_dev, 1 );
}
module_init(scull_init);
module_exit(scull_exit);
/***************************END*****************************/
以下是Makefile:
/***************************Begin*****************************/
KERNELDIR := /usr/src/linux-2.6.16-beyond/
obj-m := scull.o
default:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules
/***************************END*****************************/
以下是测试程序:
/***************************Begin*****************************/
#include <linux/fs.h>
#include <stdio.h>
int main()
{
char buffer[64];
int count;
int fd;
fd = open( "/dev/scull", 0 );
read( fd, buffer, 20 );
printf( "%s", buffer );
close( fd );
return( 0 );
}
/***************************END*****************************/
完成了,是不是简单得令人发指啊?
相关阅读 更多 +