title: Building out-of-tree kernel modules, depmod - and, why reboot?
body: <p>I've been working with a userland program <code>writeread.c</code> (referred <a href="https://stackoverflow.com/questions/3701955/serial-port-loopback-duplex-test-in-bash-or-c-process-substitution">here</a>), utilizing the <code>ftdi_sio</code> Linux driver.</p>
  
  <p>I had worked with the default <code>ftdi_sio</code> that comes with Ubuntu Lucid that I use - and then, as a sanity check, decided to rebuild <code>ftdi_sio</code> from source. I did not want to download the entire kernel source, so I opted for so called "building out-of-tree modules":</p>
  
  <ul>
  <li><a href="http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html" rel="nofollow noreferrer">Howto: Build Linux Kernel Module Against Installed Kernel w/o Full Kernel Source Tree</a></li>
  <li><a href="http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-out-of-tree" rel="nofollow noreferrer">Debian Linux Kernel Handbook - Common kernel-related tasks: Building out-of-tree kernel modules</a></li>
  <li><a href="http://fedoraproject.org/wiki/Docs/CustomKernel#Building_Only_Kernel_Modules_.28Out_Of_Tree_Modules.29" rel="nofollow noreferrer">Building a custom kernel - FedoraProject: Building Only Kernel Modules (Out Of Tree Modules)</a></li>
  </ul>
  
  <p>... which means you can only have installed <code>linux-headers-*</code> packages (instead of having entire <code>linux-source-*</code> installed) - and the respective kernel module source - in order to build a kernel module. </p>
  
  <p>So, I basically got the following files in a folder:</p>
  
  <ul>
  <li><a href="http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-lucid.git;a=blob_plain;f=drivers/usb/serial/ftdi_sio.c" rel="nofollow noreferrer">ftdi_sio.c</a></li>
  <li><a href="http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-lucid.git;a=blob_plain;f=drivers/usb/serial/ftdi_sio.h" rel="nofollow noreferrer">ftdi_sio.h</a></li>
  <li><a href="http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-lucid.git;a=blob_plain;f=drivers/usb/serial/ftdi_sio_ids.h" rel="nofollow noreferrer">ftdi_sio_ids.h</a></li>
  <li>Makefile (included below) </li>
  </ul>
  
  <p>and ran <code>make</code> - and a <code>ftdi_sio.ko</code> kernel objects compiles, which also can be <code>insmod</code>-ed without a problem. </p>
  
  <p>&nbsp;</p>
  
  <p>The problem is now here - as long as I work with low speeds (115200 bps), there is <em>no observable difference</em> between: loading the 'vanilla' driver (<em>using <code>sudo modprobe ftdi_sio</code></em>); and loading the newly built driver (<em>using <code>sudo modprobe usbserial; sudo insmod /path/to/ftdi_sio.ko</code></em>) - in respect to the performance of the userland program (<code>writeread.c</code>).</p>
  
  <p>However, if I try the same at 2000000 bps, then the 'vanilla' driver works fine -  while the build driver causes a <strong>segfault</strong> of the userland program (<code>writeread.c</code>). In particular, this segfault happened at <code>free()</code>-ing memory resources - because the driver would end up reading <em>more</em> bytes from the loopback connection, than it itself would write! However, that in itself is not that relevant for this discussion, because I finally found a way to get the built <code>ftdi_sio</code> to work (<em>Edit: just noticed that a similar procedure is also given in <a href="https://stackoverflow.com/questions/2237871/external-linux-kernel-module-dependencies/2238581#2238581">External Linux kernel module dependencies R#2238581 - Stack Overflow</a></em>): </p>
  
  <pre><code>$ sudo modprobe -r ftdi_sio # remove 'vanilla' driver from memory 
  ...
  # build the driver
  $ cd /path/to/ftdi_sio_2.6.32/
  $ make clean &amp;&amp; make 
  
  # check vanilla version
  $ ls -la /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
  -rw-r--r-- 1 root root 102396 2010-10-17 01:47 /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
  
  # (re)move the 'vanilla' kernel object
  $ sudo mv /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko ~/Desktop/ftdi_sio_orig.ko  
  
  # symlink our built version, as if it is the 'vanilla' one
  $ sudo ln -s /path/to/ftdi_sio_2.6.32/ftdi_sio.ko /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/
  
  # check 
  $ ls -la /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko
  lrwxrwxrwx 1 root root 57 2010-10-26 12:49 /lib/modules/2.6.32-25-generic/kernel/drivers/usb/serial/ftdi_sio.ko -&gt; /path/to/ftdi_sio_2.6.32/ftdi_sio.ko
  
  # call depmod
  $ sudo depmod
  
  # !! plug in USB at this point, built driver autoloads;
  # however, running `writeread.c` will segfault!
  
  # !! REBOOT at this point
  
  # after reboot:
  # !! plug in USB at this point, built driver autoloads;
  # and `writeread.c` runs without segfault
  </code></pre>
  
  <p>So, my <strong>question</strong> is: can anyone clarify to me, why - even after running <code>depmod</code> - do I <em>still</em> have to reboot, to have the built driver behave properly? In other words: is there any other command I could call (<em>maybe after <code>depmod</code></em>), so that the driver works properly when it's loaded, <em>without</em> rebooting? </p>
  
  <p>The reason I'm asking, is that I suspect that upon each recompilation of the kernel module, the symbol table will change - so to ensure that it works properly, I'd have to run <code>depmod</code> and reboot after each time the driver is built - which I think would be kind of tedious :) So, it would be nice to be able to rebuild the kernel module, and use it in the same session - without having to reboot. </p>
  
  <p>&nbsp;</p>
  
  <p>Well, thanks in advance for any answers, </p>
  
  <p>Cheers!!</p>
  
  <p>&nbsp;</p>
  
  <p>&nbsp;</p>
  
  <p>Makefile:</p>
  
  <pre><code>CONFIG_MODULE_FORCE_UNLOAD=y
  # flags passed to gcc for compilation - -v:verbose, -H:show include files
  # KBUILD_CFLAGS += -v
  # for debugging make itself, use --debug=i in make command for targets
  
  # debug build:
  EXTRA_CFLAGS=-g -O0
  
  KVERSION = $(shell uname -r)
  
  obj-m += ftdi_sio.o
  
  all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
  
  clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
  </code></pre>