Notify chain example 1

April 20, 2010

[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]

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 &quot;notify chain&quot; 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">&lt;linux/notifier.h&gt;</font></strong></font>
<font color="#0000ff"><strong>#include <font color="#008000">&lt;linux/module.h&gt;</font></strong></font>
<font color="#0000ff"><strong>#include <font color="#008000">&lt;linux/keyboard.h&gt;</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">&quot;%s: %s: &quot;</font> <font color="#2040a0">fmt</font> <font color="#008000">&quot;<font color="#77dd77">\n</font>&quot;</font>,		\
				<font color="#008000">&quot;test&quot;</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">&gt;</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">&gt;</font><font color="#2040a0">down</font><font color="#4444ff">)</font> <font color="#4444ff">&amp;</font><font color="#4444ff">&amp;</font> <font color="#4444ff">(</font><font color="#2040a0">value</font> <font color="#4444ff">&gt;</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">&quot;%c&quot;</font>, <font color="#2040a0">KVAL</font><font color="#4444ff">(</font><font color="#2040a0">param</font><font color="#4444ff">-</font><font color="#4444ff">&gt;</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">&amp;</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">&amp;</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">&quot;GPL&quot;</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.