Device Drivers can be classified into three basic types:
1.Character driver
2.Block driver
3.Network driver.
A character device is one that can be accessed as a stream of bytes i.e. character by character. And code needed make communication possible b/w a character device and application is character driver.
Now lets explain the basic arch :-
memory are divided into two parts kernel space and user space .all the application in user space and all device driver in kernel space .the only way to interface between user space and kernel space through node.node will create by mknod. module_init and module_exit(MACRO)use to add and remove driver.module_init insert driver to memory(RAM) using lsmod.
module_init remove driver to memory using (rmmod) .if our driver is insert than we register driver using alloc_chardev_region().alloc_chrdev_region register driver ,creat the major(type dev_t) and they also register the driver for n number of devices.they will give address 32bits firts 12 bits are major number and left 20 bits are minor number.if we insert driver than they give highest avalible major number .the range of major number is (0 to 255). & give lowest avalible major no (range 0 to 255).one advantage of alloc_chrdev_region that register the driver n number of device .after register driver than kmalloc to sculldev.kmalloc give physical space(address) on memory(ram).
scull:-
scull is basically a linklist,every struct we can say node and they are connected to each other thats way we can say linklist ,the first node name as sculldev,struct sculldev first member struct scullqset and many more like private data,wcount,quantum_size,qset_size,device_size,c_dev,scull second node that is scullqset (member of sculldev).in scullqset first member is struct scullQset *next and second member is void **data,double pointer data is basically
pointout memory(that store information(double pointer data that is first pointout qset and that qset pointout quantum
that quantum store information(the size of quantum is 8 bits)).
In application we perform some task like open,write,read,close.in application firstly we want to open a node.than we using open system call(sys/open).in open system call we define two arr(string(file name),mode(permission)),that system call are define in glibe ,they open the node and return highest avalible fd.
container_of:-
In container_of(ptr,type,member) in which first argument is pointer to i_cdev member of struct inode,2nd argument is user defined structure which contains pointer to struct cdev and third argument is pointer to struct cdev.Actually struct cdev is actual representation of the device.Now return of container_of will be starting address of mapped memory(sculldev).
now node open application full access on node ,application any opertion perform like read ,write,close .but in my application first i write than lseek than again write after write read data.application write data driver will start write on memory(with the help of copy_from_user).first they check the size of data.than they check how many scullqset,qset and quantum needed and they create that.after this they perform read task,that is very similiar write opertion(read opertion using with the help of copy_to_user).after read opertion done call scull_trim().that are free the memory.to free the memory using kfree.
application:
now write the multithread one application.in application perform some task open,read,write,close on different thread.now to test this firstly compile char driver .after this module_init insert using lsmod.than execute application.working fine.after finished application than remove driver to use rmmod.