This is a basic skeleton of a Linux kernel module about notify chain that I’ll put as examples on my final course paper. When user presses a key, kernel “reads” it and then, using notify chain informs all subsystems which want to be informed about pressed key.
/* keyboard-dump.c
*
* This is a "notify chain" example that dumps keyboard on kernel message
*
* (C) Copyright 2010, Tiago Maluta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/notifier.h>
#include <linux/module.h>
#include <linux/keyboard.h>
static int debug = 1;
#define dbg(fmt, arg...) \
do { \
if (debug) \
printk (KERN_DEBUG "%s: %s: " fmt "\n", \
"test" , __FUNCTION__ , ## arg); \
} while (0)
int keyboard_event_handler(struct notifier_block *self,
unsigned long val,
void *data)
{
struct keyboard_notifier_param *param = data;
unsigned int value = param->value;
if ((!param->down) && (value > 0xf000))
printk("%c", KVAL(param->value));
return NOTIFY_DONE ;
}
static struct notifier_block keyboard_notifier = {
.notifier_call = keyboard_event_handler,
};
static int __init keyboard_init(void)
{
register_keyboard_notifier(&keyboard_notifier);
dbg();
return 0;
}
static void __exit keyboard_exit(void)
{
unregister_keyboard_notifier(&keyboard_notifier);
dbg();
}
module_init(keyboard_init);
module_exit(keyboard_exit);
MODULE_LICENSE("GPL");
<body bgcolor="#ffffff" text="#000000">
<pre>
<font color="#444444">/* keyboard-dump.c
*
* This is a "notify chain" example that dumps keyboard on kernel message
*
* (C) Copyright 2010, Tiago Maluta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/</font>
<font color="#0000ff"><strong>#include <font color="#008000"><linux/notifier.h></font></strong></font>
<font color="#0000ff"><strong>#include <font color="#008000"><linux/module.h></font></strong></font>
<font color="#0000ff"><strong>#include <font color="#008000"><linux/keyboard.h></font></strong></font>
<strong>static</strong> <strong>int</strong> <font color="#2040a0">debug</font> <font color="#4444ff">=</font> <font color="#ff0000">1</font><font color="#4444ff">;</font>
<font color="#0000ff"><strong>#define dbg(fmt, arg...) \</strong></font>
<strong>do</strong> <font color="#4444ff"><strong>{</strong></font> \
<strong>if</strong> <font color="#4444ff">(</font><font color="#2040a0">debug</font><font color="#4444ff">)</font> \
<font color="#2040a0">printk</font> <font color="#4444ff">(</font><font color="#2040a0">KERN_DEBUG</font> <font color="#008000">"%s: %s: "</font> <font color="#2040a0">fmt</font> <font color="#008000">"<font color="#77dd77">\n</font>"</font>, \
<font color="#008000">"test"</font> , <font color="#2040a0">__FUNCTION__</font> , ## <font color="#2040a0">arg</font><font color="#4444ff">)</font><font color="#4444ff">;</font> \
<font color="#4444ff"><strong>}</strong></font> <strong>while</strong> <font color="#4444ff">(</font><font color="#ff0000">0</font><font color="#4444ff">)</font>
<strong>int</strong> <font color="#2040a0">keyboard_event_handler</font><font color="#4444ff">(</font><strong>struct</strong> <font color="#2040a0">notifier_block</font> <font color="#4444ff">*</font><font color="#2040a0">self</font>,
<strong>unsigned</strong> <strong>long</strong> <font color="#2040a0">val</font>,
<strong>void</strong> <font color="#4444ff">*</font><font color="#2040a0">data</font><font color="#4444ff">)</font>
<font color="#4444ff"><strong>{</strong></font>
<strong>struct</strong> <font color="#2040a0">keyboard_notifier_param</font> <font color="#4444ff">*</font><font color="#2040a0">param</font> <font color="#4444ff">=</font> <font color="#2040a0">data</font><font color="#4444ff">;</font>
<strong>unsigned</strong> <strong>int</strong> <font color="#2040a0">value</font> <font color="#4444ff">=</font> <font color="#2040a0">param</font><font color="#4444ff">-</font><font color="#4444ff">></font><font color="#2040a0">value</font><font color="#4444ff">;</font>
<strong>if</strong> <font color="#4444ff">(</font><font color="#4444ff">(</font><font color="#4444ff">!</font><font color="#2040a0">param</font><font color="#4444ff">-</font><font color="#4444ff">></font><font color="#2040a0">down</font><font color="#4444ff">)</font> <font color="#4444ff">&</font><font color="#4444ff">&</font> <font color="#4444ff">(</font><font color="#2040a0">value</font> <font color="#4444ff">></font> <font color="#ff0000">0xf000</font><font color="#4444ff">)</font><font color="#4444ff">)</font>
<font color="#2040a0">printk</font><font color="#4444ff">(</font><font color="#008000">"%c"</font>, <font color="#2040a0">KVAL</font><font color="#4444ff">(</font><font color="#2040a0">param</font><font color="#4444ff">-</font><font color="#4444ff">></font><font color="#2040a0">value</font><font color="#4444ff">)</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<strong>return</strong> <font color="#2040a0">NOTIFY_DONE</font> <font color="#4444ff">;</font>
<font color="#4444ff"><strong>}</strong></font>
<strong>static</strong> <strong>struct</strong> <font color="#2040a0">notifier_block</font> <font color="#2040a0">keyboard_notifier</font> <font color="#4444ff">=</font> <font color="#4444ff"><strong>{</strong></font>
.<font color="#2040a0">notifier_call</font> <font color="#4444ff">=</font> <font color="#2040a0">keyboard_event_handler</font>,
<font color="#4444ff"><strong>}</strong></font><font color="#4444ff">;</font>
<strong>static</strong> <strong>int</strong> <font color="#2040a0">__init</font> <font color="#2040a0">keyboard_init</font><font color="#4444ff">(</font><strong>void</strong><font color="#4444ff">)</font>
<font color="#4444ff"><strong>{</strong></font>
<font color="#2040a0">register_keyboard_notifier</font><font color="#4444ff">(</font><font color="#4444ff">&</font><font color="#2040a0">keyboard_notifier</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<font color="#2040a0">dbg</font><font color="#4444ff">(</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<strong>return</strong> <font color="#ff0000">0</font><font color="#4444ff">;</font>
<font color="#4444ff"><strong>}</strong></font>
<strong>static</strong> <strong>void</strong> <font color="#2040a0">__exit</font> <font color="#2040a0">keyboard_exit</font><font color="#4444ff">(</font><strong>void</strong><font color="#4444ff">)</font>
<font color="#4444ff"><strong>{</strong></font>
<font color="#2040a0">unregister_keyboard_notifier</font><font color="#4444ff">(</font><font color="#4444ff">&</font><font color="#2040a0">keyboard_notifier</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<font color="#2040a0">dbg</font><font color="#4444ff">(</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<font color="#4444ff"><strong>}</strong></font>
<font color="#2040a0">module_init</font><font color="#4444ff">(</font><font color="#2040a0">keyboard_init</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<font color="#2040a0">module_exit</font><font color="#4444ff">(</font><font color="#2040a0">keyboard_exit</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
<font color="#2040a0">MODULE_LICENSE</font><font color="#4444ff">(</font><font color="#008000">"GPL"</font><font color="#4444ff">)</font><font color="#4444ff">;</font>
</pre>
The output will be visible (i.e: dmesg) on kernel ring buffer.
If you like try don’t cut&paste the code above but use I gist repository here.