-
Notifications
You must be signed in to change notification settings - Fork 0
/
gadgetfs-ubuntu.html
19 lines (17 loc) · 6.38 KB
/
gadgetfs-ubuntu.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!doctype html><meta charset=utf-8><title>make</title><meta content="Thomas Duboucher" name=author><meta content="Thomas Duboucher, Serianox,blog" name=keywords><meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name=viewport><link href=style.css rel=stylesheet><h1 id=using-gadget-filesystem-under-ubuntu>Using <em>Gadget Filesystem</em> under <em>Ubuntu</em></h1><p>I wanted to emulate a USB device in Linux for testing purpose. This can be done easily using the <a href=http://www.linux-usb.org/gadget/ >Gadget API</a>. However I quickly discovered that this feature was <a href=https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1073089>not present in Ubuntu</a>, even in the form of a kernel module in <em>linux-extra</em>. The only solution remaining was to rebuild the missing kernel module manually.<p>The main issue with a Linux kernel is that both the API and the ABI are not stable, meaning:<ul><li>You can’t use any source version of the module. The kernel API is evolving and you are likely to miss new or deprecated API. The current version of the <em>dummy_hcd</em> module does not compile due to newly introduced APIs. The matching kernel source is available in the <em>linux-extra</em> package.<li>You can’t keep a module you built for one version to another version. You must always rebuilt your module to match the current kernel ABI. Ideally the module must be known from <em>modprobe</em> to be correctly loaded along its dependencies. This is solved by using <em><a href=https://github.com/dell/dkms>DKMS</a></em>.</ul><p>Now the proces was fairly simple.<ol type=1><li>Install the package <code>linux-source</code> to have the kernel sources matching the currently installed kernel.</ol><p>This part is fairly easy.<div class=sourceCode id=cb1><pre class="sourceCode sh"><code class="sourceCode bash"><a class=sourceLine id=cb1-1 title=1><span class=fu>sudo</span> aptitude install linux-source</a></code></pre></div><ol type=1 start=2><li>Setup a build process that would extract the source of the <code>dummy_hcd</code> kmod from these sources and,</ol><p>For a Makefile, you can retrieve the current version of the kernel from <code>uname</code> plus some <code>grep</code>.<div class=sourceCode id=cb2><pre class="sourceCode makefile"><code class="sourceCode makefile"><a class=sourceLine id=cb2-1 title=1><span class=dt>SVERSION </span><span class=ch>:=</span><span class=st> </span><span class=ch>$(</span><span class=kw>shell</span><span class=st> uname -r | grep -o "^[^-]*"</span><span class=ch>)</span></a></code></pre></div><p>Then extract and move the <code>dummy_hcd.c</code> file from the current kernel source to the current folder.<div class=sourceCode id=cb3><pre class="sourceCode makefile"><code class="sourceCode makefile"><a class=sourceLine id=cb3-1 title=1><span class=dv>dummy_hcd.c:</span><span class=dt> /usr/src/linux-source-</span><span class=ch>$(</span><span class=dt>SVERSION</span><span class=ch>)</span><span class=dt>/linux-source-</span><span class=ch>$(</span><span class=dt>SVERSION</span><span class=ch>)</span><span class=dt>.tar.bz2</span></a>
<a class=sourceLine id=cb3-2 title=2>tar -xjvf <span class=ch>$^</span> linux-source-<span class=ch>$(</span><span class=dt>SVERSION</span><span class=ch>)</span>/drivers/usb/gadget/udc/dummy_hcd.c &&\</a>
<a class=sourceLine id=cb3-3 title=3> cp linux-source-<span class=ch>$(</span><span class=dt>SVERSION</span><span class=ch>)</span>/drivers/usb/gadget/udc/dummy_hcd.c <span class=ch>$@</span></a></code></pre></div><ol type=1 start=3><li>Build the kmod using the kernel Makefile.</ol><p>Following the basic example found in the documentation.<div class=sourceCode id=cb4><pre class="sourceCode makefile"><code class="sourceCode makefile"><a class=sourceLine id=cb4-1 title=1><span class=dt>obj-m </span><span class=ch>:=</span><span class=st> dummy_hcd.o</span></a>
<a class=sourceLine id=cb4-2 title=2><span class=dt>KVERSION </span><span class=ch>:=</span><span class=st> </span><span class=ch>$(</span><span class=kw>shell</span><span class=st> uname -r</span><span class=ch>)</span></a>
<a class=sourceLine id=cb4-4 title=4><span class=dv>all:</span><span class=dt> dummy_hcd.c</span></a>
<a class=sourceLine id=cb4-5 title=5> <span class=ch>$(</span><span class=dt>MAKE</span><span class=ch>)</span> -C /lib/modules/<span class=ch>$(</span><span class=dt>KVERSION</span><span class=ch>)</span>/build M=<span class=ch>$(</span><span class=dt>PWD</span><span class=ch>)</span> modules</a>
<a class=sourceLine id=cb4-7 title=7><span class=dv>clean:</span></a>
<a class=sourceLine id=cb4-8 title=8> <span class=ch>$(</span><span class=dt>MAKE</span><span class=ch>)</span> -C /lib/modules/<span class=ch>$(</span><span class=dt>KVERSION</span><span class=ch>)</span>/build M=<span class=ch>$(</span><span class=dt>PWD</span><span class=ch>)</span> clean</a></code></pre></div><ol type=1 start=4><li>Wrap everything into a DKMS module.</ol><p>First we should install DKMS.<div class=sourceCode id=cb5><pre class="sourceCode sh"><code class="sourceCode bash"><a class=sourceLine id=cb5-1 title=1><span class=fu>sudo</span> aptitude install dkms</a></code></pre></div><p>Then add a <code>dkms.conf</code> to <code>ls /usr/src/dummy_hcd-0.1/</code> along with the Makefile we previously created.<pre class=cfg><code>PACKAGE_NAME="dummy_hcd"
PACKAGE_VERSION="0.1"
CLEAN="make clean"
MAKE[0]="make all KVERSION=$kernelver"
BUILT_MODULE_NAME[0]="dummy_hcd"
DEST_MODULE_LOCATION[0]="/extra"
AUTOINSTALL="yes"</code></pre><p>We can then add our DKMS module to be built and added to our kernel modules.<div class=sourceCode id=cb7><pre class="sourceCode sh"><code class="sourceCode bash"><a class=sourceLine id=cb7-1 title=1><span class=ex>dkms</span> add -m dummy_hcd -v 0.1</a>
<a class=sourceLine id=cb7-2 title=2><span class=ex>dkms</span> build -m dummy_hcd -v 0.1</a>
<a class=sourceLine id=cb7-3 title=3><span class=ex>dkms</span> install -m dummy_hcd -v 0.1</a></code></pre></div><p>Finally, we can test our module is working by loading it and mounting the Gadget Filesystem.<div class=sourceCode id=cb8><pre class="sourceCode sh"><code class="sourceCode bash"><a class=sourceLine id=cb8-1 title=1><span class=ex>modprobe</span> dummy_hcd</a>
<a class=sourceLine id=cb8-2 title=2><span class=fu>mount</span> -t gadgetfs gadgetfs /dev/gadgetfs</a></code></pre></div><p>The complete project is published on <a href=https://github.com/serianox/DKMS-dummy_hcd>Github</a>.