驅(qū)動(dòng):
/*
* char-read.c
*
* Character driver with read operation
*
* Copyright (C) 2005 Farsight
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
MODULE_LICENSE ("GPL");
int hello_major = 253;
int hello_minor = 0;
int number_of_devices = 1;
char data[50]="foobar not equal to barfoo";
struct cdev cdev;
dev_t dev = 0;
static int hello_open (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened\n");
return 0;
}
static int hello_release (struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hmmm... device closed\n");
return 0;
}
ssize_t hello_read (struct file *filp, char *buff, size_t count, loff_t *offp)
{
ssize_t result = 0;
/*這里的buff僅是演示如把內(nèi)核空間的變量傳遞給用戶空間*/
if (copy_to_user (buff, data, sizeof(data)-1))
result = -EFAULT;
else
printk (KERN_INFO "wrote %d bytes\n", count);
return result;
}
ssize_t hello_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
ssize_t ret = 0;
printk (KERN_INFO "Writing %d bytes\n", count);
if (count>127) return -ENOMEM;
if (count<0) return -EINVAL;
if (copy_from_user (data, buf, count)) {
ret = -EFAULT;
}
else {
data[127]='\0';
printk (KERN_INFO"Received: %s\n", data);
ret = count;
}
return ret;
}
struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.read = hello_read,
.write = hello_write
};
static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add (&cdev, devno , 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
}
static int __init hello_2_init (void)
{
int result;
dev = MKDEV (hello_major, hello_minor);
result = register_chrdev_region (dev, number_of_devices, "hello");
if (result<0) {
printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);
return result;
}
char_reg_setup_cdev ();
printk (KERN_INFO "char device registered\n");
return 0;
}
static void __exit hello_2_exit (void)
{
dev_t devno = MKDEV (hello_major, hello_minor);
cdev_del (&cdev);
unregister_chrdev_region (devno, number_of_devices);
}
module_init (hello_2_init);
module_exit (hello_2_exit);
測(cè)試程序
/*
* test.c
*
* Test application code for char-read.c
*
* Copyright (C) 2005 Farsight
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main (void)
{
int fd;
char buff[50];
fd = open ("/dev/hello",O_RDWR);
if (fd < 0) {
printf ("fd open failed\n");
exit(0);
}
printf ("\n/dev/hello opened, fd=%d\n",fd);
memset (buff, '\0', 50);
printf ("Read returns %d\n", read (fd, buff, sizeof(buff)));
buff[50]='0';
printf ("buff = %s\n", buff);
close (fd);
printf ("/dev/hello closed :)\n");
return 0;
}
Makefile:
#KERNELDIR 變量換成你的目標(biāo)內(nèi)核源碼
KERNELDIR ?= /home/lht/kernel2.6/linux-2.6.14
obj-m += char-read.o
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。