On Linux, why does `modprobe ext4` usually succeed where running `insmod` directly on the same ext4 module file fails, and what do depmod and modules.dep have to do with it?
answer
- one takes a path, one takes a name
- unresolved symbols, no lazy binding
- the map is generated, not written
- stale index after a manual copy
- modprobe.d only applies to one of them
basics
~20 smodprobe resolves dependencies: it looks the module up by name in modules.dep under /lib/modules/<kernel release> and loads everything it needs first, in order. insmod inserts exactly one file, so a module whose prerequisites are missing fails with an unknown-symbol error.
solid answer
~50 s`insmod` is the raw operation: hand it a path, it inserts that one object and nothing else. If the module references symbols exported by another module that is not loaded, the insert fails and the kernel log shows `Unknown symbol` lines. `modprobe` is the policy layer on top: it takes a module *name*, looks it up in `/lib/modules/$(uname -r)/modules.dep`, loads the dependency chain bottom-up, and also honours `/etc/modprobe.d` — aliases, `options` lines, `blacklist` and `install` rules. That dependency map is not maintained by hand; `depmod` builds it by scanning every module in the tree, reading the symbols each one exports and requires, and writing `modules.dep` plus the alias and symbol indexes. Package managers run `depmod` after installing a kernel or modules. If you drop a `.ko` into the tree yourself and forget to run `depmod`, `modprobe` will say the module is not found even though the file is right there.
go deeper
Know that modprobe is the command you normally use and that it takes a module name, while insmod takes a file path and does only that one insert. Say that modprobe pulls in what the module depends on.
Explain the dependency map: depmod scans the module tree, records exported and required symbols in modules.dep and the alias indexes, and modprobe reads them. Be able to name the unknown-symbol and version-magic failures.
Be able to debug a load failure end to end from the kernel log — distinguish a missing dependency, a vermagic mismatch and a stale index — and know that a hand-installed module without depmod is a repeatable production trap.
Own how modules reach a fleet at all: packaged in the kernel package, in a vendor package, or rebuilt per host. Argue for a build-and-package path where depmod, signing and indexes are handled by tooling rather than by an engineer copying files.
## Two tools, two altitudes Both ship in the same package (kmod) and both ultimately make the kernel link an object into itself, but they operate at different levels. - **`insmod <path>`** — a thin wrapper over the module-loading syscall. It takes a filesystem path, not a name. It knows nothing about dependencies, nothing about configuration, nothing about the module tree. What you point at is what gets inserted. - **`modprobe <name>`** — takes a module *name* or an alias, consults the indexes under `/lib/modules/<kernel release>/` and the configuration under `/etc/modprobe.d/`, and then performs however many inserts are needed, in the right order. It is also what removes a module together with the dependencies that become unused (`modprobe -r`). ## Why dependencies exist between modules Modules export symbols for other modules to use. A filesystem module leans on shared helper modules; a wireless driver leans on the generic stack module for its protocol family; a hardware driver leans on a bus or PHY library module. When the kernel links a module it must resolve every symbol the module references against symbols already present — in the built-in kernel or in modules already loaded. There is no lazy binding and no automatic fetch: unresolved means refused. So the ordering matters, and getting it right by hand is exactly the busywork `modprobe` exists to remove. ## What depmod actually produces `depmod` walks `/lib/modules/<release>/kernel/`, opens each module, and reads the metadata the compiler embedded in it: the symbols it exports, the symbols it needs, its declared aliases, its licence, its version magic. From that it writes several index files next to the tree: - `modules.dep` (plus a binary form) — for every module, the list of modules that must be loaded first. - `modules.alias` — the wildcard patterns that map hardware `modalias` strings and feature aliases to module names. This is what makes hotplug autoloading work. - `modules.symbols` — which module provides which exported symbol. These are *generated* files. They are stale the moment you add, remove or rebuild a module without re-running `depmod`, and a stale index is the cause of the classic "the file is right there and modprobe says it does not exist" confusion. ```bash # what would modprobe load, and in what order? modprobe --show-depends ext4 # rebuild the indexes after dropping a module into the tree by hand depmod -a ``` ## The failure messages, and what each one means - **`could not insert module …: Unknown symbol in module`**, with `Unknown symbol <name> (err -2)` in the kernel log. A prerequisite module is not loaded. This is the classic `insmod` failure and the reason `modprobe` exists. - **`Invalid module format`**, with `version magic '…' should be '…'` in the kernel log. The module was built for a different kernel. Every module carries a *vermagic* string — kernel release plus a handful of config attributes — and the kernel refuses a mismatch, because a struct layout it depends on may have changed silently. - **`Module <name> not found in directory /lib/modules/<release>`**. `modprobe` looked in the index for the running kernel and did not find that name. Either the module belongs to a different kernel, or `depmod` has not been run. - **`Operation not permitted`**. The caller lacks `CAP_SYS_MODULE`, or module loading has been disabled for the rest of the boot. ## When you still want insmod Driver development. You have just compiled a single `.ko` out of tree, it is not installed into `/lib/modules`, and you want to insert exactly that file and no other. `insmod ./mydriver.ko` does precisely that, and its bluntness is the point: no configuration file rewrites what you asked for, no alias resolves to some other module. As soon as the module is installed into the tree, `depmod` has been run, and other people have to load it, `modprobe` is the correct interface. ## The mental model to carry away `insmod` is a syscall with a path argument. `modprobe` is name resolution plus dependency resolution plus site configuration. Almost every "why will this module not load" question resolves to one of three things: the dependency chain, the version magic, or a stale index that `depmod` would fix.
- You copied a .ko into /lib/modules/$(uname -r)/kernel/drivers/ and modprobe says the module is not found. What is wrong?The indexes are stale. `modprobe` resolves names through `modules.dep` and the alias files, which are generated by `depmod` from the tree contents — it does not scan directories at load time. Run `depmod -a` (or `depmod <release>`) to regenerate them, then `modprobe` will find the module. Packages run `depmod` in their post-install scripts for exactly this reason.
- Does modprobe -r behave the same way as rmmod?No. `rmmod` removes the one module you name and stops. `modprobe -r` removes that module and then any modules it depended on that are now left with a zero reference count, walking the dependency chain back down. Both still refuse while something holds a reference; neither forces anything by default.
- What is version magic and why does the kernel refuse a module whose vermagic differs?Vermagic is a string compiled into every module recording the kernel release and a few build attributes such as SMP and preemption settings. Kernel internal structures are not a stable ABI — layouts and offsets change between builds — so a module compiled against different headers could corrupt memory. Refusing the load with "Invalid module format" turns a silent memory bug into an error at insert time.
saying these in an interview costs you the question
- Thinks insmod resolves dependencies like modprobe does
- Says missing symbols are bound lazily on first use
- Believes modules.dep is a file you edit by hand
- Forgets depmod after copying a module into the tree
- Assumes /etc/modprobe.d options apply to insmod too