
Write your first Linux kernel module - benev
http://www.linuxvoice.com/be-a-kernel-hacker/?pk_campaign=hn&pk_kwd=3
======
jvns
This is so great!

Writing toy kernel modules on your own is a super fun way to get into kernel
programming. There's no danger of anything going wrong, especially if you
develop inside a VM.

My partner wrote a kernel module for a talk I gave that rickrolls your file
system -- it overrides the 'open' system call so that any time you open a
'.mp3' file, it plays Rick Astley instead. (this requires you to have Rick
Astley already on your computer =))

The source code for that (and a few other toy kernel modules) is at
[https://github.com/jvns/kernel-module-fun](https://github.com/jvns/kernel-
module-fun)

The rickroll module (by Kamal Marhubi) is the most well commented and fun:
[https://github.com/jvns/kernel-module-
fun/blob/master/rickro...](https://github.com/jvns/kernel-module-
fun/blob/master/rickroll.c)

I wrote a blog post with more about this kernel-programming-for-fun
philosophy: [http://jvns.ca/blog/2014/01/04/4-paths-to-being-a-kernel-
hac...](http://jvns.ca/blog/2014/01/04/4-paths-to-being-a-kernel-hacker/)

Of course, writing code for the _mainline kernel_ is a responsible task, but
writing kernel code on your own machine that nobody will ever run in
production is a great way to learn, and I think it's made me a better
programmer.

A few concrete ways I think it's made me a better programmer:

\- I now understand the interface between kernel space and userspace much
better (I use strace all the time to debug my regular userspace code!)

\- realizing that the Linux kernel is just written in C and it's something I
can read (and understand! and change!) was a big deal for me

\- understanding the basics of the underlying operating system helps me reason
about my programs better

\- I now feel like if I ran into an _actual_ kernel bug or performance
problem, it's something I could conceivably attempt to fix and understand,
instead of hiding under the bed and saying OH NO THE KERNEL IT IS TOO HARD

------
deutronium
This is my first kernel module, which 'fakes' your system uptime:

[http://www.anfractuosity.com/projects/uptime/](http://www.anfractuosity.com/projects/uptime/)

Personally I think people should be encouraged to hack around with the kernel,
rather than be afraid of it, how else can we learn?

------
pdevr
This is a good starting point for anyone interested in the Eudyptula Challenge
[1].

[1] [http://eudyptula-challenge.org/](http://eudyptula-challenge.org/)

~~~
sp332
_The idea for this came to us after a long night of drinking in which it was
determined that if the Linux kernel was to survive, it would need new
programmers to fix all of the bugs that were recently added after a long night
of drinking._

Sound thinking.

------
chrisBob
Do most kernel programmers start out working on their regular daily-use
machine? My only experience is with an embedded linux environment, and I would
probably recommend starting with something like a RPi so that your environment
is easy to restore if you mess something up.

I also recommend "Linux Device Drivers" from O'Reilly.
[http://lwn.net/Kernel/LDD3/](http://lwn.net/Kernel/LDD3/)

~~~
sophacles
Whenever I do kernel stuff, it happens in a VM, limited to a subset of the
cores available on the machine. That way when I inevitably bork something, I
can just forcibly stop it.

Another trick I've used is making as much of my core logic as possible happen
in functions that are called from the kernel hooks, rather than in the kernel
hooks. Then you can test a ton of it in userland to handle basic logic and
flow control bugs, finally porting the code to the module. To help with this,
it sometimes is actually faster to copy some of the kernel routines you use to
a different .c file and change things like kprintf and kmalloc for the
userland versions. It isn't going to be a perfect port, but it helps get some
of the complex stuff out of the way where you have your familiar userland
tools.

All that said - I've only dabbled in the kernel a little, there are probably
better ways that someone can chime in on.

~~~
solarexplorer
Keeping the complex stuff out of the kernel is good advice. (and not just
during development)

~~~
sophacles
True! Unfortunately it's sometimes unavoidable. The specific case I was
remembering involved writing a qdisc... it was actually more complex to move
that out of the kernel via nf_queue than to just do it in-kernel. (At least
some parts of it.)

------
jhiesey
I might be missing something, but the final version still looks susceptible to
deadlock to me.

Suppose the buffer is empty. Process A, which is reading, gets through the
mutex_unlock() call and into wait_event_interruptible(), which seems to first
internally check the condition. It is then switched out before it internally
waits.

Process B then runs all the way through, acquiring the mutex, doing its work,
and runs wake_up_interruptible(), which won't do anything, because process A
hasn't started waiting. Process B then releases the mutex and gets switched
out.

Process A then gets switched back in, and then immediately starts waiting,
with no more events to wake it up. Why won't it just wait forever (deadlock)?

Am I missing something? Do all processes occasionally get woken up without an
explicit wake up?

------
Aardwolf
VirtualBox uses a kernel module, and that is annoying because the linux kernel
API changes with every update, which means its kernel module needs to be
recompiled. Since I update my Linux quite often, that basically means:

Everytime some friends call me to play a certain game online with each other,
they need to be waiting a bit longer for me because I have yet again to
recompile VirtualBox's kernel modules.

Is there a way to convert something that requires kernel modules, to run fully
in userspace?

I'd be happy to lose some efficiency for this. Just a 100% reliable game to
run my game would be perfect.

Are there things you can do only in kernel modules and not in userspace, and
does VB need this? In theory userspace can do everything you need, right?
Graphics, networking, audio, ...

~~~
aquayellow
Virtualbox is an out-of-tree module and hence needs to be compiled. The base
package is GPLv2 and is compatible with the Linux kernel license, but I don't
know if Virtualbox developers ever tried to "upstream" their module. This is
probably the easiest way to solve your problem. Most Virtualization Software
these days use virtualization hardware extensions (Intel VMX/AMD SVM) and so
the "hypervisor code" needs to be able to execute privileged instructions, eg
- you can't run VMON from ring 3/userspace.

~~~
justincormack
Apparently the virtualbox code is terrible, hence the lack of upstreaming...

------
benjojo12
I had great fun writing a silly toy kernel module a few weeks back, (
[https://github.com/benjojo/dev_markov](https://github.com/benjojo/dev_markov)
) Would totally recommend anyone curious giving it a go.

------
Nursie
Cool, definitely relevant to my interests. I've done various ARM/orion5x
platform porting related stuff before but never a module...

------
Myrmornis
Really great article.

------
thegeomaster
Maybe it's worth emphasizing that writing kernel code is a very responsible
task, not to be taken lightly. Hackers coming from a userspace background tend
to think it's just "userspace with a few quirks" which is grossly wrong: your
code has to be _completely free of bugs_ , as a dangling pointer, for
instance, won't just send you a friendly SIGSEGV and terminate your ass, it
will crash the whole system, leading to consequences for everyone who relies
on its stability. Just imagine introducing a bug which crashes a Linux-based
life support system. You could be responsible for endangering human lives. (I
ageee that Linux isn't a sane choice here, but just for the sake of the
argument.)

Also, standards to get your pull requests merged into mainline Linux are
insanely high, but even given that, you can never rely solely on maintainers'
code review to catch your mistakes. Take kernel hacking seriously.

~~~
danford
>You could be responsible for endangering human lives.

I'm pretty sure what ever devices people depend on to keep them alive would be
running a modified version of the Linux kernel with anything unnecessary
stripped out and probably a lot of custom stuff.

They wouldn't just download it from kernel.org and throw it on there. I would
hope not at least.

~~~
cnvogel
I wholeheartly agree with ❝devices people depend on to keep them alive would
be running a -- version of the Linux kernel with anything unnecessary stripped
out❞.

But the part with a ❝ _modified_ version (...) and probably a lot of custom
stuff❞ made be shudder.

The Linux kernel is a _very_ well maintained piece of software, and whenever,
in the embedded world, I've seen modification or larger forks of the
stock/mainline kernel, they always were of worse quality and had more bugs
than what I (or everyone else) has gotten used to when running mainline code
(as is customary on your normal x86 PCs).

That's because code-review actually _works_ in Linux, and while it makes it
sometimes very hard to get new features in, the ones that make it are usually
well vettet.

