Opening Device Files

chrdev_open from fs/devices.c is the generic function for opening character devices. Figure 6-6 shows the associated code flow diagram.

chrdev_open

Find device specific file_operations

f_op-^pe^J

Figure 6-6: Code flow diagram for chrdev_open.

Figure 6-6: Code flow diagram for chrdev_open.

Assume that the inode that represents the device file has not been opened before. Given the device number, kobject_lookup queries the character device database introduced in Section 6.2.5 and returns the kobject instance associated with the driver. This, in turn, allows for obtaining the cdev instance.

With the cdev instance for the device in hand, the kernel also has access to the device-specific file_operations via cdev->ops. Various connections between data structures are then set up like Figure 6-7.

struct inode struct cdev struct fiie_operations

Figure 6-7: Relations between data structures for the representation of character devices.

□ inode->i_cdev points to the selected cdev instance. When the inode is opened next time, the character device database need not be queried anymore because the cached value can be used.

□ The inode is added to cdev->list (i_devices is used as the list element in the inode).

□ file->f_ops, that is, the file_operations for struct file, are set to point to the file_operations instance given by struct cdev.

The (now device-specific) open method of the new file_operations from struct file is then invoked to carry out the required initialization tasks on the device (some peripherals need to negotiate operating details by means of handshaking before they are used for the first time). The function can also be used to make the data structure changes needed for a specific minor number.

Let us consider the example of a character device with major number 1. According to the LANANA standard, this device has 10 different minor numbers; each provides a different function each provides a different function, each of which relates to memory access operations. Table 6-1 lists a few minor numbers together with the associated filenames and functions.

Some devices will be familiar, particularly the /dev/null device. Without going into the details of the individual minor numbers, it is clear from the device descriptions that there are considerable differences between the functions implemented, even though they are all concerned with memory access. It is therefore not surprising that, again, only a single function pointer is defined in the file_operations structure of the chrdevs entry; open points to memory_open after one of the above files has been opened.

The procedure is defined in drivers/char/mem.c and implements a dispatcher that distinguishes between the individual devices by reference to the minor number and selects the appropriate file_operations. Figure 6-8 illustrates how the file operations change when a memory device is opened.

The functions gradually reflect the special features of the device. Initially, only the general procedure for opening character devices is known. This is then replaced by a special procedure to open the memory-related device files. The function pointers are then refined even further depending on the minor number selected. The end products do not necessarily use identical functions, as the examples of null_fops (for /dev/null) and random_fops (for /dev/random) demonstrate.

Table 6-1: Minor Numbers for Major 1 (Memory Access).

Minor

File

Description

1

/dev/mem

Physical memory

2

/dev/kmem

Virtual kernel address space

3

/dev/null

Bit bucket

4

/dev/port

Access to I/O ports

5

/dev/zero

Source for null characters

8

/dev/random

Non-deterministic random generator

def_chr_fops memory_fops memory_fops mem_fops kmem_fops null_fops random_fops

Selected by major number mem_fops kmem_fops null_fops random_fops

Selected by minor number

Continue reading here: Figure 68 File operations when memory devices are opened

Was this article helpful?

0 0