/* firstdriver.c 起始 */
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/version.h>
char kernel_version[] = UTS_RELEASE;
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything, e.g. file_operations, file */
#include <linux/errno.h>
#include <linux/types.h> /* ssize_t */
#include <asm-i386/uaccess.h> /* verify_area, __put_user */
#define TEST_MAJOR 0
int test_major = TEST_MAJOR; /* the major of the test driver */
/* open function */
static int test_open(struct inode* inode, struct file* filp)
{
MOD_INC_USE_COUNT; /* defined in <linux/module.h> */
return 0; /* success */
}
/* release function */
static int test_release(struct inode *inode, struct file* filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
/* read function */
static ssize_t test_read(struct file* filp, char* buf, size_t count, loff_t* fpos)
{
int i;
if(verify_area(VERIFY_WRITE, buf, count) == -EFAULT)
return -EFAULT;
for(i=count; i>0; i--)
{
__put_user(1, buf);
buf++;
}
return count;
}
/* write function */
static ssize_t test_write(struct file* filp, const char* buf, size_t count, loff_t* fpos)
{
return count;
}
#if 0
struct file_operations test_fops = {
NULL, /* struct module */
NULL, /* llseek */
test_read, /* read */
test_write, /* write */
NULL, /* readdir */
NULL, /* poll */
NULL, /* ioctl */
NULL, /* mmap */
test_open, /* open */
NULL, /* flush */
test_release, /* release */
NULL,
};
#else
struct file_operations test_fops = {
owner: NULL,
read: test_read,
write: test_write,
open: test_open,
release: test_release,
};
#endif
#ifdef MODULE
#if 0
int init_module(void)
#else //new format
int __init firstdriver_init(void)
#endif
{
MODULE_LICENSE("GPL");
int result = register_chrdev(test_major, "firstdriver", &test_fops);
if(result < 0)
{
printk(KERN_WARNING "testdriver: can't get major %d/n", test_major);
return result;
}
if(test_major == 0)
test_major = result; /* dynamic */
}
#if 0
void cleanup_module(void)
#else // new format
void __exit firstdriver_exit(void)
#endif
{
unregister_chrdev(test_major, "firstdriver");
}
// new format
module_init(firstdriver_init);
module_exit(firstdriver_exit);
#endif /* end of MODULE */
/* firstdriver.c 结束 */
/*test.c 测试程序 起始*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int testdev;
int i;
char buf[10];
testdev = open("/dev/firstdriver", O_RDWR);
if(testdev == -1)
{
printf("can't open file/n");
exit(0);
}
read(testdev, buf, 10);
for(i=0; i<10; i++)
printf("%d", buf[i]);
printf("/n");
close(testdev);
}
/*test.c 测试程序 结束*/
/* Makefile 起始*/
CC = gcc
FLAGS = -O2 -D__KERNEL__ -DMODULE -I /usr/src/linux-2.4/include
all : firstdriver.o test
# build the driver
firstdriver.o : firstdriver.c
$(CC) $(FLAGS) -c firstdriver.c
# build the test program
test : test.o
$(CC) -o test test.o
test.o :test.c
$(CC) -c test.c
clean:
@-rm -f firstdriver.o
@-rm -f test.o test
/* Makefile 结束 */
/* load.sh 加载脚本 起始*/
# !/bin/sh
module="firstdriver"
device="firstdriver"
/sbin/insmod ${module}.o
major=`cat /proc/devices | awk "//$2==/"$module/" {print //$1}"`
#注,此处是`(~那个键),而不是'(单引号)
rm -f /dev/${device}
mknod /dev/${device} c $major 0
/* load.sh 加载脚本 结束*/
/* unload.sh 卸载脚本 起始*/
# !/bin/sh
module="firstdriver"
device="firstdriver"
/sbin/rmmod ${module}
# Remove device file
rm -f /dev/${device}
/* unload.sh 卸载脚本 结束*/