Hello,
I wrote a very simple character device driver. It compiles correctly and
insmod can insert it.
The problem is that I can't see my driver listed in /dev after insmomd has executed.
I also tried to execute mknod chardev c 250 0 after insmod, but the problem persists (250 is the major number yielded by register_chrdev.
I have Linux 10.04, kernel 2.6.32-21-generic
Any suggestion?
Thank you in advance
The code follows
chardev.c
Code:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
void cleanup_module(void);
int init_module(void);
static int device_open(struct inode *, struct file*);
static int device_release(struct inode *, struct file*);
static ssize_t device_read(struct file*, char __user*, size_t, loff_t*);
static ssize_t device_write(struct file*,const char __user*, size_t, loff_t*);
#define SUCCESS 0
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
static int Major;
static int Device_Open = 0;
static char msg[BUF_LEN];
static char* msg_ptr;
static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};
//static int __init chardev_init(void){
int init_module(void){
Major = register_chrdev(0, DEVICE_NAME, &fops);
if(Major<0){
printk(KERN_ALERT "Registering char device failed with %d\n",Major);
return Major;
}
printk(KERN_INFO "Major number: %d\n",Major);
printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n",DEVICE_NAME,Major);
return SUCCESS;
}
int device_open(struct inode* inode, struct file* file){
static int count = 0; //Why counter is here? Why not global?
if(Device_Open==0)
return -EBUSY;
sprintf(msg, "I already told you hello %d times", count++) ;
msg_ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static ssize_t device_read(struct file* filp, char __user* buffer, size_t length,
loff_t* offset){
int bytes_read = 0;
if(*msg_ptr == 0)
return 0;
while(*msg_ptr && length ){
put_user(*(msg_ptr++),buffer++); //Why they are both pointer?
length--;
bytes_read++;
}
return bytes_read;
}
static ssize_t device_write(struct file* filp,const char __user* buffer, size_t len, loff_t* off) {
printk(KERN_ALERT "Sorry, this operation isn't supported \n");
return -EINVAL;
}
static int device_release(struct inode* inode, struct file* file){
Device_Open--;
module_put(THIS_MODULE);
return 0;
}
//static void __exit chardev_exit(void){
void cleanup_module(void){
// int ret =
unregister_chrdev(Major,DEVICE_NAME);
// if(ret < 0)
printk(KERN_ALERT "Unregistering chrdev \n");
}
Makefile
Code:
obj-m += chardev.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean