1 / 15

Kernel Modules And Device Drivers

Kernel Modules And Device Drivers. Keith Harrison. Roadmap. Kernel Basics Kernel Modules Example Proc Filesystem Example Device Drivers Example. Kernel Basics. Kernel basics. No libc functions!!! No printf, use printk instead Some common functions implemented inside the kernel

althea
Download Presentation

Kernel Modules And Device Drivers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Kernel Modules And Device Drivers Keith Harrison

  2. Roadmap • Kernel Basics • Kernel Modules • Example • Proc Filesystem • Example • Device Drivers • Example

  3. Kernel Basics

  4. Kernel basics • No libc functions!!! • No printf, use printk instead • Some common functions implemented inside the kernel • No memory protection • Oops • Not Pageable • Small, fixed size stack • Synchronization and Concurrency issues

  5. Kernel Functions • copy_to_user() • copy_from_user() • vmalloc() • alloc_pages(), alloc_page() • free_pages(), free_page() • kmalloc(), kfree() • vmalloc(), vfree()

  6. Kernel Modules • module_init() • module_exit() • MODULE_LICENSE(); • MODULE_AUTHOR();

  7. Kernel Modules Example #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> static inthello_init(void){ printk(KERN_ALERT "I bear a charmed life.\n"); return 0; } static void hello_exit(void){ printk(KERN_ALERT "Out, out, brief candle!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Shakespeare");

  8. Proc filesystem • Virtual Files • Important Functions: • create_proc_entry() • remove_proc_entry() • Other Functions: • create_proc_read_entry() • proc_mkdir() • proc_symlink()

  9. Proc Filesystem Example #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #define procfs_name "helloworld" structproc_dir_entry *My_Proc_File; static intmyproc_init(void){ My_Proc_File = create_proc_read_entry(procfs_name, 0644, NULL, procfile_read, NULL); printk(KERN_INFO "/proc/%s created\n", procfs_name); return 0; } static void myproc_exit(void){ remove_proc_entry(procfs_name, &proc_root); printk(KERN_INFO "/proc/%s removed\n", procfs_name); } module_init(myproc_init); module_exit(myproc_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Shakespeare");

  10. Proc Filesystem Example intprocfile_read(char *buffer, char **buffer_location, off_t offset, intbuffer_length, int *eof, void *data) { int ret; printk(KERN_INFO "procfile_read (/proc/%s) called\n", procfs_name); if (offset > 0) { /* we have finished to read, return 0 */ ret = 0; } else { /* fill the buffer, return the buffer size */ ret = sprintf(buffer, "HelloWorld!\n"); } return ret; }

  11. Device Drivers • Character devices • Block devices • Major number • typically associated with the driver • Minor number • Typically associated with physical instance of device

  12. Character Device Example intinit_mychardev(void) { Major = register_chrdev(0, DEVICE_NAME, &fops); if (Major < 0) { printk ("Registering the character device failed with %d\n", Major); return Major; } printk("<1>I was assigned major number %d. To talk to\n", Major); printk("<1>the driver, create a dev file with\n"); printk("'mknod /dev/hello c %d 0'.\n", Major); printk("<1>Try various minor numbers. Try to cat and echo to\n"); printk("the device file.\n"); printk("<1>Remove the device file and module when done.\n"); return 0; } void cleanup_mychardev(void) { /* Unregister the device */ unregister_chrdev(Major, DEVICE_NAME); } module_init(init_mychardev); module_exit(cleanup_mychardev); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Shakespeare");

  13. Character Device Example /* Called when a process tries to open the device file, like * "cat /dev/mycharfile" */ static intdevice_open(structinode *inode, struct file *file) { static int counter = 0; if (Device_Open) return -EBUSY; Device_Open++; snprintf(hello_msg,80,"I already told you %d times Hello world!\n", counter++); hello_msg_Ptr = hello_msg; write_msg_Ptr = write_msg; return SUCCESS; } /* Called when a process closes the device file. */ static intdevice_release(structinode *inode, struct file *file) { Device_Open --; /* We're now ready for our next caller */ return 0; }

  14. Character Device Example static ssize_tdevice_read(struct file *filp, char *buffer, /* The buffer to fill with data */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ { /* Number of bytes actually written to the buffer */ intbytes_read = 0; /* Actually put the data into the buffer */ while (length && *hello_msg_Ptr) { /* The buffer is in the user data segment, not the kernel segment; * assignment won't work. We have to use put_user which copies data from * the kernel data segment to the user data segment. */ put_user(*(hello_msg_Ptr++), buffer++); length--; bytes_read++; } /* Actually put the data into the buffer */ while (write_msg_Ptr && length && *write_msg_Ptr) { /* The buffer is in the user data segment, not the kernel segment; * assignment won't work. We have to use put_user which copies data from * the kernel data segment to the user data segment. */ put_user(*(write_msg_Ptr++), buffer++); length--; bytes_read++; } /* Most read functions return the number of bytes put into the buffer */ return bytes_read; }

  15. Character Device Example static ssize_tdevice_write(struct file *filp, const char *buff, size_tlen, loff_t *off) { char new_msg[80] = {0}; copy_from_user(new_msg,buff,len); if(len > 60) len = 65; snprintf(write_msg,15+len,"Last Message: %s\n", new_msg); write_msg_Ptr = write_msg; return len; }

More Related