SlideShare uma empresa Scribd logo
1 de 35
Baixar para ler offline
Linux Device Drivers
a brief introduction
Alexandre Moreno
Seenergy Corp.
alexandre@seenergy.com.tw
February 2012
cba
1 Introduction
2 The kernel—user space API
3 Hello, world
4 Deferred work
5 Platform devices
6 Example: UART driver
7 Miscellaneous Topics
Introducton
Device drivers are the abstraction layer between software concepts
and hardware circuitry:
They provide a standard interface to perihperals, hiding the
details of how devices work
Almost every system operation eventually maps to a physical
device
The OS kernel embeds device drivers for every peripheral
device present in the system
Unix motto also applies here, i.e. provide mechanism, not
policy
have seven times the bug rate of other kernel code1
1: pdos. csail. mit. edu/ 6. 097/ readings/ osbugs. pdf
Classes of devices
Typically device drivers are classified as follows:
Character devices: simplest type. They are accessed as a
stream of bytes, sequentially
Block devices: I/O operations transfer whole blocks (e.g. 512
bytes), can be random-accessed and host a filesystem.
Network interfaces: packet delivery, uses network subsystem
API; do not use device nodes in order to be accessed
But this taxonomy is not universal, e.g. an USB device might
appear in the kernel as char device (serial port), block device (USB
flash drive) or network device (USB Ethernet interface)
Linux kernel—user-space API
Linux provides different mechanisms for communicating between
user and kernel space:
System calls: functions1 which are useful for many application
(about 380)
ioctl syscall: catch-all for non-standard file operations
Virtual file systems: procfs, sysfs, configfs, debugfs
sysctl: configure kernel parameters at runtime
Netlink: sockets-based interface e.g. iptables/netfilter
Upcall: allows kernel modules start a program in userspace
1: syscalls aren’t usually invoked directly from userspace, but rather thru C library wrappers. This is because a
system call requires, among other things trapping to kernel mode, set errno variable etc. which is arch specific.
From userspace it’s just a C library function.
Common practise
From the previous list of interfaces, device drivers usually:
implement file operations, like open, read, write, poll, mmap
etc. which implements the system calls with the same name
might use ioctls for other device-specific operations, e.g.
query capabilities, tuning, etc.
use the pseudo file system /proc to expose internal data
structures
Everything is a file
The UNIX philosophy is quoted as ”everything is a file”. That
what really means is that everything is a stream of bytes—in the
file system namespace.
Sockets and pipes are the exception, lacking a file name. A more
precise definition would be ”everything is a file descriptor”
The advantage of this approach is that you can use the same
(file-based) interfaces on different things.
http: // yarchive. net/ comp/ linux/ everything_ is_ file. html
File operations
file operations (simplified)
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
};
Character devices are accessed as files. Drivers should provide
implementations of some of these functions. Thus one opens a
device, reads/writes from/to it, and closes it, using the same file
I/O semantics used for regular files.
include/linux/fs.h
Loadable Modules
Linux has the ability to extend the kernel functionality at
runtime using modules
Device drivers can also be added to the kernel in this fashion
(benefits are a smaller kernel, on demand loading gives you a
better footprint and no kernel recompilation to add new
modules)
You can use the module-init-tools package, which contains a
set of programs for loading, inserting and removing kernel
modules.
Example:
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
If CONFIG_FOO is neither y nor m, then the file will not be compiled
nor linked.
hello, world (1)
helloworld.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, worldn");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, worldn");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
ifneq (£(KERNELRELEASE),)
obj-m := helloworld.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
hello, world (2)
And this is a simple session showing how to bring it to life
$ ls
helloworld.c helloworld.ko helloworld.mod.c helloworld.mod.o
helloworld.o Makefile modules.order Module.symvers
$ sudo insmod ./helloworld.ko
$ dmesg | tail -1
[151235.953044] Hello, world
$ cat /proc/modules | grep helloworld
helloworld 680 0 - Live 0xf8252000
$ modinfo helloworld.ko
filename: helloworld.ko
license: Dual BSD/GPL
srcversion: 736D100661E927970863868
depends:
vermagic: 2.6.32-39-generic SMP mod_unload modversions 586
$ sudo rmmod helloworld
$ dmesg | tail -1
[151277.360643] Goodbye, world
Driver entry and exit points
model init
module_init(hello_init);
The driver’s init() routine specified in module init() will be called
during boot (when statically linked in) or when the module is
dynamically loaded. The driver passes its structure of operations to
the device’s subsystem when it registers itself during its init().
model exit
module_exit(hello_exit);
module exit will wrap the driver clean-up code with
cleanup module when used with rmmod when the driver is a
module. If the driver is built-in, module exit has no effect.
Access the Linux kernel using the /proc filesystem
prochello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
static struct proc_dir_entry *proc_ent;
static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data)
{
char *hello_str = "Hello, world!n";
int len = strlen(hello_str); /* Don’t include the null byte. */
strcpy(buffer, hello_str);
*eof = 1;
return len;
}
static int simpl_init(void)
{
proc_ent = create_proc_entry("simpl", 0, NULL);
if(!proc_ent){
remove_proc_entry("simpl", NULL/*&proc_root*/ );
return -ENOMEM;
}
proc_ent->read_proc = proc_read;
return 0;
}
static void simpl_exit(void)
{
remove_proc_entry("simpl", NULL/*&proc_root*/ );
}
module_init(simpl_init);
module_exit(simpl_exit);
Interrupts
At any given time the system is either in user or kernel (aka
supervisor) mode. When the kernel runs, it is either in:
process context: on behalf of the user, e.g. thru a system call,
or
atomic context: or interrupt context, servicing a device, e.g.
the system timer.
Thus, a device driver is either in process or interrupt context.
These contexts are very different regarding concurrency and latency
of operations, and that’s the reason we need deferred work APIs.
Interrupt handlers
Run asynchronously, and are registered using request irq(), which
asks the kernel to call them when that IRQ line raises and
interrupt. If that request fails, you would need a fallback routine.
Once you finish processing, you can either return:
not handled: you check your registers and happens that your
device neither reads or writes anything, so means some other
device was using that line
handled: you’re done or
deferred: Deferred means that after the handler has
performed a possible time-critical part of the handling, some
other work, is done later, by so-called bottom-halves
Bottom halves
Deferring work idea: split time-sensitive work from
non-time-sensitive one. For that purpose, the kernel provides:
timers
workqueues
kernel threads
One particular useful analogy from OO design, is the
Reactor/Proactor pattern.
Memory-mapped peripherals
Embedded systems, particularly those based on systems-on-a-chip,
usually lack of a standard peripheral bus—e.g. USB, with
discovery capabilities, for most integrated devices. Thus these
devices need to be explicitly instantiated by kernel code. The
Platform device API is provided for that purpose. At boot time,
the bootloader passes the machine type it is booting in a register.
https: // www. kernel. org/ doc/ Documentation/ driver-model/ platform. txt
Device trees
The previous approach, means the kernel needs the entire
description of the hardware. A new approach is to use a device
tree, a textual description of the hardware configuration. The
bootloader loads too images, the kernel (e.g. uImage) and the
device tree, and then passes the address of the table in a register
to the kernel, instead of the machine type.
http: // lwn. net/ Articles/ 448502/
The TTY layer
syscall interface
character driver
TTY Core
TTY driver
TTY driver
serial_core
serial driver
Line
discipline
char
driver
The Linux console (1)
In embedded Linux, it’s common to use a serial port as console
Hardware
Terminal
Physical
line
UART
UART
driver
Line
discipline
TTY
driver
User
process
User
process
User
process
Kernel
Software
Hardware
Terminal
Physical
line
UART
UART
driver
Line
discipline
TTY
driver
User
process
User
process
User
process
Kernel
Software
The serial ports are named ttyS0, ttyS1, etc. (COM1, COM2, etc.
in DOS/Windows), and accessed thru /dev/ttyS0, etc.
The Linux console (2)
In your desktop Linux, you have virtual consoles (/dev/tty1, etc.).
Normally in the 7th virtual console start the X Window System
UART
driver
Line
discipline
TTY
driver
User
process
User
process
User
process
Software
Terminal
Emulator
Line
discipline
TTY
driver
User
process
User
process
User
process
Kernel
Software
Keyboard
Display
Hardware
VGA
Driver
Keyboard
Driver
The other 6 VT are text consoles.
From your desktop, when using a terminal emulator such as xterm
or a network login service such as ssh a pseudo-terminal device
(dev/pts0 etc.) is used.
Check it out in your Linux desktop machine
$ ps aux | grep tty
root 834 0.0 0.0 1788 468 tty4 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty4
root 837 0.0 0.0 1788 472 tty5 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty5
root 845 0.0 0.0 1788 472 tty2 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty2
root 846 0.0 0.0 1788 472 tty3 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty3
root 849 0.0 0.0 1788 472 tty6 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty6
root 970 1.8 6.8 90380 69812 tty7 Ss+ Mar27 42:51 /usr/bin/X :0
-nr -verbose -auth /var/run/gdm/auth-for-gdm-e3KUoh/database -nolisten tcp vt7
root 1145 0.0 0.1 3160 1796 tty1 Ss Mar27 0:02 /bin/login --
alex 28851 1.0 0.3 6224 3632 tty1 S 17:56 0:05 -bash
alex 28880 2.0 0.1 2712 1080 tty1 R+ 18:05 0:00 ps aux
alex 28881 1.0 0.0 3324 836 tty1 S+ 18:05 0:00 grep --color=auto tty
The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by
an exec of the program getty
Check it out in your Linux desktop machine
$ ps aux | grep tty
root 834 0.0 0.0 1788 468 tty4 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty4
root 837 0.0 0.0 1788 472 tty5 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty5
root 845 0.0 0.0 1788 472 tty2 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty2
root 846 0.0 0.0 1788 472 tty3 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty3
root 849 0.0 0.0 1788 472 tty6 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty6
root 970 1.8 6.8 90380 69812 tty7 Ss+ Mar27 42:51 /usr/bin/X :0
-nr -verbose -auth /var/run/gdm/auth-for-gdm-e3KUoh/database -nolisten tcp vt7
root 1145 0.0 0.1 3160 1796 tty1 Ss Mar27 0:02 /bin/login --
alex 28851 1.0 0.3 6224 3632 tty1 S 17:56 0:05 -bash
alex 28880 2.0 0.1 2712 1080 tty1 R+ 18:05 0:00 ps aux
alex 28881 1.0 0.0 3324 836 tty1 S+ 18:05 0:00 grep --color=auto tty
$ stty -a < /dev/tty1
speed 38400 baud; rows 30; columns 80; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by
an exec of the program getty
Data structures
The generic UART driver is defined by the following structures:
A data structure representing a driver : uart driver
Single instance for each driver
uart register driver() and uart unregister driver()
A data structure representing a port : uart port
One instance for each port (several per driver are possible)
uart add one port() and uart remove one port()
interface between serial core and the hardware specific driver:
uart ops
Linked from uart port through the ops field
https: // www. kernel. org/ doc/ Documentation/ serial/ driver
uart ops
struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
unsigned int (*get_mctrl)(struct uart_port *);
void (*stop_tx)(struct uart_port *);
/* ... */
};
uart driver
struct uart_driver {
struct module *owner;
const char *driver_name;
const char *dev_name;
int major;
int minor;
int nr;
struct console *cons;
};
uart port
struct uart_port {
spinlock_t lock; /* port lock */
unsigned long iobase; /* in/out[bwl] */
unsigned char __iomem *membase; /* read/write[bwl] */
int (*handle_irq)(struct uart_port *);
unsigned int irq; /* irq number */
unsigned long irqflags; /* irq flags */
unsigned int uartclk; /* base uart clock */
unsigned int fifosize; /* tx fifo size */
unsigned char x_char; /* xon/xoff char */
unsigned char regshift; /* reg offset shift */
unsigned char iotype; /* io access style */
/* ... */
const struct uart_ops *ops;
resource_size_t mapbase; /* for ioremap */
struct device *dev; /* parent device */
/* ... */
};
linux/drivers/char/serial core.h
altera uart ops
static struct uart_ops altera_uart_ops = {
.tx_empty = altera_uart_tx_empty,
.get_mctrl = altera_uart_get_mctrl,
.set_mctrl = altera_uart_set_mctrl,
.start_tx = altera_uart_start_tx,
.stop_tx = altera_uart_stop_tx,
/* ... */
};
extended uart port
struct altera_uart {
struct uart_port port;
struct timer_list tmr;
unsigned int sigs;
unsigned short imr;
};
altera uart driver
static struct uart_driver altera_uart_driver = {
.owner = THIS_MODULE,
.driver_name = DRV_NAME,
.dev_name = "ttyAL",
.major = SERIAL_ALTERA_MAJOR,
.minor = SERIAL_ALTERA_MINOR,
.nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS,
.cons = ALTERA_UART_CONSOLE,
};
static struct altera_uart altera_uart_ports[MAXPORTS];
linux/drivers/tty/serial/altera uart.c
init routines
register the driver
static int __init altera_uart_init(void)
{
int rc;
rc = uart_register_driver(&altera_uart_driver);
if (rc)
return rc;
rc = platform_driver_register(&altera_uart_platform_driver);
if (rc) {
uart_unregister_driver(&altera_uart_driver);
return rc;
}
return 0;
}
unregister the driver
static void __exit altera_uart_exit(void)
{
platform_driver_unregister(&altera_uart_platform_driver);
uart_unregister_driver(&altera_uart_driver);
}
module_init(altera_uart_init);
module_exit(altera_uart_exit);
the init macro tells the compiler to put that function in the .init section (also init data and exit)
I/O Memory Allocation and Mapping
allocating and mapping the UART registers
static int __devinit altera_uart_probe(struct platform_device *pdev)
{
struct uart_port *port;
struct resource *res_mem;
int i = pdev->id;
/* ... */
port = &altera_uart_ports[i].port;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem)
port->mapbase = res_mem->start;
else if (platp->mapbase)
port->mapbase = platp->mapbase;
/* ... */
port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
/* ... */
port->ops = &altera_uart_ops;
/* ... */
uart_add_one_port(&altera_uart_driver, port);
/* ... */
return 0;
}
emap is needed because we need the kernel provides page tables to access it.
There is also a pairing remove() method, that undoes what probe () did (remove the port, etc.). This methods are
part of the struct platform driver (include/linux/platform device.h)
The dev init macro says that this is not a hot-pluggable device
read/write operations in the device registers
read a memory-mapped register
static u32 altera_uart_readl(struct uart_port *port, int reg)
{
return readl(port->membase + (reg << port->regshift));
}
write a memory-mapped register
static void altera_uart_writel(struct uart_port *port, u32 dat, int reg)
{
writel(dat, port->membase + (reg << port->regshift));
}
read/write operations in the device registers
read a 32-bit value
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) __raw_readl((c))); __r; })
#define __raw_readl(a) ( __chk_io_ptr(a), *(volatile unsigned int __force *)(a))
Check out how the read macros
introduce a memory barrier (avoid reordering of instructions),
takes care of endianness
use the volatile keyword to prevent the compiler from register
caching.
I/O regions should already configured as noncached and
nonbuffered memory by the kernel in init code, to avoid accessing
stale data from cache.
Interrupt handling
rx/tx interrupt service routine
static irqreturn_t altera_uart_interrupt(int irq, void *data)
{
struct uart_port *port = data;
unsigned int isr;
isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
spin_lock(&port->lock);
if (isr & ALTERA_UART_STATUS_RRDY_MSK)
altera_uart_rx_chars(pp);
if (isr & ALTERA_UART_STATUS_TRDY_MSK)
altera_uart_tx_chars(pp);
spin_unlock(&port->lock);
return IRQ_RETVAL(isr);
}
attach UART with interrupt vector
static int altera_uart_startup(struct uart_port *port)
{
int ret;
ret = request_irq(port->irq, altera_uart_interrupt, 0, DRV_NAME, port);
spin_lock_irqsave(&port->lock, flags);
/* Enable RX interrupts now */
pp->imr = ALTERA_UART_CONTROL_RRDY_MSK;
writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG);
spin_unlock_irqrestore(&port->lock, flags);
return 0;
}
GCC hacks in the Linux kernel
inline, deprecated, used and const ... functions
Statement expressions (i.e. the ({ and }) constructs).
Declaring attributes of a function / variable / type
( attribute )
typeof
Zero length arrays
Macro varargs
Arithmetic on void pointers
Non-Constant initializers (automatic variables)
Assembler Instructions (not outside arch/ and include/asm/)
asm ()
Function names as strings ( func ).
builtin constant p()
Object-oriented design tecniques used in the kernel (1)
Inheritance from a base class by embedding it as a first member.
extended uart port
struct altera_uart {
struct uart_port port;
struct timer_list tmr;
unsigned int sigs;
unsigned short imr;
};
The C standard requires that no padding is introduced by the
compiler at the start of a struct.
Object-oriented design tecniques used in the kernel (2)
Example showing the use of the container of().
container of macro
static unsigned int altera_uart_get_mctrl(struct uart_port *port)
{
struct altera_uart *pp = container_of(port, struct altera_uart, port);
unsigned int sigs;
sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0;
sigs |= (pp->sigs & TIOCM_RTS);
return sigs;
}
Access to implementation-specific data, like a derived class.
Object-oriented design tecniques used in the kernel (3)
Method Dispatch, using virtual function tables
virtual method table
struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *);
void (*stop_tx)(struct uart_port *);
void (*start_tx)(struct uart_port *);
void (*send_xchar)(struct uart_port *, char ch);
void (*stop_rx)(struct uart_port *);
/* ... */
};
structure which contains only function pointers where the first
argument of each is a pointer to some other structure (the object
type) which itself contains a pointer to this vtable

Mais conteúdo relacionado

Mais procurados

Linux device driver
Linux device driverLinux device driver
Linux device driverchatsiri
 
Linux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionLinux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionGene Chang
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Adrian Huang
 
Linux Initialization Process (1)
Linux Initialization Process (1)Linux Initialization Process (1)
Linux Initialization Process (1)shimosawa
 
eMMC Embedded Multimedia Card overview
eMMC Embedded Multimedia Card overvieweMMC Embedded Multimedia Card overview
eMMC Embedded Multimedia Card overviewVijayGESYS
 
Building Mini Embedded Linux System for X86 Arch
Building Mini Embedded Linux System for X86 ArchBuilding Mini Embedded Linux System for X86 Arch
Building Mini Embedded Linux System for X86 ArchSherif Mousa
 
U Boot or Universal Bootloader
U Boot or Universal BootloaderU Boot or Universal Bootloader
U Boot or Universal BootloaderSatpal Parmar
 
Linux Memory Management
Linux Memory ManagementLinux Memory Management
Linux Memory ManagementNi Zo-Ma
 
Embedded Linux BSP Training (Intro)
Embedded Linux BSP Training (Intro)Embedded Linux BSP Training (Intro)
Embedded Linux BSP Training (Intro)RuggedBoardGroup
 
Part 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module ProgrammingPart 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module ProgrammingTushar B Kute
 
Jagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchJagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchlinuxlab_conf
 

Mais procurados (20)

Basic Linux Internals
Basic Linux InternalsBasic Linux Internals
Basic Linux Internals
 
Linux device driver
Linux device driverLinux device driver
Linux device driver
 
Linux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionLinux MMAP & Ioremap introduction
Linux MMAP & Ioremap introduction
 
Linux Programming
Linux ProgrammingLinux Programming
Linux Programming
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...
 
Linux kernel modules
Linux kernel modulesLinux kernel modules
Linux kernel modules
 
A practical guide to buildroot
A practical guide to buildrootA practical guide to buildroot
A practical guide to buildroot
 
Linux Initialization Process (1)
Linux Initialization Process (1)Linux Initialization Process (1)
Linux Initialization Process (1)
 
Embedded Linux Kernel - Build your custom kernel
Embedded Linux Kernel - Build your custom kernelEmbedded Linux Kernel - Build your custom kernel
Embedded Linux Kernel - Build your custom kernel
 
Embedded Linux on ARM
Embedded Linux on ARMEmbedded Linux on ARM
Embedded Linux on ARM
 
Linux device drivers
Linux device drivers Linux device drivers
Linux device drivers
 
eMMC Embedded Multimedia Card overview
eMMC Embedded Multimedia Card overvieweMMC Embedded Multimedia Card overview
eMMC Embedded Multimedia Card overview
 
Building Mini Embedded Linux System for X86 Arch
Building Mini Embedded Linux System for X86 ArchBuilding Mini Embedded Linux System for X86 Arch
Building Mini Embedded Linux System for X86 Arch
 
Embedded Android : System Development - Part II (Linux device drivers)
Embedded Android : System Development - Part II (Linux device drivers)Embedded Android : System Development - Part II (Linux device drivers)
Embedded Android : System Development - Part II (Linux device drivers)
 
U Boot or Universal Bootloader
U Boot or Universal BootloaderU Boot or Universal Bootloader
U Boot or Universal Bootloader
 
Character drivers
Character driversCharacter drivers
Character drivers
 
Linux Memory Management
Linux Memory ManagementLinux Memory Management
Linux Memory Management
 
Embedded Linux BSP Training (Intro)
Embedded Linux BSP Training (Intro)Embedded Linux BSP Training (Intro)
Embedded Linux BSP Training (Intro)
 
Part 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module ProgrammingPart 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module Programming
 
Jagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchJagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratch
 

Destaque

Kernel Recipes 2016 -
Kernel Recipes 2016 - Kernel Recipes 2016 -
Kernel Recipes 2016 - Anne Nicolas
 
NLLGG Raspberry Pi Themadag 23-11-2013
NLLGG Raspberry Pi Themadag 23-11-2013NLLGG Raspberry Pi Themadag 23-11-2013
NLLGG Raspberry Pi Themadag 23-11-2013Marcel Hergaarden
 
Linuxdd[1]
Linuxdd[1]Linuxdd[1]
Linuxdd[1]mcganesh
 
Gnubs-pres-foss-cdac-sem
Gnubs-pres-foss-cdac-semGnubs-pres-foss-cdac-sem
Gnubs-pres-foss-cdac-semSagun Baijal
 
Linux kernel code
Linux kernel codeLinux kernel code
Linux kernel codeGanesh Naik
 
Device drivers Introduction
Device drivers IntroductionDevice drivers Introduction
Device drivers Introductionvijay selva
 
Device Drivers in Linux
Device Drivers in LinuxDevice Drivers in Linux
Device Drivers in LinuxShreyas MM
 
Breaking into Open Source and Linux: A USB 3.0 Success Story
Breaking into Open Source and Linux: A USB 3.0 Success StoryBreaking into Open Source and Linux: A USB 3.0 Success Story
Breaking into Open Source and Linux: A USB 3.0 Success StorySage Sharp
 
Raspberry Pi - Lecture 6 Working on Raspberry Pi
Raspberry Pi - Lecture 6 Working on Raspberry PiRaspberry Pi - Lecture 6 Working on Raspberry Pi
Raspberry Pi - Lecture 6 Working on Raspberry PiMohamed Abdallah
 
Linux Kernel Introduction
Linux Kernel IntroductionLinux Kernel Introduction
Linux Kernel IntroductionSage Sharp
 
Performance comparison between Linux Containers and Virtual Machines
Performance comparison between Linux Containers and Virtual MachinesPerformance comparison between Linux Containers and Virtual Machines
Performance comparison between Linux Containers and Virtual MachinesSoheila Dehghanzadeh
 
Introduction to Raspberry Pi and GPIO
Introduction to Raspberry Pi and GPIOIntroduction to Raspberry Pi and GPIO
Introduction to Raspberry Pi and GPIOKris Findlay
 
Device tree support on arm linux
Device tree support on arm linuxDevice tree support on arm linux
Device tree support on arm linuxChih-Min Chao
 
Containers and Cloud: From LXC to Docker to Kubernetes
Containers and Cloud: From LXC to Docker to KubernetesContainers and Cloud: From LXC to Docker to Kubernetes
Containers and Cloud: From LXC to Docker to KubernetesShreyas MM
 

Destaque (20)

Raspberry Pi
Raspberry PiRaspberry Pi
Raspberry Pi
 
Kernel Recipes 2016 -
Kernel Recipes 2016 - Kernel Recipes 2016 -
Kernel Recipes 2016 -
 
Driver_linux
Driver_linuxDriver_linux
Driver_linux
 
Rtos 2
Rtos 2Rtos 2
Rtos 2
 
Rtos
RtosRtos
Rtos
 
NLLGG Raspberry Pi Themadag 23-11-2013
NLLGG Raspberry Pi Themadag 23-11-2013NLLGG Raspberry Pi Themadag 23-11-2013
NLLGG Raspberry Pi Themadag 23-11-2013
 
Linuxdd[1]
Linuxdd[1]Linuxdd[1]
Linuxdd[1]
 
Gnubs-pres-foss-cdac-sem
Gnubs-pres-foss-cdac-semGnubs-pres-foss-cdac-sem
Gnubs-pres-foss-cdac-sem
 
Linux kernel code
Linux kernel codeLinux kernel code
Linux kernel code
 
Device drivers Introduction
Device drivers IntroductionDevice drivers Introduction
Device drivers Introduction
 
Device Drivers in Linux
Device Drivers in LinuxDevice Drivers in Linux
Device Drivers in Linux
 
Breaking into Open Source and Linux: A USB 3.0 Success Story
Breaking into Open Source and Linux: A USB 3.0 Success StoryBreaking into Open Source and Linux: A USB 3.0 Success Story
Breaking into Open Source and Linux: A USB 3.0 Success Story
 
Raspberry Pi - Lecture 6 Working on Raspberry Pi
Raspberry Pi - Lecture 6 Working on Raspberry PiRaspberry Pi - Lecture 6 Working on Raspberry Pi
Raspberry Pi - Lecture 6 Working on Raspberry Pi
 
Linux Device Driver’s
Linux Device Driver’sLinux Device Driver’s
Linux Device Driver’s
 
Linux Kernel Introduction
Linux Kernel IntroductionLinux Kernel Introduction
Linux Kernel Introduction
 
Containers in the Cloud
Containers in the CloudContainers in the Cloud
Containers in the Cloud
 
Performance comparison between Linux Containers and Virtual Machines
Performance comparison between Linux Containers and Virtual MachinesPerformance comparison between Linux Containers and Virtual Machines
Performance comparison between Linux Containers and Virtual Machines
 
Introduction to Raspberry Pi and GPIO
Introduction to Raspberry Pi and GPIOIntroduction to Raspberry Pi and GPIO
Introduction to Raspberry Pi and GPIO
 
Device tree support on arm linux
Device tree support on arm linuxDevice tree support on arm linux
Device tree support on arm linux
 
Containers and Cloud: From LXC to Docker to Kubernetes
Containers and Cloud: From LXC to Docker to KubernetesContainers and Cloud: From LXC to Docker to Kubernetes
Containers and Cloud: From LXC to Docker to Kubernetes
 

Semelhante a Linux Device Driver Fundamentals

Linux kernel driver tutorial vorlesung
Linux kernel driver tutorial vorlesungLinux kernel driver tutorial vorlesung
Linux kernel driver tutorial vorlesungdns -
 
Linux Device Driver,LDD,
Linux Device Driver,LDD,Linux Device Driver,LDD,
Linux Device Driver,LDD,Rahul Batra
 
linux device driver
linux device driverlinux device driver
linux device driverRahul Batra
 
Driver Programming Report
Driver Programming ReportDriver Programming Report
Driver Programming ReportShivek Khurana
 
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B KuteUnit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B KuteTushar B Kute
 
Ppt project process migration
Ppt project process migrationPpt project process migration
Ppt project process migrationjaya380
 
Writing Character driver (loadable module) in linux
Writing Character driver (loadable module) in linuxWriting Character driver (loadable module) in linux
Writing Character driver (loadable module) in linuxRajKumar Rampelli
 
Linux Kernel Development
Linux Kernel DevelopmentLinux Kernel Development
Linux Kernel DevelopmentPriyank Kapadia
 
REAL TIME OPERATING SYSTEM PART 2
REAL TIME OPERATING SYSTEM PART 2REAL TIME OPERATING SYSTEM PART 2
REAL TIME OPERATING SYSTEM PART 2Embeddedcraft Craft
 
Know thyubuntu
Know thyubuntuKnow thyubuntu
Know thyubuntuchkmao
 
M.c.a. (sem ii) operating systems
M.c.a. (sem   ii) operating systemsM.c.a. (sem   ii) operating systems
M.c.a. (sem ii) operating systemsTushar Rajput
 
Operating System Concepts Presentation
Operating System Concepts PresentationOperating System Concepts Presentation
Operating System Concepts PresentationNitish Jadia
 
Unix Shell and System Boot Process
Unix Shell and System Boot ProcessUnix Shell and System Boot Process
Unix Shell and System Boot ProcessArvind Krishnaa
 
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdf
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdfunixlinux - kernelexplain yield in user spaceexplain yield in k.pdf
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdfPRATIKSINHA7304
 

Semelhante a Linux Device Driver Fundamentals (20)

Linux kernel driver tutorial vorlesung
Linux kernel driver tutorial vorlesungLinux kernel driver tutorial vorlesung
Linux kernel driver tutorial vorlesung
 
Device drivers tsp
Device drivers tspDevice drivers tsp
Device drivers tsp
 
Linux Device Driver,LDD,
Linux Device Driver,LDD,Linux Device Driver,LDD,
Linux Device Driver,LDD,
 
linux device driver
linux device driverlinux device driver
linux device driver
 
Device Drivers
Device DriversDevice Drivers
Device Drivers
 
Driver Programming Report
Driver Programming ReportDriver Programming Report
Driver Programming Report
 
Studienarb linux kernel-dev
Studienarb linux kernel-devStudienarb linux kernel-dev
Studienarb linux kernel-dev
 
Walking around linux kernel
Walking around linux kernelWalking around linux kernel
Walking around linux kernel
 
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B KuteUnit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
 
Ppt project process migration
Ppt project process migrationPpt project process migration
Ppt project process migration
 
Writing Character driver (loadable module) in linux
Writing Character driver (loadable module) in linuxWriting Character driver (loadable module) in linux
Writing Character driver (loadable module) in linux
 
Linux Kernel Development
Linux Kernel DevelopmentLinux Kernel Development
Linux Kernel Development
 
REAL TIME OPERATING SYSTEM PART 2
REAL TIME OPERATING SYSTEM PART 2REAL TIME OPERATING SYSTEM PART 2
REAL TIME OPERATING SYSTEM PART 2
 
Know thyubuntu
Know thyubuntuKnow thyubuntu
Know thyubuntu
 
M.c.a. (sem ii) operating systems
M.c.a. (sem   ii) operating systemsM.c.a. (sem   ii) operating systems
M.c.a. (sem ii) operating systems
 
LINUX Device Drivers
LINUX Device DriversLINUX Device Drivers
LINUX Device Drivers
 
Operating System Concepts Presentation
Operating System Concepts PresentationOperating System Concepts Presentation
Operating System Concepts Presentation
 
Unix Shell and System Boot Process
Unix Shell and System Boot ProcessUnix Shell and System Boot Process
Unix Shell and System Boot Process
 
Linux filesystemhierarchy
Linux filesystemhierarchyLinux filesystemhierarchy
Linux filesystemhierarchy
 
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdf
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdfunixlinux - kernelexplain yield in user spaceexplain yield in k.pdf
unixlinux - kernelexplain yield in user spaceexplain yield in k.pdf
 

Último

2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Último (20)

2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

Linux Device Driver Fundamentals

  • 1. Linux Device Drivers a brief introduction Alexandre Moreno Seenergy Corp. alexandre@seenergy.com.tw February 2012 cba
  • 2. 1 Introduction 2 The kernel—user space API 3 Hello, world 4 Deferred work 5 Platform devices 6 Example: UART driver 7 Miscellaneous Topics
  • 3. Introducton Device drivers are the abstraction layer between software concepts and hardware circuitry: They provide a standard interface to perihperals, hiding the details of how devices work Almost every system operation eventually maps to a physical device The OS kernel embeds device drivers for every peripheral device present in the system Unix motto also applies here, i.e. provide mechanism, not policy have seven times the bug rate of other kernel code1 1: pdos. csail. mit. edu/ 6. 097/ readings/ osbugs. pdf
  • 4. Classes of devices Typically device drivers are classified as follows: Character devices: simplest type. They are accessed as a stream of bytes, sequentially Block devices: I/O operations transfer whole blocks (e.g. 512 bytes), can be random-accessed and host a filesystem. Network interfaces: packet delivery, uses network subsystem API; do not use device nodes in order to be accessed But this taxonomy is not universal, e.g. an USB device might appear in the kernel as char device (serial port), block device (USB flash drive) or network device (USB Ethernet interface)
  • 5. Linux kernel—user-space API Linux provides different mechanisms for communicating between user and kernel space: System calls: functions1 which are useful for many application (about 380) ioctl syscall: catch-all for non-standard file operations Virtual file systems: procfs, sysfs, configfs, debugfs sysctl: configure kernel parameters at runtime Netlink: sockets-based interface e.g. iptables/netfilter Upcall: allows kernel modules start a program in userspace 1: syscalls aren’t usually invoked directly from userspace, but rather thru C library wrappers. This is because a system call requires, among other things trapping to kernel mode, set errno variable etc. which is arch specific. From userspace it’s just a C library function.
  • 6. Common practise From the previous list of interfaces, device drivers usually: implement file operations, like open, read, write, poll, mmap etc. which implements the system calls with the same name might use ioctls for other device-specific operations, e.g. query capabilities, tuning, etc. use the pseudo file system /proc to expose internal data structures
  • 7. Everything is a file The UNIX philosophy is quoted as ”everything is a file”. That what really means is that everything is a stream of bytes—in the file system namespace. Sockets and pipes are the exception, lacking a file name. A more precise definition would be ”everything is a file descriptor” The advantage of this approach is that you can use the same (file-based) interfaces on different things. http: // yarchive. net/ comp/ linux/ everything_ is_ file. html
  • 8. File operations file operations (simplified) struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); }; Character devices are accessed as files. Drivers should provide implementations of some of these functions. Thus one opens a device, reads/writes from/to it, and closes it, using the same file I/O semantics used for regular files. include/linux/fs.h
  • 9. Loadable Modules Linux has the ability to extend the kernel functionality at runtime using modules Device drivers can also be added to the kernel in this fashion (benefits are a smaller kernel, on demand loading gives you a better footprint and no kernel recompilation to add new modules) You can use the module-init-tools package, which contains a set of programs for loading, inserting and removing kernel modules. Example: obj-$(CONFIG_FOO) += foo.o $(CONFIG_FOO) evaluates to either y (for built-in) or m (for module). If CONFIG_FOO is neither y nor m, then the file will not be compiled nor linked.
  • 10. hello, world (1) helloworld.c #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello, worldn"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, worldn"); } module_init(hello_init); module_exit(hello_exit); Makefile ifneq (£(KERNELRELEASE),) obj-m := helloworld.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif
  • 11. hello, world (2) And this is a simple session showing how to bring it to life $ ls helloworld.c helloworld.ko helloworld.mod.c helloworld.mod.o helloworld.o Makefile modules.order Module.symvers $ sudo insmod ./helloworld.ko $ dmesg | tail -1 [151235.953044] Hello, world $ cat /proc/modules | grep helloworld helloworld 680 0 - Live 0xf8252000 $ modinfo helloworld.ko filename: helloworld.ko license: Dual BSD/GPL srcversion: 736D100661E927970863868 depends: vermagic: 2.6.32-39-generic SMP mod_unload modversions 586 $ sudo rmmod helloworld $ dmesg | tail -1 [151277.360643] Goodbye, world
  • 12. Driver entry and exit points model init module_init(hello_init); The driver’s init() routine specified in module init() will be called during boot (when statically linked in) or when the module is dynamically loaded. The driver passes its structure of operations to the device’s subsystem when it registers itself during its init(). model exit module_exit(hello_exit); module exit will wrap the driver clean-up code with cleanup module when used with rmmod when the driver is a module. If the driver is built-in, module exit has no effect.
  • 13. Access the Linux kernel using the /proc filesystem prochello.c #include <linux/init.h> #include <linux/module.h> #include <linux/proc_fs.h> /* Necessary because we use the proc fs */ static struct proc_dir_entry *proc_ent; static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data) { char *hello_str = "Hello, world!n"; int len = strlen(hello_str); /* Don’t include the null byte. */ strcpy(buffer, hello_str); *eof = 1; return len; } static int simpl_init(void) { proc_ent = create_proc_entry("simpl", 0, NULL); if(!proc_ent){ remove_proc_entry("simpl", NULL/*&proc_root*/ ); return -ENOMEM; } proc_ent->read_proc = proc_read; return 0; } static void simpl_exit(void) { remove_proc_entry("simpl", NULL/*&proc_root*/ ); } module_init(simpl_init); module_exit(simpl_exit);
  • 14. Interrupts At any given time the system is either in user or kernel (aka supervisor) mode. When the kernel runs, it is either in: process context: on behalf of the user, e.g. thru a system call, or atomic context: or interrupt context, servicing a device, e.g. the system timer. Thus, a device driver is either in process or interrupt context. These contexts are very different regarding concurrency and latency of operations, and that’s the reason we need deferred work APIs.
  • 15. Interrupt handlers Run asynchronously, and are registered using request irq(), which asks the kernel to call them when that IRQ line raises and interrupt. If that request fails, you would need a fallback routine. Once you finish processing, you can either return: not handled: you check your registers and happens that your device neither reads or writes anything, so means some other device was using that line handled: you’re done or deferred: Deferred means that after the handler has performed a possible time-critical part of the handling, some other work, is done later, by so-called bottom-halves
  • 16. Bottom halves Deferring work idea: split time-sensitive work from non-time-sensitive one. For that purpose, the kernel provides: timers workqueues kernel threads One particular useful analogy from OO design, is the Reactor/Proactor pattern.
  • 17. Memory-mapped peripherals Embedded systems, particularly those based on systems-on-a-chip, usually lack of a standard peripheral bus—e.g. USB, with discovery capabilities, for most integrated devices. Thus these devices need to be explicitly instantiated by kernel code. The Platform device API is provided for that purpose. At boot time, the bootloader passes the machine type it is booting in a register. https: // www. kernel. org/ doc/ Documentation/ driver-model/ platform. txt
  • 18. Device trees The previous approach, means the kernel needs the entire description of the hardware. A new approach is to use a device tree, a textual description of the hardware configuration. The bootloader loads too images, the kernel (e.g. uImage) and the device tree, and then passes the address of the table in a register to the kernel, instead of the machine type. http: // lwn. net/ Articles/ 448502/
  • 19. The TTY layer syscall interface character driver TTY Core TTY driver TTY driver serial_core serial driver Line discipline char driver
  • 20. The Linux console (1) In embedded Linux, it’s common to use a serial port as console Hardware Terminal Physical line UART UART driver Line discipline TTY driver User process User process User process Kernel Software Hardware Terminal Physical line UART UART driver Line discipline TTY driver User process User process User process Kernel Software The serial ports are named ttyS0, ttyS1, etc. (COM1, COM2, etc. in DOS/Windows), and accessed thru /dev/ttyS0, etc.
  • 21. The Linux console (2) In your desktop Linux, you have virtual consoles (/dev/tty1, etc.). Normally in the 7th virtual console start the X Window System UART driver Line discipline TTY driver User process User process User process Software Terminal Emulator Line discipline TTY driver User process User process User process Kernel Software Keyboard Display Hardware VGA Driver Keyboard Driver The other 6 VT are text consoles. From your desktop, when using a terminal emulator such as xterm or a network login service such as ssh a pseudo-terminal device (dev/pts0 etc.) is used.
  • 22. Check it out in your Linux desktop machine $ ps aux | grep tty root 834 0.0 0.0 1788 468 tty4 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty4 root 837 0.0 0.0 1788 472 tty5 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty5 root 845 0.0 0.0 1788 472 tty2 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty2 root 846 0.0 0.0 1788 472 tty3 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty3 root 849 0.0 0.0 1788 472 tty6 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty6 root 970 1.8 6.8 90380 69812 tty7 Ss+ Mar27 42:51 /usr/bin/X :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-e3KUoh/database -nolisten tcp vt7 root 1145 0.0 0.1 3160 1796 tty1 Ss Mar27 0:02 /bin/login -- alex 28851 1.0 0.3 6224 3632 tty1 S 17:56 0:05 -bash alex 28880 2.0 0.1 2712 1080 tty1 R+ 18:05 0:00 ps aux alex 28881 1.0 0.0 3324 836 tty1 S+ 18:05 0:00 grep --color=auto tty The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by an exec of the program getty
  • 23. Check it out in your Linux desktop machine $ ps aux | grep tty root 834 0.0 0.0 1788 468 tty4 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty4 root 837 0.0 0.0 1788 472 tty5 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty5 root 845 0.0 0.0 1788 472 tty2 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty2 root 846 0.0 0.0 1788 472 tty3 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty3 root 849 0.0 0.0 1788 472 tty6 Ss+ Mar27 0:00 /sbin/getty -8 38400 tty6 root 970 1.8 6.8 90380 69812 tty7 Ss+ Mar27 42:51 /usr/bin/X :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-e3KUoh/database -nolisten tcp vt7 root 1145 0.0 0.1 3160 1796 tty1 Ss Mar27 0:02 /bin/login -- alex 28851 1.0 0.3 6224 3632 tty1 S 17:56 0:05 -bash alex 28880 2.0 0.1 2712 1080 tty1 R+ 18:05 0:00 ps aux alex 28881 1.0 0.0 3324 836 tty1 S+ 18:05 0:00 grep --color=auto tty $ stty -a < /dev/tty1 speed 38400 baud; rows 30; columns 80; line = 0; intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff -iuclc -ixany -imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by an exec of the program getty
  • 24. Data structures The generic UART driver is defined by the following structures: A data structure representing a driver : uart driver Single instance for each driver uart register driver() and uart unregister driver() A data structure representing a port : uart port One instance for each port (several per driver are possible) uart add one port() and uart remove one port() interface between serial core and the hardware specific driver: uart ops Linked from uart port through the ops field https: // www. kernel. org/ doc/ Documentation/ serial/ driver
  • 25. uart ops struct uart_ops { unsigned int (*tx_empty)(struct uart_port *); void (*set_mctrl)(struct uart_port *, unsigned int mctrl); unsigned int (*get_mctrl)(struct uart_port *); void (*stop_tx)(struct uart_port *); /* ... */ }; uart driver struct uart_driver { struct module *owner; const char *driver_name; const char *dev_name; int major; int minor; int nr; struct console *cons; }; uart port struct uart_port { spinlock_t lock; /* port lock */ unsigned long iobase; /* in/out[bwl] */ unsigned char __iomem *membase; /* read/write[bwl] */ int (*handle_irq)(struct uart_port *); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ unsigned int fifosize; /* tx fifo size */ unsigned char x_char; /* xon/xoff char */ unsigned char regshift; /* reg offset shift */ unsigned char iotype; /* io access style */ /* ... */ const struct uart_ops *ops; resource_size_t mapbase; /* for ioremap */ struct device *dev; /* parent device */ /* ... */ }; linux/drivers/char/serial core.h
  • 26. altera uart ops static struct uart_ops altera_uart_ops = { .tx_empty = altera_uart_tx_empty, .get_mctrl = altera_uart_get_mctrl, .set_mctrl = altera_uart_set_mctrl, .start_tx = altera_uart_start_tx, .stop_tx = altera_uart_stop_tx, /* ... */ }; extended uart port struct altera_uart { struct uart_port port; struct timer_list tmr; unsigned int sigs; unsigned short imr; }; altera uart driver static struct uart_driver altera_uart_driver = { .owner = THIS_MODULE, .driver_name = DRV_NAME, .dev_name = "ttyAL", .major = SERIAL_ALTERA_MAJOR, .minor = SERIAL_ALTERA_MINOR, .nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS, .cons = ALTERA_UART_CONSOLE, }; static struct altera_uart altera_uart_ports[MAXPORTS]; linux/drivers/tty/serial/altera uart.c
  • 27. init routines register the driver static int __init altera_uart_init(void) { int rc; rc = uart_register_driver(&altera_uart_driver); if (rc) return rc; rc = platform_driver_register(&altera_uart_platform_driver); if (rc) { uart_unregister_driver(&altera_uart_driver); return rc; } return 0; } unregister the driver static void __exit altera_uart_exit(void) { platform_driver_unregister(&altera_uart_platform_driver); uart_unregister_driver(&altera_uart_driver); } module_init(altera_uart_init); module_exit(altera_uart_exit); the init macro tells the compiler to put that function in the .init section (also init data and exit)
  • 28. I/O Memory Allocation and Mapping allocating and mapping the UART registers static int __devinit altera_uart_probe(struct platform_device *pdev) { struct uart_port *port; struct resource *res_mem; int i = pdev->id; /* ... */ port = &altera_uart_ports[i].port; res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; else if (platp->mapbase) port->mapbase = platp->mapbase; /* ... */ port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); /* ... */ port->ops = &altera_uart_ops; /* ... */ uart_add_one_port(&altera_uart_driver, port); /* ... */ return 0; } emap is needed because we need the kernel provides page tables to access it. There is also a pairing remove() method, that undoes what probe () did (remove the port, etc.). This methods are part of the struct platform driver (include/linux/platform device.h) The dev init macro says that this is not a hot-pluggable device
  • 29. read/write operations in the device registers read a memory-mapped register static u32 altera_uart_readl(struct uart_port *port, int reg) { return readl(port->membase + (reg << port->regshift)); } write a memory-mapped register static void altera_uart_writel(struct uart_port *port, u32 dat, int reg) { writel(dat, port->membase + (reg << port->regshift)); }
  • 30. read/write operations in the device registers read a 32-bit value #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) __raw_readl((c))); __r; }) #define __raw_readl(a) ( __chk_io_ptr(a), *(volatile unsigned int __force *)(a)) Check out how the read macros introduce a memory barrier (avoid reordering of instructions), takes care of endianness use the volatile keyword to prevent the compiler from register caching. I/O regions should already configured as noncached and nonbuffered memory by the kernel in init code, to avoid accessing stale data from cache.
  • 31. Interrupt handling rx/tx interrupt service routine static irqreturn_t altera_uart_interrupt(int irq, void *data) { struct uart_port *port = data; unsigned int isr; isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; spin_lock(&port->lock); if (isr & ALTERA_UART_STATUS_RRDY_MSK) altera_uart_rx_chars(pp); if (isr & ALTERA_UART_STATUS_TRDY_MSK) altera_uart_tx_chars(pp); spin_unlock(&port->lock); return IRQ_RETVAL(isr); } attach UART with interrupt vector static int altera_uart_startup(struct uart_port *port) { int ret; ret = request_irq(port->irq, altera_uart_interrupt, 0, DRV_NAME, port); spin_lock_irqsave(&port->lock, flags); /* Enable RX interrupts now */ pp->imr = ALTERA_UART_CONTROL_RRDY_MSK; writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); spin_unlock_irqrestore(&port->lock, flags); return 0; }
  • 32. GCC hacks in the Linux kernel inline, deprecated, used and const ... functions Statement expressions (i.e. the ({ and }) constructs). Declaring attributes of a function / variable / type ( attribute ) typeof Zero length arrays Macro varargs Arithmetic on void pointers Non-Constant initializers (automatic variables) Assembler Instructions (not outside arch/ and include/asm/) asm () Function names as strings ( func ). builtin constant p()
  • 33. Object-oriented design tecniques used in the kernel (1) Inheritance from a base class by embedding it as a first member. extended uart port struct altera_uart { struct uart_port port; struct timer_list tmr; unsigned int sigs; unsigned short imr; }; The C standard requires that no padding is introduced by the compiler at the start of a struct.
  • 34. Object-oriented design tecniques used in the kernel (2) Example showing the use of the container of(). container of macro static unsigned int altera_uart_get_mctrl(struct uart_port *port) { struct altera_uart *pp = container_of(port, struct altera_uart, port); unsigned int sigs; sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; sigs |= (pp->sigs & TIOCM_RTS); return sigs; } Access to implementation-specific data, like a derived class.
  • 35. Object-oriented design tecniques used in the kernel (3) Method Dispatch, using virtual function tables virtual method table struct uart_ops { unsigned int (*tx_empty)(struct uart_port *); void (*stop_tx)(struct uart_port *); void (*start_tx)(struct uart_port *); void (*send_xchar)(struct uart_port *, char ch); void (*stop_rx)(struct uart_port *); /* ... */ }; structure which contains only function pointers where the first argument of each is a pointer to some other structure (the object type) which itself contains a pointer to this vtable