Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Linux built-in driver load order?

How can we customize the built-in driver load order (to make some built-in driver module load first, and the dependent module load later)?

like image 326
Dien Nguyen Avatar asked Jul 25 '12 03:07

Dien Nguyen


People also ask

How does Linux load drivers?

Most of the Linux device drivers can be loaded on demand as kernel modules when they are needed and unloaded when they are no longer being used. This makes the kernel very adaptable and efficient with the system's resources, Configurable. Linux device drivers can be built into the kernel.

How do you check what drivers are loaded in Linux?

Run the command lsmod to see if driver is loaded. (look for the driver name that was listed in the output of lshw, "configuration" line). If you did not see the driver module in the list then use the modprobe command to load it.

What is driver model in Linux?

The Linux Kernel Driver Model is a unification of all the disparate driver models that were previously used in the kernel. It is intended to augment the bus-specific drivers for bridges and devices by consolidating a set of data and operations into globally accessible data structures.

How does Linux load modules?

In Linux, all modules end with the . ko extension, and they are normally loaded automatically as the hardware is detected at system boot. However a system administrator can manage the modules using certain commands.


2 Answers

Built-in drivers wont be loaded, hence built-in. Their initialization functions are called and the drivers are activated when kernel sets up itself. These init functions are called in init/main.c::do_initcalls(). All init calls are classified in levels, which are defined in initcall_levels and include/linux/init.h

These levels are actuall symbols defined in linker script (arch/*/kernel/vmlinux.lds.*). At kernel compile time, the linker collects all function marked module_init() or other *_initcall(), classify in levels, put all functions in the same level together in the same place, and create like an array of function pointers.

What do_initcall_level() does in the run-time is to call each function pointed by the pointers in the array. There is no calling policy, except levels, in do_initcall_level, but the order in the array is decided in the link time.

So, now you can see that the driver's initiation order is fixed at the link time, but what can you do?

  1. put your init function in the higher level, or
  2. put your device driver at the higher position in Makefile

The first one is clear if you've read the above. ie) use early_initcall() instead if it is appropriate.

The second one needs a bit more explanation. The reason why the order in a Makefile matter is how the current kernel build system works and how the linkers works. To make a long story short, the build system takes all object files in obj-y and link them together. It is highly environment dependent but there is high probability that the linker place first object file in the obj-y in lower address, thus, called earlier.

If you just want your driver to be called earlier than other drivers in the same directory, this is simplest way to do it.

like image 85
Yasushi Shoji Avatar answered Sep 21 '22 13:09

Yasushi Shoji


depmod examines the symbols exported and required by each module and does a topological sort on them that modprobe can later use to load modules in the proper order. Requiring the symbols from modules you wish to be dependent on is enough for it to do the right thing.

like image 30
Ignacio Vazquez-Abrams Avatar answered Sep 22 '22 13:09

Ignacio Vazquez-Abrams