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;
}
|