Inode Device File

Source: Internet
Author: User

The device is not identified by its file name, butID of the Primary and Secondary device numbers of the file(The file name and the file's primary and secondary device numbers are displayed in the inode data area of the parent directory of the device file, which is the stuff at the FS Layer ).

 

Differences between a device file and a common file:

Command: ls-L/dev/

1: B/C before the access permission, indicating Block devices and character devices respectively.

2: Device FilesNo file lengthThe other two values are added, namely, the primary device number and the secondary device number. The two form a unique number, and the kernel can find the corresponding device driver.

Since the udev mechanism is introduced,/Dev is no longer placed in a disk-based file system, but uses tmpfs, a lightweight variant of RAM disk file system ramfs. This meansThe device node is not persistent.After the system is shut down/restarted, it will disappear.

 

IOCTL: The input/output control interface is a common interface used to configure and modify specific device properties.

 

 

If the kernel can understand which character devices and Block devices are available in the system, it is naturally advantageous. Therefore, a database must be maintained and an interface must be provided, this allows driver developers to add new items to the database.

Data structure:

1,Device database

Although Block devices and character devices are very different from each otherUsed to track all available devicesThe databases are the same. Because character devices and Block devices are identified by unique device numbers. However, the Database tracks different objects based on Block devices/character devices.

. Each character device is represented as a struct cdev instance.

. Struct genhd is used to manage the partition of a block device. It is used to manage the cdev.

There are two global arrays (Bdev_map is used for Block devices, and cdev_map is used for character devices.Is used to implement the hash, and the master device number is used as the hash key. Both cdev_map and bdev_map are instances of the same data structure struct kobj_map. The hash method is simple: Major % 255.

Struct kobj_map {
Struct probe {
Struct probe * next;
Dev_t dev;
Unsigned long range;
Struct module * owner;
Kobj_probe_t * Get;
INT (* Lock) (dev_t, void *);
Void * data;
} * Probes [255];
Struct mutex * lock;
};

The mutex lock serializes the access to the hash list. The members of struct probe are as follows:

Next: link all hash entries to a single linked list. (I have not figured out whether the device master device numbers in this single-chain table are the same?)

Dev: indicates the device number, including the primary and secondary device numbers.

Rang: the continuous range of device numbers is stored in range. The range of each slave device number associated with the device is [minors (Dev), minors (Dev) + range-1].

Owner: the module that provides the device driver.

Get: points to a function that returns the kobject instance associated with the device.

Data: The difference between a character device and a block device is data. For a character device, it points to an instance of struct cdev, and for a block device, it points to the instance of struct genhd.

 

2,Character device range Database

The second type of database is only used for character devices. It is used to manageDriver allocationThe range of device numbers. The driver can request a dynamic device number (using register_chrdev_region () functionRegister the device number), Or specify a range from which to obtain (using alloc_chrdev_region () functionAssign device number).

Use the scattered list again to track the range of allocated device numbers, and also use the primary device number as the hash key. The data structure is as follows:

Static struct char_device_struct {
Struct char_device_struct * next;
Unsigned int Major;
Unsigned int baseminor;
Int minorct;
Char name [64];
Struct cdev * cdev;/* future version of will die will be deleted */
} * Chrdevs [chrdev_major_hash_size];

Next: link all hash elements in the same hash row

Major: master device number

Baseminor is the smallest slave device that contains minorct serial number in a continuous range

Name provides an identifier for the device.

 

Association with file systems

Device File member in inode

Only list Driver-related members

Struct inode {

...

Dev_t I _rdev;

...

Umode_t I _mode;

...

Struct file_operations * I _fop;

...

Union {

Struct block_device * I _bdev;

Struct cdev * I _cdev;

};

....

};

I _mode: the unique identifier associated with a device file. The file type stored by the kernel in I _mode (Block-oriented/character-oriented)

The primary and secondary device numbers are stored in I _rdev.

I _fop is a collection of function pointers, including many file operations (open, read, write, etc.), which are used by Virtual File Systems for Block devices.

The kernel uses inode to indicate whether the block device or character device, and uses I _bdev/I _cdev to point to more details.

 

Standard File Operations

When you open a device file, all file system implementations call the init_special_inode function to create an inode (at the file system layer) for the character device or block device file ).

There is still a doubt that inode is created only when the device is opened. Isn't the FS system not creating inode when the device file is created, does FS only store the Device File ID and file name in the dentry of the/dev inode?

To solve the above problem, we need to note that inode is created when the device file is opened and when the device file is created, but the two inode are not the same and are two different types of data. The inode generated when the device file is created is stored in the hard disk. Its structure is relatively simple and will disappear as the device file is deleted. The inode created when the device file is opened is the struct inode structure, which is saved in Ram and disappears as the file is closed.

The following question is: "Does FS only store the Device File ID and file name in the dentry of the/dev inode ?" This assumption is incorrect. In this case, the/dev directory is a temporary folder and does not have inode nodes in the inode block, however, files in the directory contain inode nodes in the inode block. So we should think about it. How does FS find the files under the/dev directory? A device file is a special type of file. Its search method is different from that of a common file. In fact, the device file does not need to find the corresponding inode node on the disk, because the device file does not have a data zone at all, we need the device operation pointer (f_ops) of the device file ). how can I find the device operation pointer? You can check the simhei section below. (The above statement is applicable to character device files, but it does not check block devices, and does not know whether Block devices are similar. In fact, there is also a problem. According to the above explanation, we do not need to create an inode node for the device file on the disk, but the system is still created, it is certain that such an inode node is useful, and the system will not do anything meaningless)

Void init_special_inode (struct inode * inode, umode_t mode, dev_t rdev)
{
Inode-> I _mode = mode;
If (s_ischr (mode )){
Inode-> I _fop = &Def_chr_fops;
Inode-> I _rdev = rdev;
} Else if (s_isblk (mode )){
Inode-> I _fop = &Def_blk_fops;
Inode-> I _rdev = rdev;
} Else if (s_isfifo (mode ))
Inode-> I _fop = & def_fifo_fops;
Else if (s_issock (mode ))
Inode-> I _fop = & bad_sock_fops;
Else
Printk (kern_debug "init_special_inode: bogus I _mode (% O)/n", mode );
}

Used for standard operations on character Devices

FS/device. c

Const struct file_operations def_chr_fops = {
. Open = chrdev_open,
};

The main task of the chrdev_open () function isThis structure (in fact, I don't understand what structure this structure refers to, and it seems a bit like struct file)Fill in the function pointer (file_operation) that has enabled the device to perform meaningful operations on the device file and ultimately operate the device itself.

Block Diagram of the chrdev_open () function:

It indicates that the inode of the device file has not been opened before,Based on the device number, kobject_lookup queries the database (cdev_map) of the character device and returns the associated kobject instance with the driver. The returned value can be used to obtain the cdev instance..

After obtaining the cdev instance corresponding to the device, the kernel can access the file_operations specific to the device through cdev-> ops. Next, set the associations between various data structures.

Inode-> I _cdev points to the selected cdev instance. When this inode is enabled next time, you do not have to query the database of the character device because the cached value can be used.

This inode will be added to cdev-> List

File-> f_ops is the new file_operations used for struct file. It is set to point to the file_operations instance given by struct cdev.

Next, call the OPEN function in the new file_operations of the struct file (currently used for specific devices, the open function implemented by specific devices at the driver layer ), perform the required initialization tasks on the device.

Used for block device standard operations

FS/block_dev.c

Const struct file_operations def_blk_fops = {
. Open = blkdev_open,
. Release = blkdev_close,
. Llseek = block_llseek,
. Read = do_sync_read,
. Write = do_sync_write,
. Aio_read = generic_file_aio_read,
. Aio_write = generic_file_aio_write_nolock,
. MMAP = generic_file_mmap,
. Fsync = block_fsync,
. Unlocked_ioctl = block_ioctl,
# Ifdef config_compat
. Compat_ioctl = compat_blkdev_ioctl,
# Endif
. Splice_read = generic_file_splice_read,
. Splice_write = generic_file_splice_write,
};

Although file_operations and block_device_operations have a similar structure, they cannot be confused. File_operations is used by the VFS layer to communicate with user space. Functions in file_operations are called by the user layer. The functions call the functions in block_device_operations to communicate with Block devices. Block_device_operations must be implemented for various Block devices separately, and device attributes must be abstracted. On this basis, file_operations can be created to allow users to use the same operations (functions provided by file_operations) all Block devices can be processed.

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.