I would like to know how Linux, such us Ubuntu, "know" how and what drivers to install when installing it from scratch. For example, I buy a new computer without any system and I install Ubuntu. Inside my PC I have a GPU, HDDs, etc., also some peripherals, like mouse, keyboard, etc. Obviously, a fresh install does not have drivers needed for the system to control and communicate with the hardware so how does Ubuntu "know" what drivers to install/download and how does it do that?
All peripherals identify themselves with mostly unique IDs. Some IDs are for generic interfaces (HDD/mouse,etc). Linux has most drivers built in, and the generic drivers have compatibility lists for IDs that support a limited feature set.It gets more complicated but dmesg, lscpu, hwinfo, lshw, dmidecode, lspci, etc will list the IDs if you want to look
(Based on Google-cached copy of http://people.skolelinux.org/pere/blog/Modalias_strings___a_practical_way_to_map__stuff__to_hardware.html by Petter Reinholdtsen.)
In the hardware, there are certain standard device identifiers that can be accessed as long as you know the standard access method for that particular I/O bus or subsystem, without having any further knowledge about the actual device. In Linux, these identifiers are used to build up modalias strings, which are then used to find the correct driver for each device.
The source code of each driver module can include
MODULE_DEVICE_TABLE structures, which are used by the
depmod command to create module alias wildcard entries that will match the modalias strings of the hardware supported by that particular module.
When the kernel detects a piece of hardware with no matching driver loaded yet, it will create a modalias string from the identifiers of the hardware, and use it to request a module to be autoloaded. The
modprobe command will then use the
/lib/modules/$(uname -r)/modules.alias[.bin] file created by
depmod to see if a matching module exists. If it does, that module is loaded and gets to probe the hardware for further details if necessary.
For example, I have a DVB TV card:
$ lspci -v -nn -s 07:00.0 07:00.0 Multimedia video controller : Conexant Systems, Inc. CX23885 PCI Video and Audio Decoder [14f1:8852] (rev 04) Subsystem: Hauppauge computer works Inc. CX23885 PCI Video and Audio Decoder [0070:6a28]
This results in a modalias string like this:
cx23885 module has these aliases based on
MODULE_DEVICE_TABLE in its source code:
# modinfo cx23885 ... alias: pci:v000014F1d00008880sv*sd*bc*sc*i* alias: pci:v000014F1d00008852sv*sd*bc*sc*i* ...
When the kernel detects the card, it effectively runs the
modprobe pci:v000014F1d00008852sv00000070sd00006A28bc04sc00i00 command. The second alias of the
cx23885 module matches, and so that module gets loaded.
PCI/PCI-X/PCIe bus devices
This is the "PCI subtype". It uses modalias strings like this:
This can be decoded as follows:
v 00008086 (vendor) d 00002770 (device) sv 00001028 (subvendor) sd 000001AD (subdevice) bc 06 (bus class) sc 00 (bus subclass) i 00 (interface)
lspci -nn, you can see the class, subclass, vendor and device IDs. If you add the
-v option, you can also see the subvendor:subdevice IDs.
With USB devices, the modalias strings look like this:
This unpacks to:
v 1D6B (device vendor) p 0001 (device product) d 0206 (bcddevice) dc 09 (device class) dsc 00 (device subclass) dp 00 (device protocol) ic 09 (interface class) isc 00 (interface subclass) ip 00 (interface protocol)
lsusb command, you can see the vendor and product IDs. If you use the
-v option, you can see the other IDs too.
These use the ACPI PNP identifiers, prefixed with
acpi: and separated with colons:
This can be a very long modalias string:
This unpacks to:
bvn IBM (BIOS vendor) bvr 1UETB6WW(1.66) (BIOS version) bd 06/15/2005 (BIOS date) svn IBM (system vendor) pn 2371H4G (product name) pvr ThinkPadX40 (product version) rvn IBM (board vendor) rn 2371H4G (board name) rvr NotAvailable (board version) cvn IBM (chassis vendor) ct 10 (chassis type) cvr NotAvailable (chassis version)
SerIO devices, i.e. mostly PS/2 mice
The modalias string will look like this:
The values here are:
ty 01 (type) pr 00 (prototype) id 00 (id) ex 00 (extra)
Other bus/device types
There are many other bus types recognized by the Linux kernel. Studying the contents of the kernel source file file2alias.c might be helpful in deciphering the meaning of the components of each type of modalias string.