1 / 32

Linux Kernel Module

Linux Kernel Module. 9564552 許國祥 9662636 陳薏如 9662571 曾偉縉 9662603 黃偉任. Outline. Introduction Kernel Components Module load and unload operation The detail of load module operation The different between kernel 2.4 and 2.6 How to write a kernel module. Introduction.

Download Presentation

Linux Kernel Module

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. Linux Kernel Module 9564552 許國祥9662636 陳薏如 9662571 曾偉縉 9662603 黃偉任

  2. Outline • Introduction • Kernel Components • Module load and unload operation • The detail of load module operation • The different between kernel 2.4 and 2.6 • How to write a kernel module

  3. Introduction • Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. • They extend the functionality of the kernel without the need to reboot the system. • Use insmod and rmmod command can load and unload the modules.

  4. Kernel Components • Process Management • Process life cycle, Inter Process Communication, I/O • Scheduling (long-term, short-term) • Memory Management • Virtual memory, management, security • File System • File system tree, management, security • Device Control • Almost every system operation maps to a physical device • The code used to do those operations is called Device Driver • Networking • Collect incoming packets and De-Multiplexing them • Deliver outgoing packets

  5. Classes of Devices and Modules

  6. Kernel Space VS User Space • Hardware supported protection • Instructions with supervisor mode (kernel space) • Everything is allowed. • Instructions with user mode (user space) • Regulated access to both hardware and memory . • Application usually runs in user mode • Switch to supervisor mode when it requests system call • Kernel code operates on behalf of the calling process. • Switch to supervisor mode when it is interrupted • Interrupt handler routines do task in kernel mode.

  7. Kernel Modules VS Applications • Major differences • Kernel modules just registers itself for later invocation • The module_init macro. • Event-driven. • Kernel modules should carefully undo everything • The exit function specified in the module_exit macro • User program can let kernel do cleanup tasks. • Kernel modules is only linked to the kernel • Modules can use only symbols exported by kernel. • Include files are resident in “include/linux” or “include/asm”. • User program can link various libraries. • A fault in kernel module kills “at least” current process, if not the whole system

  8. Classes of Modules type • Character Devices • Be accessed as a stream of bytes • Ex: console, serial ports • Block Devices • Basically, I/O is done in block unit • Linux allows applications to read/write block device like a char device (Buffering) • Ex: Disk • Network Interfaces • Sending and receiving packets • Different from character and block devices • Do not have entry in filesystem (name only, etc. eth0) • Use socket-related kernel system calls to access interface

  9. Module Information • Predefined macros for module information manipulation • MODULE_AUTHOR() • e.g. MODULE_AUTHOR( • MODULE_DESCRIPTION() • Human-readable statements • MODULE_VERSION() • Code revision number for your module

  10. Module License • MODULE_LICENSE • Not necessary, but used to tell kernel which license applies to the module codes • Whether it is free or whether the community should take care the loading problem or bugs • You can see those license term in <linux/module.h> • "GPL" • "GPL v2" • "GPL and additional rights" • "Dual BSD/GPL" • "Dual MPL/GPL" • "Proprietary“ (default)

  11. Module Operation command • modinfo • modprobe • depmod • lsmod • insmod • rmmod

  12. Module load and unload operation

  13. Module load and unload operation • insmod do the load tasks • Load the module into kernel • Use sys_init_module() to allocate kernel spaces • Link unresolved symbol to the symbol table of kernel • Invoke the init function of module to do initialization • rmmod do the unload tasks • rmmod may fail when reference > 0 or kernel does not support module removal • lsmod will list loaded modules • Via /proc/modules file

  14. The detail of load module operation • sys_init_modulemodutils function • init_module() • setup module object • Read the section of kernel module object file • sys_init_module system call • long sys_init_module(const char *name_user, struct module *mod_user); • Load kernel object into kernel space

  15. The different between kernel 2.4 and 2.6 • Module type *.o vs *.ko • Register function • Major and Minor number length

  16. Build 2.4 kernel module CC=gcc MODCFLAGS := -Wall –DMODULE -D__KERNEL__ -DLINUX hello.o: hello.c $(CC) $(MODCFLAGS) -c hello.c

  17. Build 2.6 kernel module ifeq ($(KERNELRELEASE),) KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions else obj-m := 2_helloworld.o endif

  18. Register function 2.4 int init_module(void) { if (register_chrdev(DEV_MAJOR, DEV_NAME, &card_fops) < 0) { printk("Couldn't register a device."); return -1; } return 0; } void cleanup_module(void) { if (unregister_chrdev(DEV_MAJOR, DEV_NAME)) printk("failed to unregister driver"); else printk("driver un-installed\n"); }

  19. Register function 2.6 static dev_t myDev = 0; static char myName[] = "TestDevice"; static int result = 0; static int hello_init(void) { if( (result = alloc_chrdev_region(&myDev, 0, 1, myName)) != 0){ printk("Unable to allocate device number\n"); return -1; } printk(KERN_ALERT "My major is %d, minor is %d\n“, MAJOR(myDev),MINOR(myDev)); return 0; } static void hello_exit(void) { if(result == 0){ unregister_chrdev_region(myDev, 1); } }

  20. Device Files – Major and Minor number • Device numbers registration and release • Manually-assigned registration • Dynamically-allocated registration • Release int register_chrdev_region( dev_t first, # The beginning device number unsigned int count, # Number of continuous device number char *name # Device name (shown in /proc/devices) ); int alloc_chrdev_region( dev_t *dev, # output-only that holds the first device unsigned int firstminor, # The beginning of first minor number unsigned int count, char *name ); void unregister_chrdev_region( dev_first, # The first device number going to release unsigned int count );

  21. Major and Minor number length • Both numbers are stored in dev_t type • Defined in <linux/types.h> • In kernel 2.4 :8bis for major and 8 bits for minor • In kernel 2.6:12bis for major and 20 bits for minor

  22. How to write a kernel module From http://blog.jollen.org/mt-tb.cgi/8

  23. Device Files • Character and Block devices are accessed via device files in file system • Under /dev drivers Major =5 Minor = 0

  24. The File Operation Structure • All that is what you can provide • Prepare a file_operations structure and • Fill in the function pointer that you have implemented and • Standard C tagged structure initialization syntax (better) • Traditional method (problematic across different version) • Do registration • e.g. struct file_operations PerfEvl_fops = { NULL, /* llseek */ PerfEvl_read, NULL, /* write */ NULL, /* readdir */ NULL, /* poll */ PerfEvl_ioctl, NULL, /* mmap */ PerfEvl_open, NULL, /* flush */ PerfEvl_release, NULL, /* fsync */ NULL, /* fasync */ NULL /* lock */ }; struct file_operations scull_fops = { .owner = THIS_MODULE, .llseek = scull_llseek, .read = scull_read, .write = scull_write, .ioctl = scull_ioctl, .open = scull_opne, .release = scull_release };

  25. struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*dir_notify)(struct file *filp, unsigned long arg); int (*flock) (struct file *, int, struct file_lock *); };

  26. Capability of Driver – The cdev Structure • The kernel internal structure to represents a character device file • Defined in <linux/cdev.h> struct cdev { struct kobject kobj; struct module *owner; struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count; };

  27. Device Files – Major and Minor number • Steps to create devices files under /dev • Make sure your major and minor number • Either static or dynamic allocation (/proc/devices) • % cat /proc/devices | grep TestDevice | awk ‘{print $1}’ • Create device files using mknod • [format]: mknod name type major minor • e.g: % mknod /dev/TestDevice c 253 0 • Change file permission and owner (depend on driver) • % chown root:wheel /dev/TestDevice • % chmod 664 /dev/TestDevice

  28. Memory access between user space and kernel space • You might receive some pointers that point to user space in your driver function • Do not dereference it directly • Access it via kernel functions (<asm/uaccess.h>): • They would check whether the user space pointer is valid unsigned long copy_to_user( void __user *to, const void *from, unsigned long count); unsigned long copy_from_user( void *to, const void __user *from, unsigned long count);

  29. The read/write method • Copy data from kernel to user program / from user program to kernel • Use copy_to_user() or __copy_to_user() • The __copy_to_user() version would not check validity of user space pointer • Use copy_from_user() or __copy_from_user() • Update position • Return value • Negative if error occurs • Positive value to tell user program how many data transferred (0 means end-of-file) • Error during transfer should be reported in the next read

  30. The read/write method

  31. Conclude From http://blog.jollen.org/mt-tb.cgi/8

  32. References • http://tldp.org/LDP/lkmpg/2.6/html/index.html • http://www.jollen.org • Linux Device Driver, 2rd. • Linux Device Driver, 3rd. • Linux Kernel Development, 2nd.

More Related