[Linux Driver] character device driver learning Note (i)

Source: Internet
Author: User
Tags goto semaphore

One, what does the main device number and the secondary device number mean? Linu kernel is if the main device number to find the driver, the secondary device number to find the device.

A: Usually a main device number represents a driver, for example, in a block device, a master device number represents a EMMC device, the different secondary device number represents a different partition

The Linux kernel allows multiple drives to share a master device number, but more devices follow a principle that drives a master device number. Kernel maintainer a global hash table with the main device number key, while the data portion of the hash table is a pointer to the driver (only one secondary device) corresponding to the master device number device, or a pointer to an array of multiple secondary device drivers (secondary device shared master number)

Second, write the general order of the character devices

First, call the Kmalloc memset function to initialize the related struct (such as the device structure)
Second, register the corresponding driver, such as platform driver call Platform_driver_register (&driver) to register, driver is a full static variable.

[CPP]View Plaincopy
  1. struct test_dev{
  2. struct Cdev cdev;
  3. Char *test_devname;
  4. Char actname[32];
  5. unsigned int index;
  6. struct Semphare sem;
  7. }
  8. Static struct Platform_driver test_driver = {
  9. . Probe = Test_probe,
  10. . remove = Test_remove,
  11. . Driver = {
  12. . Name = "Test_char",
  13. . Owner = This_module,
  14. },
  15. };
  16. #define TEST_NUM 10
  17. Static struct Test_dev *test_devices;
  18. static int __init test_init (void)
  19. {
  20. int result;
  21. Test_devices=kmalloc (test_num*sizeof (struct test_dev), gfp_kernel);
  22. if (!test_devices)
  23. {
  24. result =-enomem
  25. PRINTK ("Alloc test_devices fail\n");
  26. Goto Fail_malloc;
  27. }
  28. memset (test_devices,0,test_num*sizeof (struct test_dev));
  29. result = Platform_driver_register (&test_driver);
  30. if (result)
  31. {
  32. PRINTK ("fail to register Test_driver");
  33. Goto Fail_driver_register;
  34. }
  35. return 0
  36. Fail_driver_register:
  37. return result;
  38. Fail_malloc:
  39. return result;
  40. }
  41. Module_init (Test_init);



Third, the next call to the Test_probe () function, which first assigns the main device number and the secondary device number to the Alloc_chrdev_region () function, and then calls the Cdev_init () function to register the true character device, void Cdev_init ( struct cdev*cdev,struct file_operations *fops) finally calls the Cdev_add () function to tell the kernel the structure of the information for the Init cdev_add (struct cdev*cdev,dev_t num, unsigned int count)

[CPP]View Plaincopy
  1. int Test_probe (struct platform_device *dev)
  2. {
  3. int result;
  4. dev_t Devno;
  5. result = Alloc_chrdev_region (&devno,0,test_num,"Testchar");
  6. if (result<0)
  7. {
  8. PRINTK ();
  9. Goto Fail_alloc_chrdev;
  10. }
  11. Major = Major (DEVNO);
  12. For (int i=0;i<test_num;i++)
  13. {
  14. Devno=mkdev (Major,i);
  15. Cdev_init (&test_devices[i].cdev,&test_fops);
  16. Test_devices[i].cdev.owner = This_module;
  17. Test_devices[i].cdev.ops = &test_fops;
  18. result = Cdev_add (&test_devices[i].cedv,devno,1);
  19. if (result)
  20. {
  21. PRINTK ("Cdev add fail\n");
  22. Goto Fail_register_chrdev;
  23. }
  24. }
  25. return 0;
  26. Fail_register_chrdev:
  27. Cdev_del (&test_devices[i].cdev);
  28. Unregister_chrdev_region (MKDEV (major,0), test_num);
  29. }



Three, blocking I/O

If, in the read write method of the calling character device, the device is not ready to cause the process to be read by the user layer to block (the default), place it in hibernation until the request can continue. Place the process into hibernation two points to note
(1) Do not sleep in the atomic context, the driver can no longer have a spin lock, RCU lock time Sleep, the process of having a semaphore sleep is legal, but waiting for this semaphore of other processes must also sleep, so the process has a semaphore time to sleep short enough
(2) When the process wakes up without knowing what has happened, check to make sure that the conditions we wait for are really true.
Ways to let the process hibernate:
Wait_event () Related functions
Wake-up Process method
WAKE_UP () Related functions

How to implement non-blocking I/O operations
A: Fill the O_nonblock flag in the Filp->f_flags, if open in a non-blocking way, if the device does not have ready data at this time, then the-eagain error will be returned.

Four, the device file access control

1, let a process exclusive device, by maintaining an atomic variable

Use instance: the ADB driver, which only lets ADBD one process use the device at a time.

[CPP]View Plaincopy
  1. static int Scull_s_poen (struct inode*inode,struct FILE*FILP)
  2. {
  3. struct Scull_dev *dev = &scull_s_device;
  4. if (!atomic_dec_and_test (&scull_s_available)) {
  5. Atomic_inc (&scull_s_available);
  6. Return-ebusy;
  7. }
  8. if ((Filp->flags & O_accmode) ==o_wronly)
  9. Scull_trim (Dev);
  10. filp->priate_data=dev;
  11. return 0;
  12. }


2, limit access by only one user at a time

[CPP]View Plaincopy
    1. Spin_lock (&scull_u_lock); //scull_u_lock is a global variable, so with spin lock, the use of optional lock can not sleep
    2. if (Scull_u_count && (scull_u_owner! = current->uid) && (scull_u_owner! = current->euid) & &!capable (Cap_dac_override))
    3. {
    4. Spin_unlock (&scull_u_lock);
    5. Return-ebusy;
    6. }
    7. if (Scull_u_count = = 0)
    8. {
    9. scull_u_owner=current->uid; //The first user to access the device belongs to the primary user
    10. }
    11. scull_u_count++;
    12. Spin_unlock (&scull_u_lock);

[Linux Driver] character device driver learning Note (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.