Building and Running Modules Sarah Diesburg COP 5641.

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.
Computer System Laboratory
Hp education services education.hp.com 85 System Crash Dump Version C.00 H4264S Module 9 Slides.
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.
CS 450 Module R4. R4 Overview Due on March 11 th along with R3. R4 is a small yet critical part of the MPX system. In this module, you will add the functionality.
Building and Running Modules Linux Kernel Programming CIS 4930/COP 5641.
Allocating Memory Ted Baker  Andy Wang CIS 4930 / COP 5641.
Linking & Loading CS-502 Operating Systems
Building and Running Modules Ted Baker  Andy Wang CIS 4930 / COP 5641.
Embedded Systems Programming Writing Device Drivers.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 12 Separate Compilation Namespaces Simple Make Files (Ignore all class references.
Page 1 Processes and Threads Chapter 2. Page 2 Processes The Process Model Multiprogramming of four programs Conceptual model of 4 independent, sequential.
How to make a pseudo-file As a follow-up to our first lab, we examine the steps needed to create our own ‘/proc’ file.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Phones OFF Please Processes Parminder Singh Kang Home:
An Introduction to Device Drivers Sarah Diesburg COP 5641 / CIS 4930.
Loadable Kernel Modules Dzintars Lepešs The University of Latvia.
Operating System Program 5 I/O System DMA Device Driver.
MIPS coding. SPIM Some links can be found such as:
Copyright 2001 Oxford Consulting, Ltd1 January Storage Classes, Scope and Linkage Overview Focus is on the structure of a C++ program with –Multiple.
Sogang University Advanced Operating Systems (Linux Module Programming) Sang Gue Oh, Ph.D.
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
Processes and Threads CS550 Operating Systems. Processes and Threads These exist only at execution time They have fast state changes -> in memory and.
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.
Writing a Run Time DLL The application loads the DLL using LoadLibrary() or LoadLibraryEx(). The standard search sequence is used by the operating system.
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.
An Introduction to Device Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.
1 Computer Systems II Introduction to Processes. 2 First Two Major Computer System Evolution Steps Led to the idea of multiprogramming (multiple concurrent.
Operating Systems CSE 411 CPU Management Sept Lecture 10 Instructor: Bhuvan Urgaonkar.
Interfacing Device Drivers with the Kernel
How to write a MSGQ Transport (MQT) Overview Nov 29, 2005 Todd Mullanix.
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Operating Systems Processes and Threads.
Lab 12 Department of Computer Science and Information Engineering National Taiwan University Lab12 – Driver 2014/12/16 1 /21.
Silberschatz, Galvin and Gagne ©2011 Operating System Concepts Essentials – 8 th Edition Chapter 2: The Linux System Part 2.
Week 4 - Friday.  What did we talk about last time?  Some extra systems programming stuff  Scope.
Kernel Structure and Infrastructure David Ferry, Chris Gill CSE 522S - Advanced Operating Systems Washington University in St. Louis St. Louis, MO
Copyright © Curt Hill More on Operating Systems Continuation of Introduction.
1 Intro to Kernel Modules and /proc Sarah Diesburg CS 3430 Operating Systems.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
Introduction to Operating Systems
Processes and threads.
Process concept.
Process Management Process Concept Why only the global variables?
Linking & Loading.
An Introduction to Device Drivers
Introduction to Operating Systems
Memory Protection: Kernel and User Address Spaces
Chapter 2: The Linux System Part 2
Intro to Kernel Modules and /proc
System Structure and Process Model
Memory Allocation CS 217.
chapter 2 - Hello World Model
Kernel Structure and Infrastructure
CS 6560 Operating System Design
Lecture Topics: 11/1 General Operating System Concepts Processes
Operation System Program 1
Process Control B.Ramamurthy 2/22/2019 B.Ramamurthy.
CS 6560 Operating System Design Kernel Loadable Modules
Kernel Structure and Infrastructure
CSE 451: Operating Systems Winter 2003 Lecture 4 Processes
Unix Process Control B.Ramamurthy 4/11/2019 B.Ramamurthy.
Chapter 2 Processes and Threads 2.1 Processes 2.2 Threads
CSE 451: Operating Systems Autumn 2004 Module 4 Processes
Process Description and Control in Unix
Foundations and Definitions
Process Description and Control in Unix
In Today’s Class.. General Kernel Responsibilities Kernel Organization
SPL – PS1 Introduction to C++.
Presentation transcript:

Building and Running Modules Sarah Diesburg COP 5641

Setting Up Your Test System Building modules requires a configured and built kernel tree  Can obtain one from kernel.org Modules are linked against object files found in the kernel source tree

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); No main function

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); Invoked when the module is loaded

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); Invoked when the module is removed

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); Micros to indicate which module initialization and exit functions to call

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); This module bears a free license

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); The ordering matters sometimes

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); ~= printf in C library No floating-point support

The Hello World Module #include MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “Hello, world\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “Goodbye, cruel world\n”); } module_init(hello_init); module_exit(hello_exit); Indicates the message priority Note that no ‘,’ after KERN_ALERT

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules Notice the quote ‘`’

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password:

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password: root#

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password: root# insmod hello.ko

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password: root# insmod hello.ko Hello, world root# Might be printed to /var/log/messages

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password: root# insmod hello.ko Hello, world root# rmmod hello.ko Either hello or hello.ko

Module Loading/Unloading % make –C /usr/src/linux M=`pwd` modules make: Entering directory `/usr/src/linux ' Building modules, stage 2. MODPOST 1 modules make: Leaving directory `/usr/src/linux ' % su Password: root# insmod hello.ko Hello, world root# rmmod hello.ko Goodbye cruel world root# Might be printed to /var/log/messages

Kernel Modules vs. Applications Applications  Can access various functions in user- level libraries (e.g., printf in C library) Kernel modules  No user-level libraries  printk is defined within the kernel Exported to modules  Should include only header files defined within the kernel source tree

Linking a Module to the Kernel

Threads/Processes Thread: A sequential execution stream Address space: Chunks of memory and everything needed to run a program Process: An address space + thread(s)

User Space and Kernel Space Kernel modules run in kernel space  Execute in the supervisor mode  Everything is allowed  Share the same address space Applications run in user space  Execute in the user mode  Restricted access to hardware  Each has its own address space

System Calls System calls allow processes running at the user mode to access kernel functions that run under the kernel mode Prevent processes from doing bad things, such as  Halting the entire operating system  Modifying the MBR

Hardware Interrupts Can suspend user-level processes  Transfers execution from user space to kernel space  Interrupts are handled by separate threads Not related to any user-level processes Asynchronous

Role of a Module Extend kernel functionality  Modularized code running in kernel space

Concurrency in the Kernel Sources of concurrency  Hardware interrupts  Kernel timers  Multiple CPUs  Preemption

Handling Concurrency Kernel code needs to be reentrant  Capable of running in more than one thread execution context at the time  Prevent corruption of shared data  Avoid race conditions Results depend on the timing of their executions

The Current Process Most actions performed by the kernel are done on behalf of a specific process The current process  Defined as a per CPU MACRO  struct task_struct *current; #include

The Current Process Print the current command name, process ID, and task (thread) ID #include printk(KERN_INFO “The process is \“%s\” (tgid %i) (pid %i)\n”, current->comm, current->tgid, current->pid);

A Few Other Details Limited address space for kernel  Should dynamically allocate and deallocate space for large data structures Functions starting with __ should be used with caution

Compiling Modules Details on compiling the kernel  Documentation/kbuild Required tools with matching versions  Compiler, module utilities, and so on...  If the version is too new can cause problems as well  Documentation/Changes

Simplest Makefile obj-m := hello.o One module to be built from hello.o Resulting module is hello.ko

More on Makefile s Suppose you have a module called module.ko Generated from file1.c and file2.c obj-m := module.o module-objs := file1.o file2.o

More on Makefile s To make, type the following in the directory containing the module source and Makefile make -C /usr/src/linux / M=`pwd` modules Changing to the kernel source directory

More on Makefile s To make, type the following in the directory containing the module source and Makefile make -C /usr/src/linux / M=`pwd` modules Move back to the module source directory

A More Elaborate Makefile # If KERNELRELEASE is defined, we’ve been invoked from the # kernel build system and can use its language ifneq ($(KERNELRELEASE),) obj-m := hello.o # Otherwise we were called directly from the command # line; invoke the kernel build system. else KERNELDIR ?= /lib/modules/$(shell uname –r)/build PWD := $(shell pwd) modules: $(MAKE) –C $(KERNELDIR) M=$(PWD) modules clean: rm –fr *.o *~ core.*.cmd *.ko *.mod.c.tmp_versions endif Kernel release version If KERNELDIR is not defined, define it.

Loading/Unloading Modules insmod  Dynamically links module into the kernel  Resolves all symbols with the kernel symbol table  Returns the value of the module’s init function  (more /proc/modules to see a list of currently loaded modules)

Loading/Unloading Modules insmod failure modes  Unknown/unfound symbol  Refers to symbols exported as GPL but does not declare the GPL license  Dependent modules are not yet loaded  Return value of init is bad (non-zero)

Loading/Unloading Modules rmmod  Removes a kernel module rmmod failure modes  Fails when the kernel believes that it is still in use (reference count > 0)  Problem with module init (exit functions cannot successfully complete Might need to reboot to remove the module

Version Dependency Module’s code has to be recompiled for each version of the kernel  Sensitive to kernel version, compiler version, and various configuration variables If things don’t match root# /sbin/insmod hello.ko Error inserting ‘./hello.ko’: -1 Invalid module format

Version Dependency Possible remedies  Check /var/log/messages for specific causes  Change KERNELDIR as needed

The Kernel Symbol Table Addresses of global functions and variables A module can export its symbols for other modules to use Module stacking  E.g., MSDOS file system relies on symbols exported by the FAT module

Module Stacking Example Stacking of parallel port driver modules Can use modprobe to load all modules required by a particular module

Auto-loading Modify /etc/modprobe.conf Example alias eth0 e1000 Whenever eth0 is referenced, the kernel module e1000 is loaded

Export Module Symbols In module header files Use the following macros EXPORT_SYMBOL(name); EXPORT_SYMBOL_GPL(name); _GPL makes the symbol available only to GPL-licensed modules

Defending against Namespace Problems Declare all functions and global variables static unless you mean to export them Use a module-unique prefix for all exported symbols

Preliminaries Just about all module code includes the following header files  Symbols and functions needed by modules  Allows you to specify initialization and cleanup functions

Initialization and Shutdown Initialization function  Registers any facility, or functionality offered by the module static int __init initialization_function(void) { /* initialization code here */ } module_init(initialization_function);

Initialization and Shutdown Initialization function  Registers any facility, or functionality offered by the module static int __init initialization_function(void) { /* initialization code here */ } module_init(initialization_function); Indicates that the module loader can drop this function after the module is loaded, making its memory available

Initialization and Shutdown Initialization function  Registers any facility, or functionality offered by the module static int __init initialization_function(void) { /* initialization code here */ } module_init(initialization_function); Mandatory to specify the initialization function

The Cleanup Function Unregisters various functionalities and returns all resources static void __exit cleanup_function(void) { /* Cleanup code here */ } module_exit(cleanup_function);

The Cleanup Function Unregisters various functionalities and returns all resources static void __exit cleanup_function(void) { /* Cleanup code here */ } module_exit(cleanup_function); Indicates that this function is for unloading only

The Cleanup Function Unregisters various functionalities and returns all resources static void __exit cleanup_function(void) { /* Cleanup code here */ } module_exit(cleanup_function); Needed to specify the cleanup function

Error Handling During Initialization static int __init my_init_function(void) { int err; /* registration takes a pointer and a name */ err = register_this(ptr1, “skull”); if (err) goto fail_this; err = register_that(ptr2, “skull”); if (err) goto fail_that; err = register_those(ptr3, “skull”); if (err) goto fail_those; return 0; /* success */ fail_those: unregister_that(ptr2, “skull”); fail_that: unregister_this(ptr1, “skull”); fail_this: return err; /* propagate the error */ }

Error Handling During Initialization static int __init my_init_function(void) { int err; /* registration takes a pointer and a name */ err = register_this(ptr1, “skull”); if (err) goto fail_this; err = register_that(ptr2, “skull”); if (err) goto fail_that; err = register_those(ptr3, “skull”); if (err) goto fail_those; return 0; /* success */ fail_those: unregister_that(ptr2, “skull”); fail_that: unregister_this(ptr1, “skull”); fail_this: return err; /* propagate the error */ } Check for error codes

Goto? Cleaner code for error recovery Faster than separate error-handling functions Better for the cache Great online discussion 

Cleanup Function static void __exit my_cleanup_function(void) { unregister_those(ptr3, “skull”); unregister_that(ptr2, “skull”); unregister_this(ptr1, “skull”); return err; }

Other Code Patterns int __init my_init(void) { int err = -ENOMEM; item1 = allocate_thing(arg1); item2 = allocate_thing2(arg2) if (!item1 || !item2) goto fail; err = register_stuff(item1, item2); if (!err) { stuff_ok = 1; } else { goto fail; } return 0; fail: my_cleanup(); return err; }

Other Code Patterns void my_cleanup(void) { if (item1) release_thing(item1); if (item2) release_thing2(item2); if (stuff_ok) unregister_stuff(); return; } No __exit when it is called by nonexit code

Module-Loading Races A facility is available once a register call is completed Kernel can make calls to registered functions before the initialization function completes Obtain and initialize all critical resources before calling the register function

Module Parameters Include moduleparam.h, stat.h Need to use the following macros  module_param(name, type, permission)  module_param_array(name, type, num, permission)

Example Use of Module Parameters Allow the “hello world” module to say hello to someone a number of times %/sbin/insmod./hello.ko someone=“Mom” times=2 Hello Mom %

Example Use of Module Parameters Need to use the module_param macro static char *someone = “world”; static int times = 1; module_param(times, int, S_IRUGO); module_param(someone, charp, S_IRUGO); Read-only flag, defined in stat.h

Support Parameter Types bool charp  Memory allocated for user provide strings int, long, short, uint, ulong, ushort  Basic integers

User Level Facilities X server Some USB drivers Various daemons/threads FUSE

User Level Facilities + Fast development + C library support + Conventional debugger + Fault isolation + Portability - Interrupts not available - Privileged access required for direct memory access - Poor performance