59

Usually kernel source are stored in /usr/src/linux-2.6.x/. To avoid to recompile the entire kernel if I modify a module's source, how can I recompile just that module?

red0ct
  • 4,840
  • 3
  • 17
  • 44
user1056635
  • 785
  • 2
  • 9
  • 12

5 Answers5

62

Switch to the root directory of your source tree and run the following command:

$ make modules SUBDIRS=drivers/the_module_directory

And to install the compiled module:

$ make modules_install SUBDIRS=drivers/the_module_directory

Note: As lunakid mentions, the latter command might not build the module first, so be careful.

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
  • (Just make sure you run that in the tree root, unlike me. ;) ) – Sz. May 12 '14 at 12:17
  • @lunakid Good point ;) Although it should be pretty clear that `SUBDIRS` is relative to the CWD :P – Niklas B. May 12 '14 at 12:19
  • It's definitely clear, but then I still found myself sitting in the wacom driver dir in the end. :) Just not watched my steps. Also, could you please add to your answer that it can also be **installed** the same way, just putting `make modules_install SUBDIRS=...`. That's almost certainly the next step, and may not be immediately trivial (even though it seems so, after e.g. I spent some minutes googling it in vain... :) ). Thx, cheers! – Sz. May 12 '14 at 12:27
  • @lunakid Done. I assume modules_install also builds, so it's really a one-step process – Niklas B. May 12 '14 at 12:29
  • +1, thx. As to build+install: seems not: it unfortunately just craps itself, if this is indeed what it feels like: INSTALL drivers/input/touchscreen/wacom_w8001.ko cp: cannot stat 'drivers/input/touchscreen/wacom_w8001.ko': No such file or directory DEPMOD 3.4.34-x61t` (Still runs DEPMOD, though, that's why I'm unsure.) – Sz. May 12 '14 at 12:37
  • @lunakid Ok thanks for the feedback, I incorporated this into my answer – Niklas B. May 12 '14 at 12:38
  • Great job, too bad I can't +2 it. :) – Sz. May 12 '14 at 12:39
  • This solution does not work. Trying this with `mmc_block.ko` returns a message that says something like `No rule to make block.o`. – Melab Dec 04 '15 at 13:10
  • Once we have done make_install, does it also load the library? I tried rmmod dm_raid (module that I was building), checked if it had successfully been removed, and then again inserted the module. Still I do not see updated printk's I have placed in my new instrumented module. Can you please tell if we need to do other things after make_install so that changes in driver get reflected? – Shehbaz Jaffer Dec 31 '15 at 03:32
24

since kernel versions 3.x.x and 4.x.x the procedure gets more complicated (but there is a hope, so keep reading):

  1. make distclean if you haven't just cloned a new source but used to build other modules before
  2. create new folder somewhere for the module source (example: extra) and copy only source files (from the kernel source or somewhere else) related to the module needed to be build into this new folder
  3. copy /boot/config-`uname -r` file (example: /boot/config-4.8.0-46-generic) into kernel source folder file .config and run make oldconfig. if the module belongs to the kernel source, verify if it has been enabled by calling make menuconfig, by searching for the module and applying letter 'M' if necessary
  4. kernel source root Makefile has to be altered with exact version components matching the current running one (you may verify with make kernelversion if it matches exactly the uname -rone)
  5. there is been a strong suggestion to build scripts also before with make scripts
  6. make prepare and make modules_prepare has to be executed prior to the actual module build
  7. Module.symvers has to be copied from the target system headers folder corresponding running kernel version /usr/src/linux-headers-`uname -r`/Module.symvers (example: /usr/src/linux-headers-3.13.0-117-generic/Module.symvers) into the newly created module source files folder prepared for the module compilation (the one extra in example).
  8. create new Makefile inside module source compilation folder having following line: obj-y += <module_source_file_name>.o or if the source code is complicated, use the guidance from here
  9. only then it's the right time to build module with make -C <kernel source path> M=the_module_directory (example: make -C . M=extra/)
  10. Use command modprobe --dump-modversion <module_name>.ko to verify CRC match between module exporting API and corresponding values in Module.symvers. in case of failure use command modinfo <module_name>.ko instead
  11. verify if kernel.release file content match exactly the one from headers of the current running version. if you'll discover + appended at the end, it means you've been compiling git clonned source and your experimental modifications caused build system to compromise the localversion string by adding + at the end.
  12. if only + has been discovered at the tail of kernel.release stored value and it's a mismatch with the exact name of the target running kernel,

the solution would be following:

commit all your changes, force release tag to shift above your modifications with the git tag -a <tag version> -f command. then rebuild your modules from step 8

Oleg Kokorin
  • 2,288
  • 2
  • 16
  • 28
  • If the driver has its own subdirectory (e.g. linux/drivers/net/ethernet/natsemi) is it still necessary to copy the driver code into its own "extra" folder? – novice Aug 07 '19 at 19:07
  • FYI for others who may run into `Symbol version dump "vmlinux.symvers" is missing.`: You may need to `cp Module.symvers vmlinux.symvers` in your Linux source tree. – KJ7LNW Feb 28 '23 at 02:02
9

You can pass the path to the module name or module directory to make as parameter.

make path/to/the/module/itself.ko
make path/to/the/module/directory/
Szilárd Pfeiffer
  • 1,636
  • 1
  • 12
  • 6
  • 1
    make path/to/the/module/itself.ko takes much more time comparing to the make modules SUBDIRS=directory/path (3 minuts vs 5 seconds). Actually, just the make path/to/directory doesn't seems to work, it always say "Nothing to be done", but I did modify the code – Lilás Jun 07 '15 at 18:25
7

In case you have edited just code in drivers/net/ethernet/intel/e1000/e1000_main.c file

Build the module.

make scripts prepare modules_prepare
make -C . M=drivers/net/ethernet/intel/e1000

Install the module.

cp drivers/net/ethernet/intel/e1000/e1000.ko /lib/modules/5.1.15/kernel/drivers/net/ethernet/intel/e1000/e1000.ko
siz
  • 114
  • 1
  • 5
4
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install

https://askubuntu.com/questions/515407/how-recipe-to-build-only-one-kernel-module

rocky
  • 191
  • 1
  • 8