+ All Categories

Download - Kernel Modules

Transcript
Page 1: Kernel Modules

Kernel Modules

Page 2: Kernel Modules

Kernel Module

• Pieces of code that can be loaded and unloaded into the kernel upon demand.

• Compiled as an independent program• With appropriate flags to indicate that it is kernel

code.• Can be linked into the kernel by installation.

– Static/Dynamic loading– “/proc/modules” or “lsmod”

• Enhance the functionality of the kernel.• Example:

– Device Drivers

Page 3: Kernel Modules

Functions in Kernel Module

• int init_module(void) – Invoked when the module is inserted to kernel– Return 0 if success.

• void cleanup_module(void) – Invoked when the module is removed from kernel

• printk() – /usr/src/linux-2.6.5-1.358/include/linux/kernel.h

Page 4: Kernel Modules

#include <linux/kernel.h>#include <linux/module.h>

int init_module(void){

printk(KERN_ALERT "Hello world.\n“);

return 0;}

void cleanup_module(void){

printk(KERN_ALERT "Goodbye world.\n");}

MODULE_LICENSE("GPL"); //GNU Public License v2 or later

Page 5: Kernel Modules

Makefile

ifneq ($(KERNELRELEASE),)

obj-m += hello.o

else

KDIR := /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

endif

Page 6: Kernel Modules

• insmod hello.ko• lsmod or “/proc/modules”• tail -f /var/log/messages• rmmod hello

Page 7: Kernel Modules

Modules vs. Programs

• Programs– main()

– performs a single task from beginning to end

– Run in user mode

– Can call the libc functions

• Modules– init_module & cleanup_module

– registers itself in order to serve future requests

– Run in kernel mode• Part of kernel program

– Only can call the ones exported by the kernel.

• include/linux

• include/asm

• Export all non-static symbols

Page 8: Kernel Modules

Device Drivers

• Character devices– one that can be accessed as a stream of

bytes – Keyboard driver

• Block devices– One that can be accessed as multiples of a

block, usually 1KB per block– Disk driver

Page 9: Kernel Modules

Device Drivers

• To communicate with hardware– Each piece of hardware is represented by a file located in /dev– An application do some operations on that file– The kernel finds corresponding device driver for that file.– Each operation on that file will trigger a function in the device dri

ver for that hardware– The file in /dev is not regular file

• To find the device driver for that file– ls -l /dev/b*– Major number

• Match with driver– Minor number

• used by the driver to distinguish between the various hardware it controls

• ls -l /dev/fd0u*

Page 10: Kernel Modules

Device Drivers

• Defines functions on the file operation– Read, write, open, close, etc

• Register the device to kernel

• creates a file in “/dev” using “mknod”

Page 11: Kernel Modules

Device Drivers

• Function mapping

struct file_operations fops = {

.read = device_read,

.write = device_write,

.open = device_open,

.release = device_release

};

• vi /usr/src/linux-2.6.5-1.358/include/linux/fs.h• int register_chrdev(unsigned int major, const char *name, struct file_

operations *fops); • int unregister_chrdev(unsigned int major, const char *name);

Page 12: Kernel Modules

#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <asm/uaccess.h>

#define DEVICE_NAME "chardev"#define BUF_LEN 80

static int Major;static char msg[BUF_LEN];static char *msg_Ptr;

Page 13: Kernel Modules

static int device_open(struct inode *inode, struct file *file)

{static int counter = 0;sprintf(msg, "This device is opened %d times!\n", counter++);msg_Ptr = msg;try_module_get(THIS_MODULE);

return 0;}

static int device_release(struct inode *inode, struct file *file)

{module_put(THIS_MODULE);return 0;

}

Page 14: Kernel Modules

• We cannot remove the device driver while device file is opened by a process.

• There's a counter which keeps track of how many processes are using your module – the 3rd column in lsmod

• try_module_get(THIS_MODULE);– Increment the use count

• module_put(THIS_MODULE);– Decrement the use count

Page 15: Kernel Modules

static ssize_t device_read(struct file *filp,char *buffer, size_t length,

loff_t * offset){

int bytes_read = 0;

if (*msg_Ptr == 0)return 0;

while (length && *msg_Ptr) {put_user(*(msg_Ptr++), buffer++);

length--;bytes_read++;

}

return bytes_read;}

Page 16: Kernel Modules

• put_user(char src, char* dst);– src is in kernel code segment– dst is in user code segment

• get_user(char dst, char* src);– src is in user code segment– dst is in kernel code segment

• A pointer into userspace should never be simply dereferenced

• #include <asm/uaccess.h>

• buffer is in user data segment• length: length of the buffer

Page 17: Kernel Modules

static ssize_t

device_write(struct file *filp, const char *buff, size_t len, loff_t * off)

{

printk("<1>This operation isn't supported.\n");

return -EINVAL;

}

Page 18: Kernel Modules

static struct file_operations fops = {.read = device_read,.write = device_write,.open = device_open,.release = device_release

};

Page 19: Kernel Modules

int init_module(void){

Major = register_chrdev(0, DEVICE_NAME, &fops);

if (Major < 0) {printk("Failed to register char device.\n");return Major;

}

printk(KERN_ALERT "chardev is assigned to major number %d.\n", Major);

return 0;}

void cleanup_module(void){

int ret = unregister_chrdev(Major, DEVICE_NAME);if (ret < 0)

printk("Error in unregister_chrdev: %d\n", ret);}

Page 20: Kernel Modules

mknod

• Create a file in /dev

• And match the file with a device driver• mknod /dev/hello c Major 0

– This Major number is from the output of /var/log/messages

Page 21: Kernel Modules

References

• Linux Device Drivers, 2nd Edition – http://www.xml.com/ldd/chapter/book/index.html

• The Linux Kernel Module Programming Guide – http://tldp.org/LDP/lkmpg/2.6/html/


Top Related