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 "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.