Device Drivers In Linux © Gregory Kesden 2000 15-412 Fall 2000.

Slides:



Advertisements
Similar presentations
Linux device-driver issues
Advertisements

Device Drivers. Linux Device Drivers Linux supports three types of hardware device: character, block and network –character devices: R/W without buffering.
CSNB324 Advanced Operating Systems 6: Device Management
RT_FIFO, Device driver.
Sogang University Advanced Operating Systems (Linux Device Drivers) Advanced Operating Systems (Linux Device Drivers) Sang Gue Oh, Ph.D.
Lecture for Lab 3, Exp1 of EE505 (Developing Device Driver) T.A. Chulmin Kim CoreLab. Mar, 11, 2011 [XenSchedulerPaper_Hotcloud-commits] r21 - /
Devices and Drivers (Chapter 7) Khattab Alhabashi UNIX System Administration.
The Linux Kernel: Memory Management
Using VMX within Linux We explore the feasibility of executing ROM-BIOS code within the Linux x86_64 kernel.
Chapter 7 Process Environment Chien-Chung Shen CIS, UD
6/10/2015C++ for Java Programmers1 Pointers and References Timothy Budd.
Interrupts What is an interrupt? What does an interrupt do to the “flow of control” Interrupts used to overlap computation & I/O – Examples would be console.
Outline  Examine some of the H/W supplied with a typical PC and consider the software required to control it.  Introduce Commkit, a software tool that.
11/13/01CS-550 Presentation - Overview of Microsoft disk operating system. 1 An Overview of Microsoft Disk Operating System.
63 UQC152H3 Advanced OS Writing a Device Driver. 64 The SCULL Device Driver Simple Character Utility for Loading Localities 6 devices types –Scull-03.
Introduction to Kernel
Home: Phones OFF Please Unix Kernel Parminder Singh Kang Home:
Computer System Laboratory
I/O Tanenbaum, ch. 5 p. 329 – 427 Silberschatz, ch. 13 p
M. Muztaba Fuad Advanced Operating System Project Device Drivers.
POSIX: Files Introduction to Operating Systems: Discussion 1 Read Solaris System Interface Guide: Ch. 5.1 Basic File I/O.
Loadable Kernel Modules Dzintars Lepešs The University of Latvia.
I/O Systems ◦ Operating Systems ◦ CS550. Note:  Based on Operating Systems Concepts by Silberschatz, Galvin, and Gagne  Strongly recommended to read.
Operating System Program 5 I/O System DMA Device Driver.
Bolin Hsu CS6900 Independent study Bolin Hsu
System Calls 1.
CS 6560 Operating System Design Lecture 13 Finish File Systems Block I/O Layer.
CSCC69: Operating Systems Assignment 3 Review. Assignment Review Implement the file-related system calls – open, close, dup2 – read, write, lseek – chdir,
Real-time Systems Lab, Computer Science and Engineering, ASU Linux Input Systems (ESP – Fall 2014) Computer Science & Engineering Department Arizona State.
COMP 3438 – Part I - Lecture 4 Introduction to Device Drivers Dr. Zili Shao Department of Computing The Hong Kong Polytechnic Univ.
FINAL MPX DELIVERABLE Due when you schedule your interview and presentation.
1-1 Embedded Network Interface (ENI) API Concepts Shared RAM vs. FIFO modes ENI API’s.
Operating Systems Lecture 7 OS Potpourri Adapted from Operating Systems Lecture Notes, Copyright 1997 Martin C. Rinard. Zhiqing Liu School of Software.
Kernel Modules. Kernel Module Pieces of code that can be loaded and unloaded into the kernel upon demand. Compiled as an independent program With appropriate.
More on UART Interrupts; System Calls Reference on Interrupt Identification Register(IIR) slide 17 of
UNIX Files File organization and a few primitives.
LAB 12: Timer and Interrupt Chung-Ta King National Tsing Hua University CS 4101 Introduction to Embedded Systems.
Lab 13 Department of Computer Science and Information Engineering National Taiwan University Lab13 – Interrupt + Timer 2014/12/23 1 /16.
Sogang University Advanced Operating Systems (Enhanced Device Driver Operations) Advanced Operating Systems (Enhanced Device Driver Operations) Sang Gue.
C Functions Three major differences between C and Java functions: –Functions are stand-alone entities, not part of objects they can be defined in a file.
Files & File system. A Possible File System Layout Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved
CE Operating Systems Lecture 2 Low level hardware support for operating systems.
1 Computer Systems II Introduction to Processes. 2 First Two Major Computer System Evolution Steps Led to the idea of multiprogramming (multiple concurrent.
Linux Device Driver 2009/04/08. Reference Book Another Reference Book Embedded Linux Primer: A Practical, Real-World Approach By Christopher Hallinan.
Interfacing Device Drivers with the Kernel
CSC414 “Introduction to UNIX/ Linux” Lecture 2. Schedule 1. Introduction to Unix/ Linux 2. Kernel Structure and Device Drivers. 3. System and Storage.
How to write a MSGQ Transport (MQT) Overview Nov 29, 2005 Todd Mullanix.
CE Operating Systems Lecture 2 Low level hardware support for operating systems.
CSNB334 Advanced Operating Systems 6. Device Management Lecturer: Asma Shakil.
4P13 Week 12 Talking Points Device Drivers 1.Auto-configuration and initialization routines 2.Routines for servicing I/O requests (the top half)
CSCC69: Operating Systems Tutorial 10. Hints on testing Assignment 3 How to test tlb replacement algorithms? – Write a program that creates an array larger.
COMP 3438 – Part I - Lecture 5 Character Device Drivers
Device Driver Concepts Digital UNIX Internals II Device Driver Concepts Chapter 13.
ICOM Noack Linux I/O structure Device special files Device switch tables and fops How the kernel finds a device Parts of a device driver or module.
MINIX Presented by: Clinton Morse, Joseph Paetz, Theresa Sullivan, and Angela Volk.
Ch 6. Interrupts and Interrupt Handlers. Overview (1) A primary responsibility of the kernel is managing the hardware connected to the machine  The kernel.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edit9on Lecture 3 Chapter 1: Introduction Provided & Updated by Sameer Akram.
Lecture 7 Interrupt ,Trap and System Call
Real Numbers Device driver process within the operating system that interacts with I/O controller logical record 1 logical record 2 logical record 3.
Chapter 7 Process Environment Chien-Chung Shen CIS/UD
Introduction to Kernel
Linux Kernel Development - Robert Love
Chapter 11: File System Implementation
Protection of System Resources
CS 3305 System Calls Lecture 7.
Linux Kernel Driver.
Want to play a game? – Linux Kernel Modules
Pointers and References
Computer System Laboratory
Loadable Kernel Modules
Presentation transcript:

Device Drivers In Linux © Gregory Kesden Fall 2000

Device Types Block devices Random access devices (buffering) For example a file system can only be mounted on a block device, because it requires random access. For example, disks are commonly implemented as block devices. Character devices Sequential access (no buffering). Examples might include printers, scanners, sound boards, &c. The same device may have both block and character oriented interfaces (In other UNIX this would actually require separate drivers. A block device driver and a raw device driver.)

Major and Minor Numbers Major number Each device driver is identified by a unique major number. This number is assigned by the Linux Device Registrar (A human – currently This number is the index into an array that contains the information about the driver (the Minor number This uniquely identifies a particular instance of a device. For example, a system may have multiple IDE hard disks each would have a major number of 3, but a different minor number. mknod /dev/name type major minor Tin UNIX, the interface to devices is via the file system. To create a file representing a device, you use mknod and supply the filename and the device’s type (c for character or b for block) and the device’s major and minor number.

The file_operation structure The file operation structure for a device contains pointers to all of the functions for a device. This is what maps the functions in the generic interface into the specific device’s behaviors.. The mappings are maintained in two arrays: static struct device_struct chrdevs[MAX_CHRDEV] static struct device_struct blkdevs[MAX_BLKDEV] The same device can have both character and block interfaces, so it can have mappings in both arrays.

struct file_operations { loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *); int (*fasync) (int, struct file *, int); int (*check_media_change) (kdev_t dev); int (*revalidate) (kdev_t dev); int (*lock) (struct file *, int, struct file_lock *); };

Setup Function - Overview Introduction Setup functions are not necessary. They allow parameters to a driver to be supplied as boot parameters. They should do nothing more than set global variable – the init() function should do all of the real work. Boot parameters When the kernel boots, it may be initialized with parameters destined for a particular device driver. The paramaters passed to the kernel generally take the form: name=param1,parms2,parm3,…,parmn name=parm1,…parmn parseoption() The parseoption() function is called by the kernel to break the command line into separate strings for each driver: name=parm1,parm2,parm3,… checksetup() This function checks the name field of the parameter to find the matching device driver. If it finds a match, it invokes the specified setup function, passing it the parameters as an integer array. It was once a simple function using a static mapping table – it now uses ELF black magic.

Setup Function -- Example static int __init BusLogic_Setup(char *str) { int ints[3]; (void)get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] != 0) { BusLogic_Error("BusLogic: Obsolete Command Line Entry” "Format Ignored\n", NULL); return 0; } if (str == NULL || *str == '\0') return 0; return BusLogic_ParseDriverOptions(str); } /* This is black magic – checksetup() plays in ELF land! */ __setup("BusLogic=", BusLogic_Setup);

The Init() Function The call to the init() function for a driver is hard-coded into the kernel’s bootstrap code. For example, a SCSI device’s intialization function could be called within scsi_dev_init() in drivers/scsi/scsi.c The init() function should ensure that the device exists. The init function must register the driver’s character and/or block interface. This installs the mapping between the generic API and the driver’s specific behaviors. Recall that these mappings are maintained in arrays and were defined by the driver’s file_operation struct. There is an array of these file_operation structs for character (chrdevs[devices and another for block devices –register_chrdev (major_num, “name”, &file_operation_struct) –register_blkdev (major_num, “name”, *file_operation_struct) It can also perform any other initialization.

Unregister() If necessary device drivers can be unregistered. Therse functions NULL out the entries in the chrdevs[] or blkdevs[] arrays. unregister_chrdev (major_number, “name”); unregister_blkdev (major_number, “name”);

Nomenclature In order to avoid name-space collisions with other definitions, functions or global variables, &c, anything that could pollute the namespace everything should begin with a unique and descriptive prefix. For example, consider the nomenclature used in the Vino Video System: –struct vino_device { … } –static struct vino_device vino[2]; –static void vino_setup(struct vino_device *v) { … } –static int vino_init(void) { … } –static void vino_dma_stop(void) { … } –&c

Polling Mode Polling Mode is supported in Linux – although it is favorable for almost nothing. An older version of Linux (2.0) contained code for a polled mode parallel port driver. It’s main work loop looked like this: do { status = LP_S(minor); count++; /* count is used as a time-out */ if (need_resched) schedule(); } while(!LP_READY(minor,status) && count < LP_CHAR(minor));

Interrupt Mode Linux supports three different flavors of Interrupt Mode I/O: “Slow” IRQs These are the most common type of ISR. Slow interrupts can be interrupted by other interrupts. Before returning to an interrupted ISR(), the ret_from_sys_call() is used – this macro restores the registers, &c to their original values. “Fast” IRQs This mode is used for very brief ISRs. When “fast” mode is used, other interrupts are not allowed. This reduces the overhead required to invoke the ISR, because less state needs to be preserved. Interrupt Sharing Interrupt sharing is the ability to have one IRQ service multiple devices. Basically, a chain of ISRs, each for a different device, is constructed for the IRQ. Each ISR is executed if the interrupt occurs. The ISRs should be able to interrogate the device to determine if, in fact, there is any work for them to do.

Installing an Interrupt Handler An ISR must be installed before it can be used. This is done using the request_irq() call: int request_irq (unsigned int irq, void (*handler)(int, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id) irq is the IRQ for which the handler is installed handler is the handler function irq_flags might include SA_INTERRUPT to specify fast IRQs or SA_SHIRQ to specify a shared IRQ (or an ORed combination). devname should be the name of the device driver (used in /proc for accounting) dev_id is meaningless to the kernel, but is passed unchanged to the handler

Interrupt Handler Shell static void dev_interrupt (int irq, void *dev_id, struct pt_regs *regs) { /* irq contains the number of the IRQ that caused this handler to be invoked – the same handler can be installed for multiple IRQs. */ /*dev_id contains whatever it was passed into request_irq() when this handler was installed. */ /* pt_regs contains the registers from the processes that was interrupted by this handler */ }

Bottom Half Support Linux recognizes the fact that interrupt handlers should only take care of actions that require immediate attention, so it has explicit support for routines that compose the bottom half of a device driver. Up to 32 bottom half routines can be defined. Bottom half routines are atomic with respect to each other. Bottom halve routines that have work to do are said to be active. After every slow interrupt completes, if there are no interrupted or pending slow interrupts, the list of bottom halves is scanned and active bottom halves are executed. (This is done as part of ret_from_syscall) In a typical case, the ISR will take care of time-critical business and activate a bottom half to finish the processing.

Using Bottom Halves Three data structures are used to implement bottom halfs –bh_base – A 32 entry array. It holds the pointers to the bottom half routines –bh_mask – a 32 bit mask. A bit set in this mask indicates that a the corresponding bottom half is initialized and usable. –bh_active – a 32 bit mask. A bit set in this mask indicates that the corresponding bottom half is active (has work to do). void init_bh (int nr, void (*routine)(void)) This installs routine as the handler for bottom half number nr. void disable_bh (int nr) This disables a bottom half. It turns off the mask bit for the installed bottom half nr. void enable_bh (int nr) This sets the mask bit for the installed bottom half nr. void mark_bh (int nr) This “actives” a bottom half, indicating that there is work for it to do.