Difference between revisions of "ECE497 Listings for Embedded Linux Primer Chapter 8"
(Added Listing 8-4) |
m (Added Header/Footer) |
||
(17 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | [[Category: | + | [[Category:ECE497old]] |
+ | {{YoderHead}} | ||
{| | {| | ||
Line 8: | Line 9: | ||
|- | |- | ||
| 8-1 | | 8-1 | ||
− | | | + | | 204 |
| Minimal Device Driver | | Minimal Device Driver | ||
| <pre> | | <pre> | ||
Line 23: | Line 24: | ||
static void __exit hello_exit(void) | static void __exit hello_exit(void) | ||
{ | { | ||
− | printk("Hello Example Exit\n"); | + | printk(KERN_INFO "Hello Example Exit\n"); |
} | } | ||
Line 35: | Line 36: | ||
|- | |- | ||
| 8-2 | | 8-2 | ||
− | | | + | | 206 |
| Kconfig Patch for Examples | | Kconfig Patch for Examples | ||
| <pre> | | <pre> | ||
Line 48: | Line 49: | ||
+config EXAMPLES | +config EXAMPLES | ||
+ tristate "Enable Examples" | + tristate "Enable Examples" | ||
− | + default | + | + default m |
+ ---help--- | + ---help--- | ||
+ Enable compilation option for Embedded Linux Primer | + Enable compilation option for Embedded Linux Primer | ||
Line 59: | Line 60: | ||
|- | |- | ||
| 8-3 | | 8-3 | ||
− | | | + | | 208 |
| Makefile Patch for Examples | | Makefile Patch for Examples | ||
| <pre> | | <pre> | ||
Line 77: | Line 78: | ||
|- | |- | ||
| 8-4 | | 8-4 | ||
− | | | + | | 209 |
| Module Build Output | | Module Build Output | ||
| <pre> | | <pre> | ||
Line 99: | Line 100: | ||
</pre> | </pre> | ||
|- | |- | ||
− | | 8-4 | + | | 8-5 |
+ | | 210 | ||
+ | | Loading and Unloading a Module | ||
+ | | <pre> | ||
+ | # /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 | ||
+ | </pre> | ||
+ | |- | ||
+ | | 8-6 | ||
+ | | 211 | ||
+ | | Example Driver with Parameter | ||
+ | | <pre> | ||
+ | /* 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"); | ||
+ | </pre> | ||
+ | |- | ||
+ | | 8-6a | ||
+ | | 211 | ||
+ | | Example Driver with Parameter | ||
+ | | <pre> | ||
+ | # /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 | ||
+ | </pre> | ||
+ | |- | ||
| 8-7 | | 8-7 | ||
− | | Module | + | | 213 |
+ | | lsmod Example Output Format | ||
+ | | <pre> | ||
+ | # /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 | ||
+ | </pre> | ||
+ | |- | ||
+ | | 8-8 | ||
+ | | 214 | ||
+ | | Typical modprobe.conf File (not on Beagle) | ||
+ | | <pre> | ||
+ | $ 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 | ||
+ | $ | ||
+ | </pre> | ||
+ | |- | ||
+ | | 8-9 | ||
+ | | 216 | ||
+ | | modinfo Output | ||
+ | | <pre> | ||
+ | # /sbin/modinfo 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 | ||
+ | </pre> | ||
+ | |- | ||
+ | | 8-10 | ||
+ | | 217 | ||
+ | | Adding File System Ops to Hello.c | ||
| <pre> | | <pre> | ||
+ | #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"); | ||
</pre> | </pre> | ||
+ | |- | ||
+ | | 8-11 | ||
+ | | 222 | ||
+ | | Adding File System Ops to Hello.c | ||
+ | | <pre> | ||
+ | #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; | ||
+ | } | ||
+ | </pre> | ||
|} | |} | ||
+ | |||
+ | {{YoderFoot}} |
Latest revision as of 04:12, 29 May 2012
Embedded Linux Class by Mark A. Yoder
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 | $ 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 | 210 | 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 | 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 | # /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 | 213 | 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 | 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 | # /sbin/modinfo 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 | 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=%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 | 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; } |
Embedded Linux Class by Mark A. Yoder