cdev_del a zaznam v /proc/devices

Sekcia: Programovanie 02.08.2010 | 19:04
Avatar m4jkl   Používateľ
zdravim,

skusam si pisat ovladac znakoveho zariadenia (zacinam :)). postupujem cca takto:
v __init funkcii:
1. alokovanie major-minor cisel cez alloc_chrdev_region()
2. dynamicka alokacia cdev struktury pomocou cdev_alloc()
3. pridanie zariadenia do systemu cdev_add()
a zariadenie sa skutocne objavi v /proc/devices

__exit funkcia:
cdev_del();
unregister_chrdev_region();
za tymto mam pomocny vypis, takze predpokladam, ze zariadenie by malo by prec zo systemu. lenze je stale tam, stale to dokonca ukazuje jeho major cislo. kompilujem to ako modul (2.6.32) a je tam aj ked ho z jadra odoberiem. ked ho tam zasa zavediem, tak sa vytvori v /proc/devices dalsie zariadenie s novym major cislom :)

co si mam o tom mysliet? alebo nieco zle chapem a je to normalne chovanie? mate s tym niekto skusenosti?

dakujem, za kazdu odpoved
    • Re: cdev_del a zaznam v /proc/devices 02.08.2010 | 22:58
      xchg   Návštevník
      Nie je to normalne chovanie. Z tvojho popisu nevyzera ze by si niekde robil chybu, postni cely kod ak nevadi
      • Re: cdev_del a zaznam v /proc/devices 02.08.2010 | 23:25
        Avatar m4jkl   Používateľ
        jasne, ze nevadi :)
        #include <linux/fs.h>
        #include <linux/cdev.h>
        #include <linux/init.h>
        #include <linux/module.h>
        
        MODULE_DESCRIPTION("sample\n\n"
        					"module.");
        MODULE_AUTHOR("me");
        MODULE_LICENSE("GPL");		// do not 'taint' the running kernel
        MODULE_VERSION("0.0.3");	
        
        
        // playing with paramters
        static short test = 0;
        module_param(test, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
        MODULE_PARM_DESC(test, "test test desc");
        
        
        static dev_t mydev_num = MKDEV(0, 0);		 
        
        static struct cdev *mydev_cdev = NULL;	
        				
        // file operations. comming soon :)
        static struct file_operations mydev_fops = {
        	.owner = THIS_MODULE
        };
        
        static int __init mymodule_init(void) {
        	
        	int res = printk(KERN_INFO "mymodule: requesting major/minor numbers\n");
        	// get major number and reserve some minor numbers
        	// params: dev_t structure, first minor number, number of desired iminor numbers, new device's name
        	res = alloc_chrdev_region(&mydev_num, MINOR(mydev_num), 1, "mydev");
        	if (res < 0)
        		goto alloc_failed;
        
        	printk(KERN_INFO "mymodule: initializing device sctructure\n");
        	// initialization of device structure
        	mydev_cdev = cdev_alloc();
        	if (mydev_cdev == NULL) {
        		res = -ENOMEM;
        		goto cdev_failed;
        	}
        
        	// connect file operations with device
        	mydev_cdev->ops = &mydev_fops;
        
        	printk(KERN_INFO "mymodule: adding device to the system\n");
        	// add device to the system, if successful then it should be visible in /proc/devices
        	// params: device struct, device numbers, number of minor numbers
        	res = cdev_add(mydev_cdev, mydev_num, 1);
        	if (res < 0)
        		goto add_failed;
        
        	printk(KERN_INFO "mymodule: all done :)\n");
        	printk(KERN_INFO "mymodule: %hd has been given to module\n", test); // or nothing has been given
        	return 0;		// ok, module initialized
        
        	// something's horribly wrong. blame canada
        	add_failed:
        		// dealocate device
        		cdev_del(mydev_cdev);
        
        	cdev_failed:
        		// return mojor/minor numbers back to kernel
        		unregister_chrdev_region(MINOR(mydev_num), 1);
        	
        	alloc_failed:
        		// ooops, no major/minor numbers for us
        	return res;
        }
        
        static void __exit mymodule_cleanup(void)
        {
        	cdev_del(mydev_cdev);
        	unregister_chrdev_region(MINOR(mydev_num), 1);
        	printk(KERN_INFO "mymodule: successfuly removed\n");
        }
        
        module_init(mymodule_init);
        module_exit(mymodule_cleanup);
        
        • Re: cdev_del a zaznam v /proc/devices 02.08.2010 | 23:36
          xchg   Návštevník
          unregister_chrdev_region(MINOR(mydev_num), 1);

          zamen za

          unregister_chrdev_region(mydev_num, 1);

          a vsetko by malo byt ok :)
          • Re: cdev_del a zaznam v /proc/devices 02.08.2010 | 23:46
            Avatar m4jkl   Používateľ
            je to tak, uz to funguje. a je to uplne logicke, dakujem :)
            vychadzal som z prikladu v knihe pana Jelinka "Jadro systemu linux". holt, ma tam chybu :)

            este raz dakujem