3. File, Inode structure and Chardevs array and other related knowledge analysis

Source: Internet
Author: User

50850004
Describes the function call relationships between virtual file systems in Linux, generic device files and device drivers

shows an application calling character device-driven process, in the design of the device driver, in general, will care about the file and inode of the two structures
User space using the open () function opens a character device FD = open ("/dev/hello", O_RDWR), this function calls two data structure struct inode{...} With struct file{...}, both of which are located at the virtual file system VFS, the following two data structures are parsed:

1. File structure
(1) This is a very important data structure in the device driver.
(2) The file in this case is different from the file pointer in the user space, the user space file is defined in the C library and never appears in the kernel. The struct file is the data structure in the kernel, so it does not appear in the user-level program.
(3) The file structure indicates an open document (device corresponding device file), in fact, each open file in the system has a corresponding struct file structure in the kernel space, which is created by the kernel when the file is opened and passed to any function on the process operation on the file until the file is closed. If the file is closed, the kernel releases the corresponding data structure.
(4) in the kernel source code, the struct file is either represented as file, or Filp (meaning "file pointer"), note that the file refers to the struct file itself, and FILP is a pointer to the struct body.

Here are a few important members
A--fmode_t f_mode;
This file mode is Fmode_read, Fmode_write identifies the file as readable, writable, or both. In the open or IOCTL function, you may need to check this field to confirm the read/write permission of the file, you do not have to directly detect read or write permissions, because the kernel itself needs to detect the permissions when doing OCTL operations.
B--loff_t f_pos;
The location of the current read and write file. is 64 bits. If you want to know where the current file is located, the driver can read the value without changing its position. For Read,write, when it receives a loff_t pointer as its last parameter, their read and write operations update the location of the file without the need to perform the FILP->f_pos operation directly. The purpose of the Llseek method is to change the location of the file.
C--unsigned int f_flags;
File flags, such as O_rdonly, O_nonblock, and O_sync. You can also check the O_NONBLOCK flag in the driver to see if there are non-blocking requests. Other signs are less used. It is particularly important to note that read and Write permissions are checked using F_mode instead of F_flog. All scalar definitions in the header file
D--struct file_operations *f_op;
Various actions related to the file. When a file needs to perform various operations quickly, the kernel assigns this pointer as part of its implementation of file opening, reading, and writing functions. Filp->f_op its value has never been saved by the kernel as the next reference, which means you can change the various actions associated with the file, which is very efficient.

e--void *private_data;
The open system call sets this pointer to a null value before the drive calls the open method. You can be free to make it your own data domain or whatever it is, such as you can point to a well-allocated data, but you must remember to release the memory space of the data in the release method before the file struct is destroyed by the kernel. Private_data is useful for saving various state information during a system call.

2. Inode structure
The VFS inode contains information such as file access rights, owner, group, size, generation time, access time, last modified time, and so on. It is the most basic unit of Linux management file system, and also the bridge of file system connection any subdirectory, file.
The kernel uses the inode struct to represent a file inside the kernel. Therefore, it is different from the struct that represents a file descriptor that has been opened (that is, the file structure), and we can use multiple file structures to represent multiple files descriptors for the same file, but all of these file structures must point to only one inode struct at this point.
The inode structure contains a whole bunch of file-related information, but for driver code, we only care about two of these domains:

(1) dev_t I_rdev;
Represents the node for a device file, which actually contains the device number.

(2) struct Cdev *i_cdev;
struct Cdev is an internal structure of the kernel that is used to represent a character device, which is a pointer to the INODE structure when the Inode node points to a character device file.

  1. struct Inode {
  2. struct Hlist_node i_hash;
  3. struct List_head i_list;
  4. struct List_head i_sb_list;
  5. struct List_head i_dentry;
  6. unsigned long I_ino;
  7. atomic_t I_count;
  8. unsigned int i_nlink;
  9. uid_t I_uid;//inode Owner ID
  10. gid_t I_gid;//inode belongs to group ID
  11. dev_t i_rdev;//If the device file indicates the device number of the recording device
  12. U64 i_version;
  13. loff_t I_size;//inode is the representative of the very small
  14. #ifdef __need_i_size_ordered
  15. seqcount_t I_size_seqcount;
  16. endif
  17. struct Timespec I_atime;//inode last access time
  18. struct Timespec I_mtime;//inode Last modified time
  19. Build time of struct Timespec I_ctime;//inode
  20. unsigned int i_blkbits;
  21. blkcnt_t i_blocks;
  22. unsigned short i_bytes;
  23. umode_t I_mode;
  24. spinlock_t I_lock;
  25. struct Mutex I_mutex;
  26. struct Rw_semaphore I_alloc_sem;
  27. const struct Inode_operations *i_op;
  28. const struct File_operations *i_fop;
  29. struct Super_block *i_sb;
  30. struct File_lock *i_flock;
  31. struct Address_space *i_mapping;
  32. struct Address_space i_data;
  33. Ifdef Config_quota
  34. struct Dquot *i_dquot[maxquotas];
  35. endif
  36. struct List_head i_devices;
  37. Union {
  38. struct Pipe_inode_info *i_pipe;
  39. struct Block_device *i_bdev;
  40. struct Cdev *i_cdev;//If the character device, corresponding to the CDEV structure
  41. };

3. Chardevs Array
As you can see, Cdev is found by I_cdev members in the struct inode{...}, and all the character devices are in the Chrdevs array

    1. define chrdev_major_hash_size 255
    2. static Define_mutex (chrdevs_lock);
    3. static struct char_device_struct {
    4. struct char_device_struct *next;//struct pointer
    5. UN signed int major; Main device number
    6. unsigned int baseminor;//Secondary device start number
    7. int minorct;//Zeper number
    8. char name[64];
    9.   struct Cdev *cdev; * * would die */ 
    10. } *chrdevs[chrdev_major_hash_size]; can only hang 255 characters main device The
      can see that the global array Chrdevs contains the 255 (chrdev_major_hash_size value) elements of a struct char_device_struct, each corresponding to a corresponding master device number.
      If a device number is assigned, a struct Char_device_struct object is created and added to the Chrdevs so that by Chrdevs the array, we can know which device numbers are assigned.

Related functions, (these functions have been described in the previous article, now look back:
Register_chrdev_region assigning a specified range of device numbers
Alloc_chrdev_region Dynamic allocation Failure range
They are all implemented primarily by calling __register_chrdev_region, and note that these two functions are simply registered device numbers. If you want to associate the device number with the Cdev (used to represent the character device), call Cdev_add.
Register_chrdev applies the specified device number and registers it in the character device driver model.
What it does is:
A--register the device number, by calling __register_chrdev_region () to implement
B--Assign a Cdev, by calling Cdev_alloc () to implement
C-Adds Cdev to the drive model, which associates the device number with the driver. by calling Cdev_add () to implement the
D-the cdev of the struct Char_device_struct object created in the first step points to the Cdev assigned in the second step. Since Register_chrdev () is an old interface, this step is not required in the new interface.

4. Cdev Structural Body
In the Linux character device driver development The character device driver structure has been parsed.

5. Access to character device files in the file system

Let's take a look at the process by which the upper application open () calls the system call function.
For a character device file, its Inode.i_cdev points to the character device driver object Cdev, if I_cdev is null, the device file is not opened
Because multiple devices can share the same driver. Therefore, the i_devices in the inode of the character device and the list in cdev form a linked list.

First, the system calls open when a character device is opened, and through a series of calls, it is eventually executed to Chrdev_open
(Finally, by calling the. Open in Def_chr_fops, and Def_chr_fops.open = Chrdev_open.) This series of call procedures, this article is not discussed)
int Chrdev_open (struct inode * inode, struct file * Filp)
What Chrdev_open () can do is summarized as follows:
1. According to the device number (Inode->i_rdev), in the character device driver model to find the corresponding driver, which is implemented by Kobj_lookup (), Kobj_lookup () will return the corresponding driver Cdev kobject.
2. Set Inode->i_cdev to point to the found Cdev.
3. Add the inode to the linked list of the cdev->list.
4. Use Cdev's OPS to set the F_op of the file object
5. If the Open method is defined in OPS, the Open method is called
6. After the execution of Chrdev_open (), the f_op of the file object points to Cdev Ops, and then the read, write, and so on of the device will perform the corresponding action Cdev.

3. File, Inode structure and Chardevs array and other related knowledge analysis

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.