Table of Contents

2009-12-21 Linux kernel driver that handles IRQ

Plan

Worklog

├── bin/                                  
│   ├── busybox*                          
│   ├── cat -> busybox*                   
│   ├── df -> busybox*                    
│   ├── du -> busybox*                    
│   ├── insmod -> busybox*                
│   ├── less -> busybox*                  
│   ├── ln -> busybox*                    
│   ├── ls -> busybox*                    
│   ├── lsmod -> busybox*                 
│   ├── mount -> busybox*                 
│   ├── rmmod -> busybox*                 
│   ├── sh -> busybox*                    
│   ├── top -> busybox*                   
│   └── vi -> busybox*
├── dev/
│   ├── pts/
│   ├── console
│   ├── kmsg
│   ├── loop0
│   ├── loop1
│   ├── loop2
│   ├── loop3
│   ├── loop4
│   ├── loop5
│   ├── loop6
│   ├── loop7
│   ├── mem
│   ├── null
│   ├── ptmx
│   ├── random
│   ├── systty
│   ├── tty
│   ├── tty0
│   ├── tty1
│   ├── tty2
│   ├── urandom
│   └── zero
├── lib/
│   └── modules/
│       └── 2.6.33-rc1/
├── proc/
├── sbin/
├── sys/
├── tmp/
├── init*
└── test.ko
#! /bin/sh

mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts

while :
do
  /bin/sh
done
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
make ARCH=i386 defconfig
# turn off networking as we don't need it
# turn on initramfs:
# General setup --->
#   [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
#   (/home/dumb/ws/ii/games-build/games/src/lkm/rootfs) Initramfs source file(s)
make ARCH=i386 menuconfig
make ARCH=i386 -j3 bzImage
#include <linux/kernel.h>         
#include <linux/init.h>           
#include <linux/module.h>         
#include <linux/irq.h>            
#include <linux/interrupt.h>      

static irqreturn_t test_irq_handler(int i, void *dev)
{                                                    
    static spinlock_t lock = __SPIN_LOCK_UNLOCKED(lock);
    unsigned long flags;                                

    printk(KERN_INFO "%s(%d, %p)\n", __func__, i, dev);
    spin_lock_irqsave(&lock, flags);                   
    printk(KERN_INFO "flags: %lx\n", flags);           
    spin_unlock_irqrestore(&lock, flags);
    return IRQ_HANDLED;
}

static int test_irq;
static int test_irq_no;
#define IRQ_NO test_irq_no

module_param(test_irq_no, int, 13);
MODULE_PARM_DESC(test_irq_no, "requested IRQ line");

static int __init test_init(void)
{
        int rc;
        printk(KERN_INFO "%s\n", __func__);
        rc = request_irq(IRQ_NO, test_irq_handler, IRQF_SHARED, "test_device", &test_irq);
        printk(KERN_INFO "request_irq(%d, %p): %d\n", IRQ_NO, &test_irq, rc);
        if (!rc)
            test_irq = IRQ_NO;
        return 0;
}

static void __exit test_exit(void)
{
        printk(KERN_INFO "%s\n", __func__);
        if (test_irq)
            free_irq(test_irq, &test_irq);
}

module_init(test_init);
module_exit(test_exit);

MODULE_AUTHOR("jcmvbkbc");
MODULE_LICENSE("GPL");
PWD = $(shell pwd)
EXTRA_CFLAGS += -Wall

obj-m += test.o

default: modules

modules clean:
        make -C $(KDIR) M=$(PWD) $@

Code: ftp://kkv.spb.su/pub/home/dumb/ws/lted/20091221/

Conclusion