Loadable Kernel Modules

Slides:



Advertisements
Similar presentations
DEVICE DRIVER VINOD KAMATH CS691X PROJECT WORK. Introduction How to write/install device drivers Systems, Kernel Programming Character, Block and Network.
Advertisements

Linux device-driver issues
Device Drivers. Linux Device Drivers Linux supports three types of hardware device: character, block and network –character devices: R/W without buffering.
RT_FIFO, Device driver.
Lecture for Lab 3, Exp1 of EE505 (Developing Device Driver) T.A. Chulmin Kim CoreLab. Mar, 11, 2011 [XenSchedulerPaper_Hotcloud-commits] r21 - /
Computer System Laboratory
CS 11 C track: lecture 7 Last week: structs, typedef, linked lists This week: hash tables more on the C preprocessor extern const.
Part IV: Memory Management
R4 Dynamically loading processes. Overview R4 is closely related to R3, much of what you have written for R3 applies to R4 In R3, we executed procedures.
CSCC69: Operating Systems
The Linux Kernel: Memory Management
Kernel memory allocation
Embedded Systems Programming Writing Device Drivers.
63 UQC152H3 Advanced OS Writing a Device Driver. 64 The SCULL Device Driver Simple Character Utility for Loading Localities 6 devices types –Scull-03.
Introduction to Kernel
Chapter 6. 2 Objectives You should be able to describe: Function and Parameter Declarations Returning a Single Value Pass by Reference Variable Scope.
POSIX: Files Introduction to Operating Systems: Discussion 1 Read Solaris System Interface Guide: Ch. 5.1 Basic File I/O.
Loadable Kernel Modules Dzintars Lepešs The University of Latvia.
Kernel module programming Nezer J. Zaidenberg. reference This guide is built on top of The Linux Kernel Module Programming Guide The guide is available.
Operating System Program 5 I/O System DMA Device Driver.
Memory Addressing in Linux  Logical Address machine language instruction location  Linear address (virtual address) a single 32 but unsigned integer.
A First Book of C++: From Here To There, Third Edition2 Objectives You should be able to describe: Function and Parameter Declarations Returning a Single.
Runtime Environments Compiler Construction Chapter 7.
Sogang University Advanced Operating Systems (Linux Module Programming) Sang Gue Oh, Ph.D.
Chapter 8 – Main Memory (Pgs ). Overview  Everything to do with memory is complicated by the fact that more than 1 program can be in memory.
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.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Memory Addressing / Kernel Modules.
UNIX Files File organization and a few primitives.
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Memory: Relocation.
Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system.
Files & File system. A Possible File System Layout Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved
LOGO System Call. Introduction System call is the mechanism used by an application program to request service from the OS. Users use it to communicate.
1 CS503: Operating Systems Spring 2014 Part 0: Program Structure Dongyan Xu Department of Computer Science Purdue University.
Why Do We Need Files? Must store large amounts of data. Information stored must survive the termination of the process using it - that is, be persistent.
Interfacing Device Drivers with the Kernel
CSC 8505 Compiler Construction Runtime Environments.
CSC414 “Introduction to UNIX/ Linux” Lecture 2. Schedule 1. Introduction to Unix/ Linux 2. Kernel Structure and Device Drivers. 3. System and Storage.
File Systems cs550 Operating Systems David Monismith.
4P13 Week 12 Talking Points Device Drivers 1.Auto-configuration and initialization routines 2.Routines for servicing I/O requests (the top half)
Lab 12 Department of Computer Science and Information Engineering National Taiwan University Lab12 – Driver 2014/12/16 1 /21.
COMP 3438 – Part I - Lecture 5 Character Device Drivers
File System Department of Computer Science Southern Illinois University Edwardsville Spring, 2016 Dr. Hiroshi Fujinoki CS 314.
Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015.
File System Design David E. Culler CS162 – Operating Systems and Systems Programming Lecture 23 October 22, 2014 Reading: A&D a HW 4 out Proj 2 out.
Computer System Structures
OS – Ex 1 Nezer J. Zaidenberg.
Introduction to Kernel
Memory Management.
Protection of System Resources
Computer System Laboratory
Linux Kernel Module Programming
Linux Kernel Driver.
Want to play a game? – Linux Kernel Modules
Chapter 8: Main Memory.
Operation System Program 4
An overview of the kernel structure
Chapter 2: System Structures
Main Memory Background Swapping Contiguous Allocation Paging
CS703 - Advanced Operating Systems
CS 6560 Operating System Design
CS 6560 Operating System Design Kernel Loadable Modules
Chapter 8: Memory Management strategies
Implementation of Embedded OS
Computer System Laboratory
Runtime Environments What is in the memory?.
Buddy Allocation CS 161: Lecture 5 2/11/19.
COMP755 Advanced Operating Systems
Lecture 20: Representing Data Elements
Page Main Memory.
Presentation transcript:

Loadable Kernel Modules

Overview What is a loadable kernel module When to use modules Intel 80386 memory management How module gets loaded in proper location Internals of module Linking and unlinking module

Kernel module description To add a new code to a Linux kernel, it is necessary to add some source files to kernel source tree and recompile the kernel. But you can also add code to the Linux kernel while it is running. A chunk of code added in such way is called a loadable kernel module Typical modules: device drivers file system drivers system calls

When kernel code must be a module higher level component of Linux kernel can be compiled as modules some Linux kernel code must be linked statically then component is included in the kernel or it is not compiled at all Basic Guideline Build working base kernel, that include anything that is necessary to get the system up, everything else can be built as modules

Advantages of modules There is no necessity to rebuild the kernel, when a new kernel option is added Modules help find system problems (if system problem caused a module just don't load it) Modules save memory Modules are much faster to maintain and debug Modules once loaded are inasmuch fast as kernel

Module Implementation Modules are stored in the file system as ELF object files The kernel makes sure that the rest of the kernel can reach the module's global symbols Module must know the addresses of symbols (variables and functions) in the kernel and in other modules (/proc/syms <2.6 /proc/kallsyms - 2.6) The kernel keeps track of the use of modules, so that no modules is unloaded while another module or kernel is using it (/proc/modules)

Module Implementation The kernel considers only modules that have been loaded into RAM by the insmod program and for each of them allocates memory area containing: a module object null terminated string that represents module's name the code that implements the functions of the module

Module Object

80386 Memory Management

Segment Translation

Page Translation

Linux paging model

Reserved Page Frames

Kernel Page Tables Provisional kernel page tables – first phase The Page Global Directory and Page table are initialized statically during the kernel compilation. During this phase of initialization kernel can address the first 4MB either with or without paging. Final kernel page table – second phase transforms linear addresses starting from PAGE_OFFSET into physical addressing starting from 0

Noncontiguous Memory Area Management free range of linear addresses are located in the area starting from PAGE_OFFSET (usually the beginning of fourth gigabyte). Kernel reserves whole upper area of memory, but uses only a small fraction of the gigabyte.

Allocating a Noncontiguous Memory Area The vmalloc( ) function allocates a noncontiguous memory area to the kernel. If the function is able to satisfy the request, then it returns the initial linear address of the new area; otherwise, it returns a NULL pointer The function then uses the pgd_offset_k macro to derive the entry in the Page Global Directory related to the initial linear address of the area

Allocating a Noncontiguous Memory Area The function then executes the cycle, in which : it first creates a Page Middle Directory for the new area. then it allocates all the Page Tables associated with the new Page Middle Directory. then, it updates the entry corresponding to the new Page Middle Directory in all existing Page Global Directories then it adds the constant 222, that is, the size of the range of linear addresses spanned by a single Page Middle Directory, to the current value of address repeated until all page table have been set up.

Releasing a Noncontiguous Memory Area noncontiguous memory areas releases the vfree( ) function. for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; vmfree_area_pages((unsigned long)(tmp->addr), tmp->size); kfree(tmp); return; }

Linking and Unlinking Modules

Programs for linking and unlinking insmod Reads from the name of the module to be linked Locates the file containing the module's object code Computes the size of the memory area needed to store the module code, its name, and the module object Invokes the create_module( ) system call Invokes the query_module( ) system call Using the kernel symbol table, the module symbol tables, and the address returned by the create_module( ) system call, relocates the object code included in the module's file. Allocates a memory area in the User Mode address space and loads with a copy of the module object Invokes the init_module( ) system call, passing to it the address of the User Mode memory area Releases the User Mode memory area and terminates

Programs for linking and unlinking lsmod reads /proc/modules rmmod From reads the name of the module to be unlinked. Invokes the query_module( ) Invokes the delete_module( ) system call, with the QM_REFS subcommand several times, to retrieve dependency information on the linked modules. modprobe takes care of possible complications due to module dependencies, uses depmod program and /etc/modules.conf file

Device drivers There are two major ways for a kernel module to talk to processes: To use the proc file system (/proc directory) Through device files (/dev directory) Device driver sits between some hardware and the kernel I/O subsystem. Its purpose is to give the kernel a consistent interface to the type of hardware it "drives".

Compiling kernel module A kernel module is not an independent executable, but an object file which will be linked into the kernel in runtime and they should be compiled with -c flag _KERNEL_ symbol MODULE symbol LINUX symbol CONFIG_MODVERSIONS symbol

Example of simple char device /* The necessary header files */ /* Standard in kernel modules */ #include <linux/kernel.h> /* We’re doing kernel work */ #include <linux/module.h> /* Specifically, a module */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif #include <linux/fs.h> #include <linux/wrapper.h> #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0) #include <asm/uaccess.h> #define SUCCESS 0 /* Device Declarations */ /* The name for our device, as it will appear /* in /proc/devices */ #define DEVICE_NAME "char_dev" #define BUF_LEN 80

/* Used to prevent */ /* concurent access into the same device */ static int Device_Open = 0; /* The message the device will give when asked */ static char Message[BUF_LEN]; static char *Message_Ptr; /* This function is called whenever a process * attempts to open the device file */ static int device_open(struct inode *inode, struct file *file) { static int counter = 0; #ifdef DEBUG printk ("device_open(%p,%p)\n", inode, file); #endif printk("Device: %d.%d\n“, inode->i_rdev >> 8, inode->i_rdev & 0xFF); if (Device_Open) return -EBUSY; Device_Open++; sprintf(Message, counter++, Message_Ptr = Message; MOD_INC_USE_COUNT; return SUCCESS; }

if (Device_Open) return -EBUSY; Device_Open++; sprintf(Message, counter++, Message_Ptr = Message; MOD_INC_USE_COUNT; return SUCCESS; } #if LINUX_VERSION_CODE >=KERNEL_VERSION(2,2,0) static int device_release(struct inode *inode, struct file *file) #else static void device_release(struct inode *inode, #endif { Device_Open --; MOD_DEC_USE_COUNT; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) return 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static ssize_t device_read(struct file *file, char *buffer, /* The buffer to fill with data */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ #else static int device_read(struct inode *inode, struct file *file, char *buffer, /* The buffer to fill with * the data */ int length) /* The length of the buffer * (mustn’t write beyond that!) */ #endif { /* Number of bytes actually written to the buffer */ int bytes_read = 0; /* If we’re at the end of the message, return 0 if (*Message_Ptr == 0) return 0; /* Actually put the data into the buffer */ while (length && *Message_Ptr) { put_user(*(Message_Ptr++), buffer++); length --; bytes_read ++; }

#ifdef DEBUG printk ("Read %d bytes, %d left\n", bytes_read, length); #endif return bytes_read; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static ssize_t device_write(struct file *file, const char *buffer, /* The buffer */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ #else static int device_write(struct inode *inode, struct file *file, const char *buffer, int length) { return -EINVAL;

/* Module Declarations */ struct file_operations Fops = { NULL, /* seek */ device_read, device_write, NULL, /* readdir */ NULL, /* select */ NULL, /* ioctl */ NULL, /* mmap */ device_open, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) NULL, /* flush */ #endif device_release /* a.k.a. close */ }; /* Initialize the module - Register the character device */ int init_module() {

/* Register the character device */ Major = module_register_chrdev(0, DEVICE_NAME, &Fops); /* Negative values signify an error */ if (Major < 0) { printk ("%s device failed with %d\n", "Sorry, registering the character", Major); return Major; } return 0; /* Cleanup - unregister the appropriate file from /proc */ void cleanup_module() { int ret; /* Unregister the device */ ret = module_unregister_chrdev(Major, DEVICE_NAME); if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret);