3
votes

Here is my understanding in opening to a file for reading/writing.

In the application layer, I can invoke the fopen() function.

The fwrite() function will invoke a system call open().

After the OS receives the open() call, it will pass the command to VFS(virtual file system).

VFS looks up the file name, including any directories needed and does the necessary access checks.

If this is in RAM cache then no disk access is needed. If not, the VFS sends a read request to the specific file system which is probably EXT4.

Then the EXT4 file system driver will determine in what disk block that directory is located in. It will then send a read command to the disk device driver.


So now let's say I want to read an i2c device A attached to the board. And the file directory is /dev/i2c/A

  • Is there a major number for all devices? For example, Linux OS sets 180 as the major number for USB. So at the device side, is there a major number 180 in each USB device?

  • If the answer to 1st question is NO, then how can the Linux OS determine which type of device A is, is it just according to the file directory?

  • I think the answer to 2nd question maybe: at the boot initialization stage, there are some certain codes that have already mount that port to the file system using something like export()? So in fact, right after the booting stage, file directory /dev/i2c/A exists there and it is bind with a major number for i2c devices. So when I want to open dev/i2c/A, the OS will find the right i2c driver for me, not the SPI or USB driver.I'm not sure about this part, i need more information on this.

  • The above situation happens when the device is mounted to the file system right after the booting stage. so what happened if I have a usb, how can this usb be mounted to the file system with the right major number 180 after it is plugged in? And I guess there is a irq when the usb is plugged in before the mounting stage starts?

2
This question's title does not match the content. The content is about How does Linux determine which driver will be open for a particular path in the /dev/ tree. The question of what driver is selected for a device is completely different: i.e. identification of peripherals by heuristic probing, or with help from a "plug and play" system.Kaz
A very similar question which was also closed.artless noise

2 Answers

8
votes

See: hotplug doc. If you run the sample code, you can see that a netlink event is sent when a device is added/removed from USB. This is part of the driver model. Each driver should attach to a BUS; this can be platform, USB, I2C, SPI, PCI, etc. As well, with in the sysfs, there will be entries to identify the particular device. Often an I2C address can be used to identify a particular client/slave chip. The driver model also facilitates suspend, resume, ordered shutdown, etc.

The files in /dev/ are created by udev or mdevuser-space programs . They associate a name with a device node (major,minor,char/block). You can use sysfs and/or your udev script to create a device name that you want based on netlink information; most of which is available to udev scripts.

Edit: For i2c the bus master driver discovers the address of devices by running a probeNote 1. A device is associated with a particular driver with a table. For example, the stargate machine file has imote2_i2c_board_info which associates i2c addresses with drivers. A similar table exists for SPI devices. PlatformNote 2 devices are added with platform_add_devices(). USB and PCI devices are identified by similar BUS specific ids of a device. Usually a machine file (or more recently device tree) associates the two.
See Also: Linux Journal - I2C Drivers pt1, Linux Journal - I2C Drivers pt2

I believe a source of confusion is that all drivers/devices are those you see in the /dev/ directory. This is not true. Only top level drivers are seen by users. Many Linux drivers/devices are used by a master device. They can form a hierarchy of devices. Usually only the top level device is exposed to the user. There are functions such as spi_write(), that a higher level driver can use to talk via SPI, the SPI device is not exposed to user space. Sound and media/tv capture cards often use an SPI device, but the user never knows this BUS exists and is being used. Often multiple card vendors will use the same chip-sets underneath. Instead of writing drivers for every card, only some glue for the card is written. Then a generic collection of chip drivers are used with the glue to tie it all together at the top of the hierarchy; this is the top level driver that is exposed to user space. This also allows smartTM chip vendors to create good drivers that system integrators can use.

Note 1: By i2c probe, I mean an I2C message that requests all registered addresses on the bus. I am not sure if probe is the correct i2c nomenclature.

Note 2 Platform devices are SOC devices. They have no associated BUS, so platform is a catch-all. Typically, platform devices are integrated with the CPU (SOC stands for system on chip).

1
votes

Every device has a major and minor number. You can see them by doing ls -n /dev For some drivers, like the disk, the major numbers are hard coded. For others it is dynamic. Minor numbers can be assigned dynamically as devices are discovered at runtime, not just at boot. The kernel maintains an internal device switch table that maps the dev numbers to the correct driver.