ECE497 Listings for Embedded Linux Primer Chapter 8

From eLinux.org
Revision as of 12:47, 26 March 2010 by Yoder (talk | contribs) (Added Listing 8-11)
Jump to: navigation, search


Number Page Caption Listing
8-1 8-3 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 8-5 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 8-7 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 8-7 Module Build Output
$ 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>:1097:2: warning: #warning syscall fadvise64 not implemented
<stdin>:1265:2: warning: #warning syscall migrate_pages not implemented
  CC [M]  drivers/char/examples/hello1.o
  Building modules, stage 2.
  MODPOST 691 modules
  CC      drivers/char/examples/hello1.mod.o
  LD [M]  drivers/char/examples/hello1.ko

real	0m41.559s
user	0m10.905s
sys	0m23.877s
8-5 8-7 Loading and Unloading a Module
# /sbin/modprobe hello1
# dmesg | tail -4
[   47.095764] OMAPFB: ioctl QUERY_PLANE
[   47.095794] OMAPFB: ioctl GET_CAPS
[   49.005889] eth0: no IPv6 routers present
[  651.947784] Hello Example Init
# /sbin/modprobe -r hello1
# dmesg | tail -4
[   47.095794] OMAPFB: ioctl GET_CAPS
[   49.005889] eth0: no IPv6 routers present
[  651.947784] Hello Example Init
[  677.682769] Hello Example Exit
8-6 8-10 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 8-11 Example Driver with Parameter
# /sbin/insmod /lib/modules/2.6.29-omap1/kernel/drivers/char/examples/hello2.ko debug_enable=1
# dmesg | tail -4
[   49.005889] eth0: no IPv6 routers present
[  651.947784] Hello Example Init
[  677.682769] Hello Example Exit
[ 2997.772644] Hello Example Init - debug mode is enabled
# /sbin/rmmod hello2
# /sbin/insmod /lib/modules/2.6.29-omap1/kernel/drivers/char/examples/hello2.ko 
# dmesg | tail -4
[ 2990.234527] Hello Example Exit
[ 2997.772644] Hello Example Init - debug mode is enabled
[ 3236.012847] Hello Example Exit
[ 3243.475494] Hello Example Init - debug mode is disabled
8-7 8-12 lsmod Example Output Format
# /sbin/lsmod
Module                  Size  Used by
hello2                  1520  0 
hello1                  1160  0 
ircomm_tty             35984  0 
ircomm                 21144  1 ircomm_tty
irda                  186196  2 ircomm_tty,ircomm
ipv6                  274380  16 
nls_iso8859_1           3856  1 
rtc_twl4030             5394  0 
8-8 8-13 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 8-15 modinfo Output
# /sbin/m
odinfo hello1
filename:       /lib/modules/2.6.29-omap1/kernel/drivers/char/examples/hello1.ko
license:        GPL
description:    Hello World Example
author:         Mark A. Yoder
srcversion:     43AAF2090DF58262722312B
depends:        
vermagic:       2.6.29-omap1 preempt mod_unload modversions ARMv7 
8-10 8-16 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=%ld, 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)
{
    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 8-20 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;
}