Application Development for Embedded Systems
description
Transcript of Application Development for Embedded Systems
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
pre-processor
compiler
assembler
linker
source code
header files
assembler .s
object code
executable file
compiler
binutils
library
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 <[email protected]>MPHS - AA. 2010/2011
C Code GCC
BSP / Kernel
Newlib
Hardware
atoi(), strtol(), bzero(), strcat(), ...
_exit(),close(),fork(),kill(),...
Newlib
Carlo Caione <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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 <[email protected]>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