ECE497 Listings for Chapter 8--Yifei

From eLinux.org
Jump to: navigation, search
Number Page Caption Listing
8-1 204 Minimal Device Driver
/* Example Minimal Character Device Driver */
#include <linux/module.h>

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello Example Init\n");

    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Hello Example Exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("Chris Hallinan");
MODULE_DESCRIPTION("Hello World Example");
MODULE_LICENSE("GPL");
8-2 206 Kconfig Patch for Examples
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig 
index 6f31c94..0805290 100644 
--- a/drivers/char/Kconfig 
+++ b/drivers/char/Kconfig 
@@ -4,6 +4,13 @@ 
 
 menu "Character devices" 
 
+config EXAMPLES 
+       tristate "Enable Examples" 
+       default m
+       ---help--- 
+         Enable compilation option for Embedded Linux Primer 
+         driver examples 
+ 
 config VT 
        bool "Virtual terminal" if EMBEDDED 
        depends on !S390 
8-3 208 Makefile Patch for Examples
diff --git a/drivers/char/Makefile b/drivers/char/Makefile 
index f957edf..f1b373d 100644 
--- a/drivers/char/Makefile 
+++ b/drivers/char/Makefile 
@@ -102,6 +102,7 @@ obj-$(CONFIG_MWAVE)         += mwave/ 
 obj-$(CONFIG_AGP)              += agp/ 
 obj-$(CONFIG_PCMCIA)           += pcmcia/ 
 obj-$(CONFIG_IPMI_HANDLER)     += ipmi/ 
+obj-$(CONFIG_EXAMPLES)         += examples/ 
 
 obj-$(CONFIG_HANGCHECK_TIMER)  += hangcheck-timer.o 
 obj-$(CONFIG_TCG_TPM)          += tpm/
8-4 209 Module Build Output
beagle@embed11:~/...$ time make modules
  CHK     include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
  CHK     include/linux/utsrelease.h
  SYMLINK include/asm -> include/asm-arm
  CALL    scripts/checksyscalls.sh
<stdin>:1523:2: warning: #warning syscall recvmmsg not implemented
  CC [M]  drivers/char/examples/hello1.o
  Building modules, stage 2.
  MODPOST 701 modules
  CC      drivers/char/examples/hello1.mod.o
  LD [M]  drivers/char/examples/hello1.ko

real	0m28.129s
user	0m38.680s
sys	0m7.950s


8-5 210 Loading and Unloading a Module
# /sbin/modprobe hello1
# dmesg | tail -4
[   73.556915] generic-usb 0003:045E:00CB.0004: input: USB HID v1.11 Mouse [Microsoft  Microsoft Basic Optical Mouse v2.0 ] on usb-ehci-omap.0-2.2/input0
[  373.735351] Alignment trap in kernel: swapper (0) PC=0xc043a30c Instr=0xe8930003 Address=0xddee002a FSR 0x001
[  420.957183] Alignment trap in kernel: swapper (0) PC=0xc043a30c Instr=0xe8930003 Address=0xdded002a FSR 0x001
[ 1913.619354] Hello Example Init

# /sbin/modprobe -r hello1
# dmesg | tail -4
[  373.735351] Alignment trap in kernel: swapper (0) PC=0xc043a30c Instr=0xe8930003 Address=0xddee002a FSR 0x001
[  420.957183] Alignment trap in kernel: swapper (0) PC=0xc043a30c Instr=0xe8930003 Address=0xdded002a FSR 0x001
[ 1913.619354] Hello Example Init
[ 2026.515991] Hello Example Exit

8-6 211 Example Driver with Parameter
/* Example Minimal Character Device Driver */
#include <linux/module.h>

static int debug_enable = 0;       /* Added driver parameter */
module_param(debug_enable, int, 0);  /* and these 2 lines */
MODULE_PARM_DESC(debug_enable, "Enable module debug mode.");

static int __init hello_init(void)
{
    /* Now print value of new module parameter */
    printk("Hello Example Init - debug mode is %s\n",
           debug_enable ? "enabled" : "disabled");

    return 0;
}

static void __exit hello_exit(void)
{
    printk("Hello Example Exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("Chris Hallinan");
MODULE_DESCRIPTION("Hello World Example");
MODULE_LICENSE("GPL");
8-6a 211 Example Driver with Parameter
root@beagleboard:~# /sbin/insmod /lib/modules/2.6.32/kernel/drivers/char/examples/hello1.ko debug_enable=1
insmod: error inserting '/lib/modules/2.6.32/kernel/drivers/char/examples/hello1.ko': -1 File exists
root@beagleboard:~# modprobe -r hello1
root@beagleboard:~# /sbin/insmod /lib/modules/2.6.32/kernel/drivers/char/examples/hello1.ko debug_enable=1
root@beagleboard:~# dmesg | tail -5
[15568.609344] Hello Example Init - debug mode is enabled
[15720.627441] Hello Example Exit
[15731.117248] Hello Example Init - debug mode is enabled
[15782.651062] Hello Example Exit
[15793.742034] Hello Example Init - debug mode is enabled
root@beagleboard:~# 

8-7 213 lsmod Example Output Format
root@beagleboard:~# /sbin/lsmod
Module                  Size  Used by
hello1                   653  0 
bufferclass_ti          4768  0 
omaplfb                 8733  0 
pvrsrvkm              154248  2 bufferclass_ti,omaplfb
rfcomm                 33484  0 
ircomm_tty             30305  0 
ircomm                 16429  1 ircomm_tty
irda                  162973  2 ircomm_tty,ircomm
ipv6                  249063  14 
hidp                   11193  0 
l2cap                  30104  4 rfcomm,hidp
bluetooth              49221  3 rfcomm,hidp,l2cap
rfkill                 14838  2 bluetooth
minix                  25759  0 
rtc_twl                 4451  0 
rtc_core               12535  1 rtc_twl
mt9t112                 9246  0 
root@beagleboard:~# 

8-8 214 Typical modprobe.conf File (not on Beagle)
$ cat /etc/modprobe.conf
alias eth1 orinoci_pci
options eth1 orinoco_debug=9
alias eth0 e100
alias snd-card-0 snd-intel8x0
options snd-card-0 index=0
$
8-9 216 modinfo Output
root@beagleboard:~# /sbin/modinfo hello1
filename:       /lib/modules/2.6.32/kernel/drivers/char/examples/hello1.ko
license:        GPL
description:    Hello World Example
author:         Chris Hallinan
srcversion:     550CC1790D2FCC055F2B7F8
depends:        
vermagic:       2.6.32 preempt mod_unload modversions ARMv7 
parm:           debug_enable:Enable module debug mode. (int)
root@beagleboard:~# 

8-10 217 Adding File System Ops to Hello.c
#include <linux/module.h>
#include <linux/fs.h>

#define HELLO_MAJOR 234

static int debug_enable = 0;
module_param(debug_enable, int, 0);
MODULE_PARM_DESC(debug_enable, "Enable module debug mode.");

struct file_operations hello_fops;

static int hello_open(struct inode *inode, struct file *file)
{
    printk("hello_open: successful\n");
    return 0;
}

static int hello_release(struct inode *inode, struct file *file)
{
    printk("hello_release: successful\n");
    return 0;
}

static ssize_t hello_read(struct file *file, char *buf, size_t count,
               loff_t *ptr)
{
    printk("hello_read: returning zero bytes\n");
    return 0;
}

static ssize_t hello_write(struct file *file, const char *buf,
               size_t count, loff_t * ppos)
{
    printk("hello_read: accepting zero bytes\n");
    return 0;
}

static int hello_ioctl(struct inode *inode, struct file *file,
               unsigned int cmd, unsigned long arg)
{
    printk("hello_ioctl: cmd=%d, arg=%ld\n", cmd, arg);
    return 0;
}

static int __init hello_init(void)
{
    int ret;
    printk("Hello Example Init - debug mode is %s\n",
           debug_enable ? "enabled" : "disabled");
    ret = register_chrdev(HELLO_MAJOR, "hello1", &hello_fops);
        if (ret < 0) {
            printk("Error registering hello device\n");
            goto hello_fail1;
        }
    printk("Hello: registered module successfully!\n");

    /* Init processing here... */

    return 0;

hello_fail1:
    return ret;
}

static void __exit hello_exit(void)
{
unregister_chrdev(HELLO_MAJOR, "hello1");   
printk("Hello Example Exit\n");
}

struct file_operations hello_fops = {
    owner:   THIS_MODULE,
    read:    hello_read,
    write:   hello_write,
    ioctl:   hello_ioctl,
    open:    hello_open,
    release: hello_release,
};

module_init(hello_init);
module_exit(hello_exit);

MODULE_AUTHOR("Chris Hallinan");
MODULE_DESCRIPTION("Hello World Example");
MODULE_LICENSE("GPL");
8-11 222 Adding File System Ops to Hello.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    /* Our file descriptor */
    int fd;
    int rc = 0;
    char *rd_buf[16];

    printf("%s: entered\n", argv[0]);

    /* Open the device */
    fd = open("/dev/hello1", O_RDWR);
    if ( fd == -1 ) {
        perror("open failed");
        rc = fd;
        exit(-1);
    }
    printf("%s: open: successful\n", argv[0]);

    /* Issue a read */
    rc = read(fd, rd_buf, 0);
    if ( rc == -1 ) {
        perror("read failed");
        close(fd);
        exit(-1);
    }
    printf("%s: read: returning %d bytes!\n", argv[0], rc);

    close(fd);
    return 0;
}