Linux Modules and Device Drivers ESP Fall 2014

  • Slides: 31
Download presentation
Linux Modules and Device Drivers (ESP – Fall 2014) Computer Science & Engineering Department

Linux Modules and Device Drivers (ESP – Fall 2014) Computer Science & Engineering Department Arizona State University Tempe, AZ 85287 Dr. Yann-Hang Lee yhlee@asu. edu (480) 727 -7507 Real-time Systems Lab, Computer Science and Engineering, ASU

Software Development Environment q IDE – Eclipse, KDevelop q Linux and GNU tools v

Software Development Environment q IDE – Eclipse, KDevelop q Linux and GNU tools v GCC, GDB, and GUI-based tools v applications in user space v operate device interface in user space (read/write of memorymapped I/Os) v interrupt service routines in kernel space v kernel modules and memory copy between user and kernel space Real-time Systems Lab, Computer Science and Engineering, ASU 1

Development Environment of Linux Host PC workstation gcc crosscompiler GDB debugger Eclipse IDE Target

Development Environment of Linux Host PC workstation gcc crosscompiler GDB debugger Eclipse IDE Target board Applications GDB Server Linux or Windows Board support package Real-time Systems Lab, Computer Science and Engineering, ASU 2

What is “kernel” q The basic component of an operating system v to provide

What is “kernel” q The basic component of an operating system v to provide the lowest-level abstraction layer for the resources (especially processors and I/O devices). v available to application processes through inter-process communication mechanisms and system calls q Kernel space and user space q What are system calls v Which are systems calls – cc, make, ls, cat, grep, read, open, printf, malloc, etc. v How can we set the baud rate of a serial port? Ø Configuration of a hyperterminal Ø stty -F /dev/tty. S 2 ospeed 38400 Ø Ioctl to get and set terminal attributes (defined in struct termios) v The mechanism of making system calls and passing parameters Real-time Systems Lab, Computer Science and Engineering, ASU 3

Kernel Components q Process Management v Process life cycle, Inter Process Communication, I/O v

Kernel Components q Process Management v Process life cycle, Inter Process Communication, I/O v Scheduling (long-term, short-term) q Memory Management v Virtual memory, management, security q File System v File system tree, management, security q Device Control v Almost every system operation maps to a physical device v The code used to do those operations is called Device Driver q Networking v Collect incoming packets and De-Multiplexing them v Deliver outgoing packets Real-time Systems Lab, Computer Science and Engineering, ASU 4

Memory Spaces (1) q The logical address space of a process is divided into

Memory Spaces (1) q The logical address space of a process is divided into two parts v – 0 x 0000 to PAGE_OFFSET-1 can be addressed in either user or kernel mode v – PAGE_OFFSET to 0 xffff can be addressed only in kernel mode v – PAGE_OFFSET is usually 0 xc 0000 q Peripheral devices are controlled by writing and reading their registers. Where are these registers? q I/O Port: request an IO port region and inb (outb) from <asm/io. h> q I/O Memory: v Request a memory region v Devices at physical addresses which have to be mapped to virtual addresses for software to access. Real-time Systems Lab, Computer Science and Engineering, ASU 5

Memory Spaces (2) q Physical memory q Virtual memory (user and kernel space) v

Memory Spaces (2) q Physical memory q Virtual memory (user and kernel space) v Linux ARM -- Linux/Documentation/arm/memory. txt (X 86 virtual memory layout) Real-time Systems Lab, Computer Science and Engineering, ASU 6

Linux Kernel Modules q Modules can be compiled and dynamically linked into kernel address

Linux Kernel Modules q Modules can be compiled and dynamically linked into kernel address space. v Useful for device drivers that need not always be resident until needed. (why? ) v Extend the functionality of the kernel without rebuilding and rebooting the system. q Kernel keeps a symbol table v Symbols accessible to kernel-loadable modules appear in /proc/kallsyms. v EXPORT_SYMBOL(), which exports to any loadable module, or v EXPORT_SYMBOL_GPL(), which exports only to GPL-licensed modules. q Can call any functions exported by the kernel v no library is linked to modules Real-time Systems Lab, Computer Science and Engineering, ASU 7

Kernel Modules q Pieces of code that can be loaded and unloaded into the

Kernel Modules q Pieces of code that can be loaded and unloaded into the kernel. v a module registers itself in order to serve future requests v Is a part of kernel – printf or printk q An example module #include <linux/module. h> // Needed by all modules #include <linux/kernel. h> // Needed for KERN_ALERT #include <linux/init. h> // Needed for the macros static int hello_2_init(void) { printk(KERN_ALERT "Hello, world 2n"); return 0; } static void hello_2_exit(void) { printk(KERN_ALERT "Goodbye, world 2n"); } module_init(hello_2_init); module_exit(hello_2_exit); Real-time Systems Lab, Computer Science and Engineering, ASU 8

Hello. World Kernel Module Example (1) /* Hello World kernel module program */ #include

Hello. World Kernel Module Example (1) /* Hello World kernel module program */ #include <linux/init. h> #include <linux/module. h> #include <linux/time. h> #include <linux/delay. h> static int hello_init(void) { int i; struct timeval cur. Time; // keeps the time since the Epoch struct tm bkd_time; // containing a calendar date and time for (i=0; i<10; i++) { do_gettimeofday(&cur. Time); time_to_tm(cur. Time. tv_sec, 0, &bkd_time); printk(KERN_ALERT "Hello, world. The current time is: %d: %d: %ldn", bkd_time. tm_hour, bkd_time. tm_min, bkd_time. tm_sec, cur. Time. tv_usec); msleep(i*1000); } } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, cruel worldn"); } module_init(hello_init); module_exit(hello_exit); Real-time Systems Lab, Computer Science and Engineering, ASU 9

Hello. World Kernel Module Example (2) # Makefile for Hello World kernel module CC

Hello. World Kernel Module Example (2) # Makefile for Hello World kernel module CC = i 586 -poky-linux-gcc ARCH = x 86 CROSS_COMPILE = i 586 -poky-linux. SROOT=/opt/clanton-full/1. 4. 2/sysroots/i 586 -poky-linux/ obj-m = Hello. Module. o all: make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(SROOT)/usr/src/kernel M=$(PWD) modules ---- copy to the target scp Hello. Module. ko root@10. 218. 101. 25: /home/. . . . ---- install and remove the module insmod Hello. Module. ko rmmod Hello. Module Real-time Systems Lab, Computer Science and Engineering, ASU 10

Linking and Unlinking Modules Real-time Systems Lab, Computer Science and Engineering, ASU 11

Linking and Unlinking Modules Real-time Systems Lab, Computer Science and Engineering, ASU 11

Programs for Linking and Unlinking Modules (1) q insmod v Reads from the name

Programs for Linking and Unlinking Modules (1) q insmod v Reads from the name of the module to be linked v Locates the file containing the module's object code v Computes the size of the memory area needed to store the module v v v code, its name, and the module object Invokes the create_module( ) system call Invokes the query_module( ) system call Using the kernel symbol table, the module symbol tables, and the address returned by the create_module( ) system call, relocates the object code included in the module's file. Allocates a memory area in the User Mode address space and loads with a copy of the module object Invokes the init_module( ) system call, passing to it the address of the User Mode memory area Releases the User Mode memory area and terminates Real-time Systems Lab, Computer Science and Engineering, ASU 12

Programs for Linking and Unlinking Modules (2) q lsmod v reads /proc/modules q rmmod

Programs for Linking and Unlinking Modules (2) q lsmod v reads /proc/modules q rmmod v From reads the name of the module to be unlinked. v Invokes the query_module( ) v Invokes the delete_module( ) system call, with the QM_REFS subcommand several times, to retrieve dependency information on the linked modules. q modprobe v loads a module into the kernel. v check any module dependency and load any other modules that are required – stacking of modules Real-time Systems Lab, Computer Science and Engineering, ASU 13

Module Implementation q The kernel considers only modules that have been loaded into RAM

Module Implementation q The kernel considers only modules that have been loaded into RAM by the insmod program and for each of them allocates memory area containing: v a module object v null terminated string that represents module's name v the code that implements the functions of the module q Building v Linux kbuild v make -C ~/kernel-2. 6 M=`pwd` modules to build modules. ko Ø “M=“ is recognized and kbuild is used Ø ~/kernel-2. 6 is the kernel source directory Ø pwd ? ? Real-time Systems Lab, Computer Science and Engineering, ASU 14

Device Driver Basics q Purpose: v a well defined and consistent interface to handle

Device Driver Basics q Purpose: v a well defined and consistent interface to handle requests for device operations v isolate device-specific code in the drivers q A software interface to hardware devices v resides in kernel or user spaces q Classification Ø character device (terminal) OS specific code I/O class specific code Ø block (disk) -- with buffer cache Ø network device driver Hardware specific code Ø pseudodevice q When to call a device driver Ø configuration, I/O operations, and interrupt I/O adapters Real-time Systems Lab, Computer Science and Engineering, ASU 15

Char and Block Devices q Character Devices v Accessed as a stream of bytes

Char and Block Devices q Character Devices v Accessed as a stream of bytes (like a file) v Typically just data channels or data areas, which allow only sequential access v Char devices are accessed by means of filesystem nodes v Example: /dev/tty 1 and /dev/lp 0 v Driver needs to implement at least the open, close, read, and write system calls q Block Devices v provides access to devices that transfer randomly accessible data in fixed- size blocks v Examples? q Design Challenges v Concurrency, performance, and portability Real-time Systems Lab, Computer Science and Engineering, ASU 16

Char Device q cdev -- the kernel internal structure to represents a character device

Char Device q cdev -- the kernel internal structure to represents a character device file v Defined in <linux/cdev. h> struct cdev { struct kobject kobj; struct module *owner; struct file_operations *ops; struct list_head list; dev_t dev; unsigned int count; }; struct file_operations ldd_fops = {. owner = THIS_MODULE, . llseek = ldd_llseek, . read = ldd_read, . write = ldd_write, . ioctl = ldd_ioctl, . open = ldd_open, . release = ldd_release }; Real-time Systems Lab, Computer Science and Engineering, ASU 17

Driver Interface for Character Devices struct file_operations { // defined in inlcude/linux/fs. h struct

Driver Interface for Character Devices struct file_operations { // defined in inlcude/linux/fs. h 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 *); ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 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 *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ………………… }; Real-time Systems Lab, Computer Science and Engineering, ASU 18

User Program & Kernel Interface Real-time Systems Lab, Computer Science and Engineering, ASU 19

User Program & Kernel Interface Real-time Systems Lab, Computer Science and Engineering, ASU 19

Basic Device Driver Structure 0 1 2 3 File descriptor table Device list (of

Basic Device Driver Structure 0 1 2 3 File descriptor table Device list (of device descriptors) “/tty 0/” 1 “/pty 0/” 1 “/xx 1/” 3 Devicedependent data Driver table (function pointers) q Major number to identify the driver associated with the device q Minor number provides a way for the driver to differentiate multiple devices. q dev_t type in <linux/types. h>: 8 bis for major and 8 bits for minor in kernel 2. 4, 12 bis for major and 20 bits for minor in kernel 2. 6. Real-time Systems Lab, Computer Science and Engineering, ASU 20

Register Char Device (1) static dev_t my. Dev = 0; static char my. Name[]

Register Char Device (1) static dev_t my. Dev = 0; static char my. Name[] = "Test. Device"; static int result = 0; static int hello_init(void) { if((result = alloc_chrdev_region(&my. Dev, 0, 1, my. Name))!= 0){ printk("Unable to allocate device numbern"); return -1; } printk(KERN_ALERT "My major is %d, minor is %dn“, MAJOR(my. Dev), MINOR(my. Dev)); return 0; } static void hello_exit(void) { if(result == 0){ unregister_chrdev_region(my. Dev, 1); } } Real-time Systems Lab, Computer Science and Engineering, ASU 21

Register Char Device (2) q Device numbers registration and release v Manually-assigned registration int

Register Char Device (2) q Device numbers registration and release v Manually-assigned registration int register_chrdev_region( dev_t first, # The beginning device number unsigned int count, # Number of continuous device number char *name # Device name (shown in /proc/devices) ); v Dynamically-allocated registration int alloc_chrdev_region( dev_t *dev, # output-only that holds the first device unsigned int firstminor, # The beginning of first minor number unsigned int count, char *name ); v Release void unregister_chrdev_region( dev_first, # The first device number going to release unsigned int count ); Real-time Systems Lab, Computer Science and Engineering, ASU 22

Device Registration q Allocate and initialize a cdev struct v cdev_alloc or cdev_init v

Device Registration q Allocate and initialize a cdev struct v cdev_alloc or cdev_init v cdev gets initilized with a file_opreations structure q cdev_add to register operatons of your device driver v int cdev_add(struct cdev *dev, dev_t num, unsigned int count) q cdev_del — remove a cdev from the system Real-time Systems Lab, Computer Science and Engineering, ASU 23

A Memory Buffer Driver Module Example q As a module, v __init gmem_init(void) v

A Memory Buffer Driver Module Example q As a module, v __init gmem_init(void) v __exit gmem_exit(void) q In gmem_init, create and register a character device with file operations v open, release, read, and write v device file is then created in file system q User program can use device name as a file and invoke file operations on the device q inode cdev gmem_dev (a super-class of cdev containging device related data) file q(Add a code example) Real-time Systems Lab, Computer Science and Engineering, ASU 24

Open System Call q The open system maps onto an operation registered by a

Open System Call q The open system maps onto an operation registered by a driver module v The kernel first does some processing (e. g. , finds the inode struct and file struct for the driver v Invokes the open operation v int open(const char *pathname, int flags); v int open(const char *pathname, int flags, mode_t mode); // return the new file descriptor, v int (*open) (struct inode *, struct file *); Real-time Systems Lab, Computer Science and Engineering, ASU 25

File Struct q The file structure represents an open file. v a kernel structure

File Struct q The file structure represents an open file. v a kernel structure v created by the kernel on open v v v and is passed to any function that operates on the file defined in <linux/fs. h> mode_t f_mode : readable or writable loff_t f_pos: current reading or writing position. struct file_operations *f_op void *private_data struct file { struct list_head f_list; struct dentry *f_dentry; struct vfsmount *f_vfsmnt; struct file_operations *f_op; atomic_t f_count; unsigned int f_flags; mode_t f_mode; loff_t f_pos; unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; struct fown_struct f_owner; unsigned int f_uid, f_gid; int f_error; unsigned long f_version; void *private_data; }; Real-time Systems Lab, Computer Science and Engineering, ASU 26

inode q Each object in the filesystem is represented by an inode v File

inode q Each object in the filesystem is represented by an inode v File type (executable, block special etc), permissions (read, write etc), Owner, Group, File Size, v File access, change and modification time, deletion time Number of links (soft/hard), extended attribute such as append only v Access Control List (ACLs) v Includes dev_t i_rdev; struct block_device *i_bdev; struct char_device *i_cdev; Real-time Systems Lab, Computer Science and Engineering, ASU 27

Memory Access – User and Kernel Spaces q You might receive some pointers that

Memory Access – User and Kernel Spaces q You might receive some pointers that point to user space in your driver function v Do not dereference it directly v Access it via kernel functions (<asm/uaccess. h>): copy_to_user() and copy_from_user() Ø They would check whether the user space pointer is valid unsigned long copy_to_user( void __user *to, const void *from, unsigned long count); unsigned long copy_from_user( void *to, const void __user *from, unsigned long count); Real-time Systems Lab, Computer Science and Engineering, ASU 28

The Read/Write Method Real-time Systems Lab, Computer Science and Engineering, ASU 29

The Read/Write Method Real-time Systems Lab, Computer Science and Engineering, ASU 29

Container_of q If strcut x contains y, can we find the pointer to x

Container_of q If strcut x contains y, can we find the pointer to x given the pointer to y q defined in <linux/kernel. h>: container_of(pointer, container_type, container_field); q takes a pointer to a field of type container_field, within a structure of type container_type, q returns a pointer to the containing structure. Real-time Systems Lab, Computer Science and Engineering, ASU 30