标题: 求助!!卸载驱动时,模块仍在使用中。module is in use [打印本页] 作者: chen_q07 时间: 2011-11-16 17:43 标题: 求助!!卸载驱动时,模块仍在使用中。module is in use 我刚接触驱动开发。学习资料是Linux Device Drivers 3rd。我根据书中的代码,稍微改写了一下,结果试验时就出现以下情况了。
求高手指导!!
1. 编译通过,用complete.init start加载模块时,Failed,但是,查看、proc/devices文件显示该模块已经加载上了,有major number。但是,
用complete.init stop卸载该模块时,出现module complete is in use的提示,不能卸载。此时,我再用complete.init start加载模块时,还是
Failed了,说是file exists,说明该模块已经加载上了。怎么办?
2. 情形如下
user 1:
cat /dev/complete
(block)
user 2:
echo "hello" > complete
(唤醒user1的cat程序,但是没有任何显示,同时,用户从root变为test(自动变的。。。)不懂了。
另外,附上源码。附件中我已经附上文件。
求高手指导。
#ifndef _COMPLETEL_H_
#define _COMPLETEL_H_
struct complete_dev {
void* data; /* Pointer to first quantum set */
struct cdev cdev; /* Char device structure */
};
void complete_cleanup(void);
#endif /* _COMPLETEL_H_ */
复制代码
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h> /* current and everything */
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
#include <linux/types.h> /* size_t */
#include <linux/cdev.h>
#include <linux/errno.h> /* error codes */
#include <linux/completion.h>
#include <asm/uaccess.h> /* copy_*_user */
#include "complete.h"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("James Chen");
static int complete_major = 0;
struct complete_dev* complete_device;
DECLARE_COMPLETION(comp);
int complete_trim(struct complete_dev *dev)
{
if (dev->data)
{
kfree(dev->data);
dev->data = NULL;
}
return 0;
}
int complete_open(struct inode *inode, struct file *filp)
{
/*struct complete_dev *dev; */ /* device information */
/*
dev = container_of(inode->i_cdev, struct complete_dev, cdev);
*/
filp->private_data = complete_device; /* for other methods */
/* now trim to 0 the length of the device if open was write-only */
result = cdev_add (&complete_device->cdev, devno, 1);
/* Fail gracefully if need be */
if (result)
{
goto fail;
}
return 0;
fail:
complete_cleanup();
return result;
}
void complete_cleanup(void)
{
if (complete_device)
{
complete_trim(complete_device);
cdev_del(&complete_device->cdev);
kfree(complete_device);
}
unregister_chrdev(complete_major, "complete");
}
module_init(complete_init);
module_exit(complete_cleanup);
复制代码
init脚本如下
#!/bin/bash
# Sample init script for the a driver module <rubini@linux.it>
DEVICE="complete"
SECTION="misc"
# The list of filenames and minor numbers: $PREFIX is prefixed to all names
PREFIX="complete"
FILES=" 0 0 "
INSMOD=/sbin/insmod; # use /sbin/modprobe if you prefer
function device_specific_post_load () {
true; # fill at will
}
function device_specific_pre_unload () {
true; # fill at will
}
# Everything below this line should work unchanged for any char device.
# Obviously, however, no options on the command line: either in
# /etc/${DEVICE}.conf or /etc/modules.conf (if modprobe is used)
# Optional configuration file: format is
# owner <ownername>
# group <groupname>
# mode <modename>
# options <insmod options>
CFG=/etc/${DEVICE}.conf
# kernel version, used to look for modules
KERNEL=`uname -r`
#FIXME: it looks like there is no misc section. Where should it be?
MODDIR="/lib/modules/${KERNEL}/kernel/drivers/${SECTION}"
if [ ! -d $MODDIR ]; then MODDIR="/lib/modules/${KERNEL}/${SECTION}"; fi
# Root or die
if [ "$(id -u)" != "0" ]
then
echo "You must be root to load or unload kernel modules"
exit 1
fi
# Read configuration file
if [ -r $CFG ]; then
OWNER=`awk "\\$1==\"owner\" {print \\$2}" $CFG`
GROUP=`awk "\\$1==\"group\" {print \\$2}" $CFG`
MODE=`awk "\\$1==\"mode\" {print \\$2}" $CFG`
# The options string may include extra blanks or only blanks
OPTIONS=`sed -n '/^options / s/options //p' $CFG`
fi
# Create device files
function create_files () {
cd /dev
local devlist=""
local file
while true; do
if [ $# -lt 2 ]; then break; fi
file="${DEVICE}$1"
mknod $file c $MAJOR $2
devlist="$devlist $file"
shift 2
done
if [ -n "$OWNER" ]; then chown $OWNER $devlist; fi
if [ -n "$GROUP" ]; then chgrp $GROUP $devlist; fi
if [ -n "$MODE" ]; then chmod $MODE $devlist; fi
}
# Remove device files
function remove_files () {
cd /dev
local devlist=""
local file
while true; do
if [ $# -lt 2 ]; then break; fi
file="${DEVICE}$1"
devlist="$devlist $file"
shift 2
done
rm -f $devlist
}
# Load and create files
function load_device () {
if [ -f $MODDIR/$DEVICE.ko ]; then
devpath=$MODDIR/$DEVICE.ko
else if [ -f ./$DEVICE.ko ]; then
devpath=./$DEVICE.ko
else
devpath=$DEVICE; # let insmod/modprobe guess
fi; fi
if [ "$devpath" != "$DEVICE" ]; then
echo -n " (loading file $devpath)"
fi
if $INSMOD $devpath $OPTIONS; then
MAJOR=`awk "\\$2==\"$DEVICE\" {print \\$1}" /proc/devices`
remove_files $FILES
create_files $FILES
device_specific_post_load
else
echo " FAILED!"
fi
}
# Unload and remove files
function unload_device () {
device_specific_pre_unload
/sbin/rmmod $DEVICE
remove_files $FILES
}