application development for embedded systems

Post on 23-Feb-2016

54 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Application Development for Embedded Systems. Andrea Marongiu, Carlo Caione { a.marongiu , carlo.caione }@ unibo.it. Application Cross-Development. Cross development is the separation of the build environment from the target environment . - PowerPoint PPT Presentation

TRANSCRIPT

Application Development for Embedded Systems

Andrea Marongiu, Carlo Caione {a.marongiu, carlo.caione}@unibo.it

Application Cross-Development Cross development is the separation of the

build environment from the target environment.

Embedded computers where a device has extremely limited resources, are typically not powerful enough to run a compiler, a file system, or a development environment.

Since debugging and testing may also require more resources than are available on an embedded system, cross-compilation can be less involved and less prone to errors than native compilation.

Application Cross-Development

FavouriteEditor

.c

Tool Chain

.o

Targetarchitecture

Target HW Simulator

HW

DevelopmentBoard

Debugger

Toolchain The first and most essential product to

develop applications on any embedded device is a cross-toolchain

A set of tools running on a host machine, used to 1. Compile high-level source code into target object

code2. Link pre-existing collections of object files

(libraries)3. Assemble the whole thing into an executable

object by the target machine

Let us take a closer look..

GNU Toolchain A collection of programming tools produced by the

GNU Project. These tools form a toolchain (suite of tools used in a serial manner) used for developing applications and operating systems.

It plays a vital role in development of Linux kernel, and software for embedded systems.

Projects included in the GNU toolchain are: GNU Compiler Collection (GCC): Suite of compilers for several

programming languages; GNU Binutils: Suite of tools including linker, assembler and other

tools; GNU Debugger (GDB): Code debugging tool; GNU make: Automation tool for compilation and build; GNU build system (autotools):

Compiling code

#include <stdio.h>#define TRUE 1#define FALSE 0

main() { int i; i = 5 * 2; printf(“5 times 2 is %d.\n”, i); printf(“TRUE is %d.\n”, TRUE); printf(“FALSE is %d.\n”, FALSE);}

Handled by the pre-processor

Handled by the compiler

Implemented in C library

Compiling code The pre-processor handles

Macros (#define) Inclusions (#include) Conditional code inclusion (#ifdef, #if) Language extensions (#pragma).

The compiler processes source code and turns it into assembler modules.

The assembler converts them to target binary code.

The linker takes the object files and searches library files to find the routines it calls. It calculates the address references and incorporates any symbolic information to create an executable file format.

GCC (GNU Compiler Collection) The GNU Compiler Collection (usually shortened to GCC)

is a set of compilers produced for various programming languages by the GNU Project.

It is a tool used by nearly every embedded engineer, even those who don’t target Linux

When starting an embedded project, the first tool needed is a cross-compiler, a compiler that generates code intended to work on a machine different from the one on which the code generation occurred.

When used in an embedded project, GCC capably does cross-compilation, without complaint

GCC is available for most embedded platforms, for example Symbian, Freescale Power Architecture-based chips, Playstation and Sega Dreamcast

GCC Architecture

Multiple front-endsCommon intermediate

representation

Retargetable!

GNU Binutils The GNU Binary Utilities, or binutils, is a collection of

programming tools for the manipulation of object code in various object file formats.

The most important tools are

as – Assembler: Transforms the assembly code produced by the compiler into a binary format executable by the target machine

ld – Linker: Takes as input several object files and generates a single executable, resolving interactions between symbols

ar – Archiver: Combines together (possibly) multiple object files into a library. This could be later linked to other applications either statically or dynamically

objdump – Dumper: It allows recreating an assembler file from an object file. It can also dump additional information about different segments of the output file format

Object Archives (Libraries)‣ In computer science, a library is a collection of

subroutines or classes used to develop software‣ Libraries contain code and data that provide

services to independent programs. This allows the sharing and changing of code and data in a modular fashion

‣ Executables and libraries make references known as links to each other through the process known as linking, which is typically done by a linker

‣ Two types of libraries:1. Static libraries2. Dynamic / shared libraries

Runtime Libraries Compilers only generate a small subset of high-level languages

facilities and commands from built-in routines.

It relies on libraries to provide the full range of functions that the language offers: Processor dependent: mathematical functions, string

manipulation and similar features that use the processor and don’t need to communicate with peripherals;

I/O dependent: defines the hardware that the software need to access. The library routine either drives directly the hardware or calls the operating system to perform its task;

System calls: typical routines are those which dinamically allocate memory, task control commands, use semaphores, etc;

Exit routines: used to terminate programs free up the memory used by the application.

Newlib Newlib is a C standard library implementation intended for

use on embedded systems.

It is a conglomeration of several library parts, all under free software licenses that make them easily usable on embedded products.

The section System Calls of the newlib documentation describes how it can be used with many operating systems.

Its primary use is on embedded systems that lack any kind of operating system; in that case it calls a "board support package" that can do things like write a byte of output on a serial port, or read a sector from a disk or other memory device.

As of 2007, devkitARM, a popular toolchain for programming homebrew software for Nintendo DS and Game Boy Advance systems, includes Newlib as its C library

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

C Code GCC

BSP / Kernel

Newlib

Hardware

atoi(), strtol(), bzero(), strcat(), ...

_exit(),close(),fork(),kill(),...

Newlib

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

BSP / Kernel

read()

BSP Kernel

UART_read()

read()

UART

read()

UART

Interrupt 0x80

kernel + BSP

Newlib

Building a ToolchainAn example: arm-elf-gcc We’ve introduced the three main software

blocks composing a toolchain Binutils – Target specific tools Gcc – Compiler for target machine C library – Target specific C library

We now describe the entire process of building a complete toolchain for a ARM7 processor

Building the toolchain for ARM The source code for binutils, gcc and

newlib can be downloaded at http://www.gnu.org/software/binutils/ http://gcc.gnu.org/mirrors.html ftp://sources.redhat.com/pub/newlib/index.html

The standard procedure to build and install each of the products consists of three steps Configuration Build Install

Building the toolchain for ARM For each of the product, create a separate

source and build directory$ROOT> mkdir binutils-src$ROOT> mkdir gcc-src$ROOT> mkdir newlib-src$ROOT> mkdir binutils-build$ROOT> mkdir gcc-build$ROOT> mkdir newlib-build

Then create an INSTALL folder for the entire toolchain

$ROOT> mkdir INSTALL

Building the toolchain for ARM Build and install the binutils specifying the

arm-elf target$ROOT> cd binutils-build$ROOT> ../binutils-src/configure --target=arm-elf \

--prefix=../INSTALL \--program-prefix=arm-elf-

$ROOT> make all install

At the end of the process, in the folder $ROOT/INSTALL/bin we’ll find the cross-tools

$ROOT> ll INSTALL/bin

Building the toolchain for ARM Add to your $PATH environment variable the path

to the binutils just installed, so that the compiler can use them to build the cross-compiler

$ROOT> export PATH=$ROOT/INSTALL/bin:$PATH

Build and install the cross-compiler specifying the arm-elf target and the location of the C library headers

$ROOT> cd gcc-build$ROOT> ../gcc-src/configure --target=arm-elf \

--prefix=../INSTALL \--program-prefix=arm-elf- \--enable-languages=c,c++ \--with-newlib \

--with-headers=../newlib-src/newlib/libc/include$ROOT> make all-gcc install-gcc

Building the toolchain for ARM Build and install the C library$ROOT> cd newlib-build$ROOT> ../newlib-src/configure --target=arm-elf \

--prefix=../INSTALL$ROOT> make all install

Finally, install the entire compiler$ROOT> cd gcc-build$ROOT> make all install

Building the toolchain for ARM

Take a look at the $ROOT/INSTALL/bin folder

Embedded Application Programming

Multimedia SoC

Microcontroller

SW & HW Low Complexity

• The application may use directly the HW• The programmer know the HW and read and write directly internal register

Complex HW

• Programmer needs abstraction layers.• Embedded O.S.• Application use HW facilities throught system call & driver

Custom middleware

• HW programmed by statically linking API•Standard / Custom API•Microkernel

Complexity

Embedded Application Programming

Multimedia SoC

Microcontroller

SW & HW Low Complexity

• The application may use directly the HW• The programmer know the HW and read and write directly internal register

Complex HW

• Programmer needs abstraction layers.• Embedded O.S.• Application use HW facilities throught system call & driver

Custom middleware

• HW programmed by statically linking API•Standard / Custom API•Microkernel

Complexity

Application Cross-Development

FavouriteEditor

Tool Chain

.o

Targetarchitecture

Target HW Simulator

HW

DevelopmentBoard

Debugger

.cApplication

0x0…0 App.

CPU

MEM

Embedded Application Programming

Multimedia SoC

Microcontroller

SW & HW Low Complexity

• The application may use directly the HW• The programmer know the HW and read and write directly internal register

Complex HW

• Programmer needs abstraction layers.• Embedded O.S.• Application use HW facilities throught system call & driver

Custom middleware

• HW programmed by statically linking API•Standard / Custom API•Microkernel

Complexity

O.S. Embedded Why we need an O.S. on embedded system:

Depends on complexity Hardware complexity, programmer needs abstraction layers Multi-process execution => scheduler Memory Managment Unit Store data => File system

Differents O.S.: Windows CE Linux embedded : based on general purpose linux +

BSP ucLinux : Lite version of Linux embedded (No MMU

support) RTems : (No File System, No MMU )

Application Cross-Development

Tool Chain

.o

Targetarchitecture

Target HW Simulator

HW

DevelopmentBoard

Debugger

FavouriteEditor

0x0…0

.c.c.cMicrokernel source code

App.

MEM

CPU

Embedded Application Programming

Multimedia SoC

Microcontroller

SW & HW Low Complexity

• The application may use directly the HW• The programmer know the HW and read and write directly internal register

Complex HW

• Programmer needs abstraction layers.• Embedded O.S.• Application use HW facilities throught system call & driver

Custom middleware

• HW programmed by statically linking API•Standard / Custom API•Microkernel

Complexity

Application Cross-Development

Tool Chain

.o

Targetarchitecture

Target HW Simulator

HW

DevelopmentBoard

Debugger

FavouriteEditor

0x0…0

.c.c.cO.S. kernel source code

O.S. kernel

MEM

CPU

Application Cross-Development

Tool Chain

.o

Targetarchitecture

Target HW Simulator

HW

DevelopmentBoard

Debugger

FavouriteEditor

0x0…0

.cApplication

App. CPU

MEM

O.S. kernel

Linux kernel patching

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

+kernel vanilla BSP patches

‣ Download the new kernel from www.kernel.org

‣ Kernel untar:$ tar -xvf <dir>/linux-2.6.33.tar.bz2

‣ Kernel patch:$ bunzip2 -c <BSP>/linux-2.6.33-BSP.patch.bz2 | patch -p1

[carlo@naomi linux-2.6.34-ARCH]$ ls -altotal 6614drwxr-xr-x 21 root root 624 Jul 6 15:01 .drwxr-xr-x 4 root root 120 Jul 6 15:01 ..drwxr-xr-x 4 root root 120 Jul 5 23:07 archdrwxr-xr-x 2 root root 104 Jul 5 23:07 block-rw-r--r-- 1 root root 111523 Jul 5 23:06 .configdrwxr-xr-x 3 root root 96 Jul 5 23:07 cryptodrwxr-xr-x 3 root root 72 Jul 5 23:06 Documentationdrwxr-xr-x 80 root root 2016 Jul 5 23:07 driversdrwxr-xr-x 62 root root 1560 Jul 5 23:06 fsdrwxr-xr-x 16 root root 400 Jul 5 23:06 includedrwxr-xr-x 2 root root 72 Jul 5 23:07 initdrwxr-xr-x 6 root root 296 Jul 5 23:06 kerneldrwxr-xr-x 2 root root 176 Jul 5 23:07 lib-rw-r--r-- 1 root root 53184 Jul 5 23:06 Makefiledrwxr-xr-x 2 root root 104 Jul 5 23:07 mm-rw-r--r-- 1 root root 646765 Jul 5 23:06 Module.symversdrwxr-xr-x 41 root root 1040 Jul 5 23:07 netdrwxr-xr-x 2 root root 72 Jul 5 23:06 samplesdrwxr-xr-x 12 root root 2544 Jul 5 22:51 scriptsdrwxr-xr-x 6 root root 176 Jul 5 23:07 securitydrwxr-xr-x 19 root root 480 Jul 5 23:06 sounddrwxr-xr-x 2 root root 48 Jul 5 23:06 .tmp_versionsdrwxr-xr-x 2 root root 72 Jul 5 23:07 usrdrwxr-xr-x 3 root root 72 Jul 5 23:07 virt-rw-r--r-- 1 root root 5941605 Jul 5 23:05 vmlinux[carlo@naomi linux-2.6.34-ARCH]$

Linux kernel configuration

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

Generic linux kernel Specific linux kernel (hw)configuration

‣ Kernel configuration:$ make ARCH=arm CROSS_COMPILE=${CROSS_COMPILER} target_defconfig$ make ARCH=arm CROSS_COMPILE=${CROSS_COMPILER} menuconfig

‣ Decide if module or not

Linux kernel cross-compiling

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

linux kernel cross-compilingmodules .ko

zImage

‣ Kernel compiling:$ make ARCH=arm CROSS_COMPILE=${CROSS_COMPILER}

‣ In computing, a loadable kernel module (or LKM) is an object file that contains code to extend the running kernel, or so-called base kernel, of an operating system

‣ Without loadable kernel modules, an operating system would have to have all possible anticipated functionality already compiled directly into the base kernel. Much of that functionality would reside in memory without being used, wasting memory, and would require that users rebuild and reboot the base kernel every time new functionality is desired

‣ Module loading $ insmod ${MODULE}.ko

‣Module unloading $ rmmod ${MODULE}.ko

./linux-2.6.x/driver/...

./linux-2.6.x/arch/boot/zImage

Host and Target

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

host target

‣ Cross-compiling the kernel

‣ Cross-compiling the root filesystem

‣ Executing

zImage + rootfs

JTAG

RS232

ETHERNET

MEMORYBOOTLOADER

Transfer zImage + rootfs to target

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ How to transfer zImage and rootfs into target?

• JTAG

• USB/UART/ETH... connection in bootloader mode

ELF/BIN/HEX JTAG Programmer Flash

ELF/BIN/HEX USB/UART/... Bootloader Flash

TFTP

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Trivial File Transfer Protocol (TFTP) is a file transfer protocol, with the functionality of a very basic form of File Transfer Protocol (FTP)

‣ Due to its simple design, TFTP could be implemented using a very small amount of memory

‣ TFTP is designed to be small and easy to implement, therefore, lacks most of the features of a regular FTP. TFTP only reads and writes files (or mail) from/to a remote server. It cannot list directories, and currently has no provisions for user authentication

‣ TFTP used the ethernet port

zModem

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Old communication protocol used in communication over serial connection

‣ Dramatically improved performance compared to older protocols, ZMODEM also offered restartable transfers, auto-start by the sender, an expanded 32-bit CRC, and control character quoting

Rootfs and wear leveling

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Wear leveling (also written wear levelling) is a technique for prolonging the service life of some kinds of erasable computer storage media, such as Flash memory used in solid-state drives and USB Flash drives

‣ Wear leveling attempts to work around limitations of these storage medias by arranging data so that erasures and re-writes are distributed evenly across the medium. In this way, no single erase block prematurely fails due to a high concentration of write cycles

• CRAMFS‣ The compressed ROM file system (or cramfs) is a free (GPL'ed) read-only Linux file system designed for simplicity and space-efficiency. It is mainly used in embedded systems and small-footprint systems

• JFFS‣ The Journalling Flash File System (or JFFS) is a log-structured file system for use on NOR flash memory devices on the Linux operating system

• JFFS2‣ Journalling Flash File System version 2 or JFFS2 is a log-structured file system for use in flash memory devices. It is the successor to JFFS. JFFS2 has been included in the Linux kernel since the 2.4.10 release. JFFS2 is also available for Open Firmware, the eCos RTOS and the RedBoot bootloader

NFS

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Flash the whole rootfs every time we change something is a waste of time

Network File System (NFS) is a network file system protocol originally developed by Sun Microsystems in 1984, allowing a user on a client computer to access files over a network in a manner similar to how local storage is accessed

Host TargetFlashrootfsrootfs

NFS + ETH

cross-tools

Loadable Kernel Modules

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ The Linux kernel is what's known as a monolithic kernel, which means that the majority of the operating system functionality is called the kernel and runs in a privileged mode. This differs from a micro-kernel, which runs only basic functionality as the kernel and pushes other functionality outside the privileged space.

‣ Linux can be dynamically altered at run time through the use of Linux kernel modules (LKMs)

‣ Dynamically alterable means that you can load new functionality into the kernel, unload functionality from the kernel, and even add new LKMs that use other LKMs. The advantage to LKMs is that you can minimize the memory footprint for a kernel, loading only those elements that are needed (which can be an important feature in embedded systems)

Applications

Kernel

CPU Memory Devices

syscalls

LKM

LKM

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

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

static int hello3_data __initdata = 3;

static int __init hello_3_init(void){ printk(KERN_ALERT "Hello, world %d\n", hello3_data); return 0;}

static void __exit hello_3_exit(void){ printk(KERN_ALERT "Goodbye, world 3\n");}

module_init(hello_3_init);module_exit(hello_3_exit);

MODULE_LICENSE("GPL");MODULE_AUTHOR(“Author”);

Module macros

Entry/exit macros

Module constructor /destructor

‣ The skeleton of a LKM:

LKM lifecycle

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

User

-Spa

ceKe

rnel

-Spa

ceinsmod rmmod

init_module delete_module

sys_init_module sys_delete_module

... ...

utilities

System Calls

Kernel Functions

user-space / kernel-space communication

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ How it it possible to transfer data between user-space and kernel-space?

• Procfs / Sysfs

• Character / block devices

• Socket

• Ioctl

• Syscalls

• Signals

• Mmap

Procfs

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

[carlo@naomi ~]$ cat /proc/version Linux version 2.6.34-ARCH (tobias@T-POWA-LX) (gcc version 4.5.0 20100610 (prerelease) (GCC) ) #1 SMP PREEMPT Mon Jul 5 21:03:38 UTC 2010

#include <linux/fs.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <linux/utsname.h>static int version_proc_show(struct seq_file *m, void *v){

seq_printf(m, linux_proc_banner,utsname()->sysname,utsname()->release,utsname()->version);return 0;

}static int version_proc_open(struct inode *inode, struct file *file){

return single_open(file, version_proc_show, NULL);

}

static const struct file_operations version_proc_fops = {.open = version_proc_open,.read = seq_read,.llseek = seq_lseek,.release = single_release,

};

static int __init proc_version_init(void){proc_create("version", 0, NULL, &version_proc_fops);return 0;

}

module_init(proc_version_init);

ioctl

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ In computing, ioctl, short for input/output control, is a system call for device-specific operations and other operations which cannot be expressed by regular system calls

‣ Uses:

• The most common use of ioctls is to control hardware devices

• One use of ioctls exposed to end-user applications is terminal I/O

• When applications need to extend the kernel, for instance to accelerate network processing, ioctl calls provide a convenient way to bridge userspace code to kernel extensions

‣ A Unix ioctl call takes as parameters:

• An open file descriptor

• A request code number

• Either an integer value, possibly unsigned (going to the driver) or a pointer to data (either going to the driver, coming back from the driver, or both).

ioctl in kernel-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

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

#define SUCCESS 0#define DEVICE_NAME "char_dev“#define BUF_LEN 80

...

struct file_operations Fops = {.read = device_read,.write = device_write,.ioctl = device_ioctl,.open = device_open,.release = device_release, /* a.k.a. close */

};

...

int init_module(){int ret_val;ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);if (ret_val < 0) {

printk(KERN_ALERT "%s failed with %d\n“,"Sorry, registering the character device ", ret_val); return ret_val;

}return 0;

}

ioctl in kernel-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

int device_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)

{int i;char *temp;char ch;

switch (ioctl_num) {

case IOCTL_SET_MSG:

temp = (char *)ioctl_param;

get_user(ch, temp);for (i = 0; ch && i < BUF_LEN; i++, temp++)

get_user(ch, temp);

device_write(file, (char *)ioctl_param, i, 0);break;

case IOCTL_GET_MSG:

i = device_read(file, (char *)ioctl_param, 99, 0);

put_user('\0', (char *)ioctl_param + i);break;

case IOCTL_GET_NTH_BYTE:

return Message[ioctl_param];break;

}

return SUCCESS;}

ioctl in user-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

#include "chardev.h“#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>...

ioctl_set_msg(int file_desc, char *message){

int ret_val;

ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);

if (ret_val < 0) {printf("ioctl_set_msg failed:%d\n", ret_val);exit(-1);

}}

...

main(){int file_desc, ret_val;char *msg = "Message passed by ioctl\n";file_desc = open(DEVICE_FILE_NAME, 0);if (file_desc < 0) {

printf("Can't open device file: %s\n", DEVICE_FILE_NAME);exit(-1);

}ioctl_get_nth_byte(file_desc);ioctl_get_msg(file_desc);ioctl_set_msg(file_desc, msg);close(file_desc);

}

Synchronization in kernel-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ In kernel space:

- Different modules interact one each other

- HW Interrupts can preempt important kernel tasks

‣ Interrupt and timers:

- There are two sources of interrupts in Linux, synchronous and asynchronous- Synchronous interrupts, better known as exceptions, are generated by the CPU control unit

- They can be generated by software special functions (ex. Timers) (SW interrupts)- Asynchronous interrupts (known as interrupts) are generated by HW resources, such as serial module, or HW timers Interrupts

- The address of all the interrupt service routines depends on architecture

Synchronization in kernel-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Interrupt:

- The nature of an asynchronous interrupt is that it happens at any time

- If it happens during a time when the kernel is busy performing an important function, then the kernel must do the following:

• Switch over and execute as much of the interrupt service routine as necessary• Switch back and finish the remainder of the task it was performing before the interrupt occurred• Switch back yet again and finish the remainder of the interrupt service routine

The first half of the interrupt service routine is referred to as the top half, while the second half is referred to as the bottom half

Synchronization in kernel-space

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Timers:

• Easy for device-driver programmers to use• Used mainly for detecting device “lockups”• But could also be used for other purposes• The driver-writer merely needs to:

• define a “customized” timeout-function

• allocate and initialize a kernel-structure

• call standard routines for timer-control

Kernel preemption

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

‣ Kernel preemption is a method used in monolithic kernels, whereby the scheduler is permitted to forcibly perform a context switch on a driver or other part of the kernel during its execution, rather than co-operatively wait for the driver or kernel function to complete its execution and return control of the processor to the scheduler

‣ The main motivation for making a kernel preemptive is to reduce the dispatch latency of the user mode processes

• Delay between the time they become runnable and the time they actually begin running • A race condition can occur when the outcome of a computation depends on how two or more interleaved kernel control paths are nested

Synchronization primitives

Carlo Caione <carlo.caione@unibo.it>MPHS - AA. 2010/2011

Technique Description Scope

Per-CPU variables Duplicate a data structure among CPUs All CPUs

Atomic operation Atomic read-modify-write instruction All

Memory barrier Avoid instruction re-ordering Local CPU

Spin lock Lock with busy wait All

Semaphore Lock with blocking wait (sleep) All

Seqlocks Lock based on access counter All

Local interrupt disabling

Forbid interrupt on a single CPU Local

Local softirq disabling Forbid deferrable function on a single CPU Local

Read-copy-update (RCU)

Lock-free access to shared data through pointers All

top related