#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/kernel.h> /* printk(), min() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/proc_fs.h>
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
struct scull_pipe {
wait_queue_head_t inq, outq; /* read and write queues */
char *buffer, *end; /* begin of buf, end of buf */
int buffersize; /* used in pointer arithmetic */
char *rp, *wp; /* where to read, where to write */
int nreaders, nwriters; /* number of openings for r/w */
struct fasync_struct *async_queue; /* asynchronous readers */
struct semaphore sem; /* mutual exclusion semaphore */
struct cdev cdev; /* Char device structure */
};
struct file_operations scull_pipe_fops = {
.owner = THIS_MODULE,
/* .llseek = no_llseek,
.read = scull_p_read,
.write = scull_p_write,
.poll = scull_p_poll,
.ioctl = scull_ioctl,
.open = scull_p_open,
.release = scull_p_release,
.fasync = scull_p_fasync,
*/
};
dev_t firstdev=260046855;/*major=248 minor=7*/
dev_t devno=260046855;
struct scull_pipe *mydevice;
int err;
int scull_p_init(void)
{
int result;
printk(KERN_INFO"Hello, KERN_INFO !\n");
printk(KERN_INFO"Hello, shit !\n");
result = register_chrdev_region(firstdev, 1, "song");
printk("firstdev=%d\n",firstdev);
printk("MAJOR=%d\n",MAJOR(firstdev));
printk("MINOR=%d\n",MINOR(firstdev));
if (result < 0) {
printk(KERN_NOTICE "Unable to get scullp region, error %d\n", result);
return 0;
}
mydevice=kmalloc(sizeof(struct scull_pipe),GFP_KERNEL);
cdev_init(&mydevice->cdev, &scull_pipe_fops);
mydevice->cdev.owner = THIS_MODULE;
err = cdev_add (&mydevice->cdev, firstdev, 1);
if (err)
printk(KERN_NOTICE "Error %d adding scullpipe", err);
/**********************************************************************************/
firstdev++;/*major=248 minor=8*/
result = register_chrdev_region(firstdev, 2, "hi");//minor=8,9
printk("firstdev=%d\n",firstdev);
printk("MAJOR=%d\n",MAJOR(firstdev));
printk("MINOR=%d\n",MINOR(firstdev));
if (result < 0) {
printk(KERN_NOTICE "Unable to get scullp region, error %d\n", result);
return 0;
}
}
/*
* This is called by cleanup_module or on failure.
* It is required to never fail, even if nothing was initialized first
*/
void scull_p_cleanup(void)
{
printk("<4>Good-bye\n");
unregister_chrdev_region(devno, 3);
/*
*/
}
module_init(scull_p_init);
module_exit(scull_p_cleanup);
MODULE_LICENSE("GPL");
[root@localhost test]# make
[root@localhost test]# insmod test.ko
[root@localhost test]# cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
6 lp
7 vcs
10 misc
13 input
14 sound
21 sg
29 fb
68 capi20
99 ppdev
116 alsa
128 ptm
136 pts
162 raw
180 usb
189 usb_device
202 cpu/msr
203 cpu/cpuid
248 song
248 hi
249 capi
250 vmci
251 hidraw
252 usbmon
253 bsg
254 rtc
看来已经注册成功,三个设备号,第一次注册1个,第二次注册2个
每成功register_chrdev_region一次,就会在/proc/devices里添加一条记录
1.每次register可以注册一个主设备号,但可以多个次设备号
2.多次register时,主设备号可以相同,但次设备号不要相同
3.多次register时,设备名可以相同
[root@localhost test]# dmsg
...
[ 338.162180] Hello, KERN_INFO !
[ 338.162431] Hello, shit !
[ 338.162694] firstdev=260046855
[ 338.162705] MAJOR=248
[ 338.162715] MINOR=7
[ 338.179109] firstdev=260046856
[ 338.179120] MAJOR=248
[ 338.179130] MINOR=8
[ 338.179196] sys_init_module: 'test'->init suspiciously returned 26, it should follow 0/-E convention
[ 338.179198] sys_init_module: loading module anyway...
[ 338.179321] Pid: 3101, comm: insmod Not tainted 2.6.35.6-45.fc14.i686 #1
[ 338.179350] Call Trace:
[ 338.179828] [<c07a56f1>] ? printk+0x25/0x2c
[ 338.179990] [<c0462211>] sys_init_module+0xec/0x19b
[ 338.180004] [<c07a73ac>] syscall_call+0x7/0xb