SlideShare a Scribd company logo
Team Emertxe
Linux Device Drivers
An Introduction
Introduction
Familiarity Check
●
Good C & Programming Skills
●
Linux & the Filesytem
– Root, User Space Headers & Libraries
●
Files
– Regular, Special, Device
●
Toolchain
– gcc & friends
●
Make & Makefiles
●
Kernel Sources (Location & Building)
The Flow
● Introduction
– Linux kernel Ecosystem
– Kernel Souce Organization
– Command set and Files
– Writing the first driver (Module)
● Character Drivers
– Device files
– Device access from user space (End to End flow)
– Registering the driver
– File Operations and registration
– Data transfer between User and Kernel space
– ioctl
● Memory & Hardware
● Time & Timings
● USB Drivers
● Interrupt Handling
● Block Drivers
● PCI Drivers
● Debugging
The Flow...
●
Introduction
– Linux kernel Ecosystem
– Kernel Souce Organization
– Command set and Files
– Writing the first driver (Module)
●
Character Drivers
– Device files
– Device access from user space (End to End flow)
● Memory & Hardware
● Time & Timings
● USB Drivers
●
Interrupt Handling
●
Block Drivers
● PCI Drivers
● Debugging
Hands-On
●
Your First Driver
●
Character Drivers
– Null Driver
– Memory Driver
– UART Driver for Customized Hardware
●
USB Drivers
– USB Device Hot-plug-ability
– USB to Serial Hardware Driver
●
Filesystem Modules
– VFS Interfacing
– “Pseudo” File System with Memory Files
Linux Driver
Ecosystem
bash gvim X Server gcc firefox
`
`
Process
Management
ssh
Memory
Management
File Systems
Device
Control
Networking
Architecture
Dependent
Code
Character
Devices
Memory
Manager
Filesystem
Types
Block
Devices
Network
Subsystem
IF
Devices
Concurrency
MultiTasking
Virtual
Memory
Files & Dirs:
The VFS
Ttys &
Device Access
Connectivity
CPU Memory
Disks &
CDs
Consoles,
etc
Network
Interfaces
Kernel Source
Organization
Kernel Source
include
net
drivers
block
fs
mm
kernel
arch
char mtd/ide net pci ...usbserial
asm-<arch>linux
arm powerpc sparc x86 ...
The Locations &
Config Files
● Kernel Source Path: /usr/src/linux
● Std Modules Path:
– /lib/modules/<kernel version>/kernel/...
●
Module Configuration: /etc/modprobe.conf
● Kernel Windows:
– /proc
– /sys
●
System Logs: /var/log/messages
The Commands
●
lsmod
●
insmod
●
modprobe
●
rmmod
●
dmesg
●
objdump
●
nm
●
cat /proc/<file>
The Kernel's C
●
ctor & dtor
– init_module, cleanup_module
●
printf
– printk
● Libraries
– <kernel src>/kernel
●
Headers
– <kernel src>/include
The Init Code
static int __init mfd_init(void)
{
printk(KERN_INFO "mfd registered");
...
return 0;
}
module_init(mfd_init);
The Cleanup Code
static void __exit mfd_exit(void)
{
printk(KERN_INFO "mfd deregistered");
...
}
module_exit(mfd_exit);
Usage of printk
● <linux/kernel.h>
● Constant String for Log Level
– KERN_EMERG "<0>" /* system is unusable */
– KERN_ALERT "<1>" /* action must be taken immediately */
– KERN_CRIT "<2>" /* critical conditions */
– KERN_ERR "<3>" /* error conditions */
– KERN_WARNING "<4>" /* warning conditions */
– KERN_NOTICE "<5>" /* normal but significant condition */
– KERN_INFO "<6>" /* informational */
– KERN_DEBUG "<7>" /* debug-level messages */
●
printf like arguments
The Other Basics &
Ornaments
● Headers
– #include <linux/module.h>
– #include <linux/version.h>
– #include <linux/kernel.h>
● MODULE_LICENSE("GPL");
● MODULE_AUTHOR("Emertxe");
● MODULE_DESCRIPTION("First Device Driver");
Building the Module
● Our driver needs
– The Kernel Headers for Prototypes
– The Kernel Functions for Functionality
– The Kernel Build System & the Makefile for Building
●
Two options
– Building under Kernel Source Tree
● Put our driver under drivers folder
● Edit Kconfig(s) & Makefile to include our driver
– Create our own Makefile to do the right invocation
Our Makefile
ifneq (${KERNELRELEASE},)
obj-m += <module>.o
else
KERNEL_SOURCE := <kernel source directory path>
PWD := $(shell pwd)
default:
$(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) clean
endif
Try Out your First Driver
Character Drivers
Major &
Minor Number
● ls -l /dev
● Major is to Driver; Minor is to Device
● <linux/types.h> (>= 2.6.0)
– dev_t: 12 & 20 bits for major & minor
● <linux/kdev_t.h>
– MAJOR(dev_t dev)
– MINOR(dev_t dev)
– MKDEV(int major, int minor)
Registering &
Unregistering
●
Registering the Device Driver
– int register_chrdev_region(dev_t first, unsigned int count,
char *name);
– int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,
unsigned int cnt, char *name);
●
Unregistering the Device Driver
– void unregister_chrdev_region(dev_t first, unsigned int
count);
●
Header: <linux/fs.h>
The file operations
● #include <linux/fs.h>
● struct file_operations
– int (*open)(struct inode *, struct file *);
– int (*release)(struct inode *, struct file *);
– ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
– ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
– struct module owner = THIS_MODULE; / linux/module.h> */
– loff_t (*llseek)(struct file *, loff_t, int);
– int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
User level I/O
●
int open(const char *path, int oflag, ... )
●
int close(int fd);
●
ssize_t write(int fd, const void *buf, size_t nbyte)
●
ssize_t read(int fd, void *buf, size_t nbyte)
●
int ioctl(int d, int request, ...)
– The ioctl() function manipulates the underlying device
parameters of special files.
– The argument d must be an open file descriptor.
– The second argument is a device-dependent request code.
The file &
inode structures
●
struct file
– mode_t f_mode
– loff_t f_pos
– unsigned int f_flags
– struct file_operations *f_op
– void * private_data
●
struct inode
– unsigned int iminor(struct inode *);
– unsigned int imajor(struct inode *);
Registering the
file operations
●
#include <linux/cdev.h>
●
1st way initialization:
– struct cdev *my_cdev = cdev_alloc();
– my_cdev->owner = THIS_MODULE;
– my_cdev->ops = &my_fops;
● 2nd way initialization:
– struct cdev my_cdev;
– cdev_init(&my_cdev, &my_fops);
– my_cdev.owner = THIS_MODULE;
– my_cdev.ops = &my_fops;
Registering the
file operations...
● The Registration
– int cdev_add(struct cdev *cdev, dev_t num,
unsigned int count);
●
The Unregistration
– void cdev_del(struct cdev *cdev);
Registering/Unregistering
Old Way
● Registering the Device Driver
– int register_chrdev(undigned int major, const char *name,
struct file_operations *fops);
● Unregistering the Device Driver
– int unregister_chrdev(undigned int major, const char
*name);
The read flow
struct file
-------------------------
f_count
f_flags
f_mode
-------------------------
f_pos
-------------------------
...
...
ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t *off)
Buffer
(in the driver)
Buffer
(in the
application
or libc)
Kernel Space (Non-swappable) User Space (Swappable)
copy_to_user
The /dev/null
read & write
ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t
*off)
{
...
return read_cnt;
}
ssize_t my_write(struct file *f, char __user *buf, size_t cnt, loff_t
*off)
{
...
return wrote_cnt;
}
The mem device read
ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t
*off)
{
...
if (copy_to_user(buf, from, cnt) != 0)
{
return -EFAULT;
}
...
return read_cnt;
}
The mem device write
ssize_t my_write(struct file *f, char __user *buf, size_t cnt, loff_t
*off)
{
...
if (copy_from_user(to, buf, cnt) != 0)
{
return -EFAULT;
}
...
return wrote_cnt;
}
Dynamic Device Node
& Classes
● Class Operations
– struct class *class_create(struct module *owner, char
*name);
– void class_destroy(struct class *cl);
●
Device into & Out of Class
– struct class_device *device_create(struct class *cl, NULL,
dev_t devnum, NULL, const char *fmt, ...);
– void device_destroy(struct class *cl, dev_t devnum);
The I/O Control API
●
int (*ioctl)(struct inode *, struct file *, unsigned int cmd, unsigned long arg)
●
int (*unlocked_ioctl)(struct file *, unsigned int cmd, unsigned long arg)
●
Command
– <linux/ioctl.h> -> ... -> <asm-generic/ioctl.h>
– Macros
●
_IO, _IOR, _IOW, _IOWR
– Parameters
●
type (Magic character) [15:8]
●
number (index) [7:0]
●
size (param type) [29:16]
The I/O Control API
● Macro Usage
_IO(type, index)
[_IOR | _IOW | _IOWR](type, index,
datatype/size)
Module Parameters
●
<linux/moduleparam.h>
– Macros
● module_param(name, type, perm)
● module_param_array(name, type, num, perm)
● Perm (is a bitmask)
– 0
– S_IRUGO
– S_IWUSR | S_IRUGO
– Loading
● insmod driver.ko name=10
x86 Architecture
A
B
Memory Access
Physical Vs
Virtual Memory
●
The kernel Organizes Physical memory in to pages
– Page size Depends on Arch
● X86-based 4096 bytes
●
On 32-bit X86 system Kernel total Virtual address space
– Total 4GB (pointer size)
– Kernel Configuration Splits 4GB in to
● 3BG Virtual Sp for US
● 1GB Virtual Sp for Kernel
– 128MB KDS
– Virtual Address also called “Logical Address”
Memory Access from
Kernel Space
●
Virtual Address on Physical Address
– #include <linux/gfp.h>
●
unsigned long __get_free_pages(flags, order); etc
●
void free_pages(addr, order); etc
– #include <linux/slab.h>
●
void *kmalloc(size_t size, gfp_t flags);
– GFP_ATOMIC, GFP_KERNEL, GFP_DMA
● void kfree(void *obj);
– #include <linux/vmalloc.h>
● void *vmalloc(unsigned long size);
●
void vfree(void *addr);
Memory Access from
Kernel Space...
●
Virtual Address for Bus/IO Address
– #include <asm/io.h>
● void *ioremap(unsigned long offset, unsigned long size);
● void iounmap(void *addr);
● I/O Memory Access
– #include <asm/io.h>
● unsigned int ioread[8|16|32](void *addr);
● unsigned int iowrite[8|16|32](u[8|16|32] value, void *addr);
●
Barriers
– #include <linux/kernel.h>: void barrier(void);
– #include <asm/system.h>: void [r|w|]mb(void);
Hardware Access
I/O Accesses from
Kernel Space
● I/O Port Access
– #include <asm/io.h>
● unsigned in[b|w|l](unsigned port);
● void out[b|w|l](unsigned [char|short|int] value,
unsigned port);
Hands-On the Hardware

More Related Content

What's hot (20)

ODP
Embedded Android : System Development - Part III
Emertxe Information Technologies Pvt Ltd
 
PDF
Android Things : Building Embedded Devices
Emertxe Information Technologies Pvt Ltd
 
ODP
Q4.11: Porting Android to new Platforms
Linaro
 
PDF
Arm device tree and linux device drivers
Houcheng Lin
 
PPT
"Learning AOSP" - Android Hardware Abstraction Layer (HAL)
Nanik Tolaram
 
PDF
Embedded Linux Kernel - Build your custom kernel
Emertxe Information Technologies Pvt Ltd
 
PDF
Embedded Android : System Development - Part IV (Android System Services)
Emertxe Information Technologies Pvt Ltd
 
PDF
Explore Android Internals
National Cheng Kung University
 
PPT
Learning AOSP - Android Linux Device Driver
Nanik Tolaram
 
PPT
Learning AOSP - Android Booting Process
Nanik Tolaram
 
PDF
Customizing AOSP For Different Embedded Devices And Integration at Applicatio...
ijafrc
 
PDF
Android IPC Mechanism
National Cheng Kung University
 
PDF
Embedded Android Workshop
Opersys inc.
 
PDF
Uboot startup sequence
Houcheng Lin
 
PPT
U boot porting guide for SoC
Macpaul Lin
 
PPTX
Linux Kernel Booting Process (1) - For NLKB
shimosawa
 
PDF
A practical guide to buildroot
Emertxe Information Technologies Pvt Ltd
 
PDF
Android Internals
Opersys inc.
 
PDF
U-Boot - An universal bootloader
Emertxe Information Technologies Pvt Ltd
 
PPTX
U-Boot Porting on New Hardware
RuggedBoardGroup
 
Embedded Android : System Development - Part III
Emertxe Information Technologies Pvt Ltd
 
Android Things : Building Embedded Devices
Emertxe Information Technologies Pvt Ltd
 
Q4.11: Porting Android to new Platforms
Linaro
 
Arm device tree and linux device drivers
Houcheng Lin
 
"Learning AOSP" - Android Hardware Abstraction Layer (HAL)
Nanik Tolaram
 
Embedded Linux Kernel - Build your custom kernel
Emertxe Information Technologies Pvt Ltd
 
Embedded Android : System Development - Part IV (Android System Services)
Emertxe Information Technologies Pvt Ltd
 
Explore Android Internals
National Cheng Kung University
 
Learning AOSP - Android Linux Device Driver
Nanik Tolaram
 
Learning AOSP - Android Booting Process
Nanik Tolaram
 
Customizing AOSP For Different Embedded Devices And Integration at Applicatio...
ijafrc
 
Android IPC Mechanism
National Cheng Kung University
 
Embedded Android Workshop
Opersys inc.
 
Uboot startup sequence
Houcheng Lin
 
U boot porting guide for SoC
Macpaul Lin
 
Linux Kernel Booting Process (1) - For NLKB
shimosawa
 
A practical guide to buildroot
Emertxe Information Technologies Pvt Ltd
 
Android Internals
Opersys inc.
 
U-Boot - An universal bootloader
Emertxe Information Technologies Pvt Ltd
 
U-Boot Porting on New Hardware
RuggedBoardGroup
 

Viewers also liked (20)

PDF
Communication Protocols (UART, SPI,I2C)
Emertxe Information Technologies Pvt Ltd
 
PDF
Linux systems - Getting started with setting up and embedded platform
Emertxe Information Technologies Pvt Ltd
 
PDF
File systems for Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
PDF
Introduction to Embedded Systems
Emertxe Information Technologies Pvt Ltd
 
PDF
Data Structures & Algorithm design using C
Emertxe Information Technologies Pvt Ltd
 
PDF
Embedded C - Optimization techniques
Emertxe Information Technologies Pvt Ltd
 
PDF
Emertxe : Linux training portfolio
Emertxe Information Technologies Pvt Ltd
 
PDF
Interview preparation workshop
Emertxe Information Technologies Pvt Ltd
 
PDF
Linux Internals - Part I
Emertxe Information Technologies Pvt Ltd
 
PDF
BusyBox for Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
PDF
Embedded Linux - Building toolchain
Emertxe Information Technologies Pvt Ltd
 
PDF
Linux Internals - Part III
Emertxe Information Technologies Pvt Ltd
 
PDF
Emertxe : Training portfolio
Emertxe Information Technologies Pvt Ltd
 
PDF
Resume Preparation - Workshop
Emertxe Information Technologies Pvt Ltd
 
PDF
Getting started with BeagleBone Black - Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
PDF
Linux programming - Getting self started
Emertxe Information Technologies Pvt Ltd
 
PDF
Linux Internals - Interview essentials 4.0
Emertxe Information Technologies Pvt Ltd
 
PPTX
Embedded c
Ami Prakash
 
Communication Protocols (UART, SPI,I2C)
Emertxe Information Technologies Pvt Ltd
 
Linux systems - Getting started with setting up and embedded platform
Emertxe Information Technologies Pvt Ltd
 
File systems for Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
Introduction to Embedded Systems
Emertxe Information Technologies Pvt Ltd
 
Data Structures & Algorithm design using C
Emertxe Information Technologies Pvt Ltd
 
Embedded C - Optimization techniques
Emertxe Information Technologies Pvt Ltd
 
Emertxe : Linux training portfolio
Emertxe Information Technologies Pvt Ltd
 
Interview preparation workshop
Emertxe Information Technologies Pvt Ltd
 
BusyBox for Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
Embedded Linux - Building toolchain
Emertxe Information Technologies Pvt Ltd
 
Linux Internals - Part III
Emertxe Information Technologies Pvt Ltd
 
Emertxe : Training portfolio
Emertxe Information Technologies Pvt Ltd
 
Resume Preparation - Workshop
Emertxe Information Technologies Pvt Ltd
 
Getting started with BeagleBone Black - Embedded Linux
Emertxe Information Technologies Pvt Ltd
 
Linux programming - Getting self started
Emertxe Information Technologies Pvt Ltd
 
Linux Internals - Interview essentials 4.0
Emertxe Information Technologies Pvt Ltd
 
Embedded c
Ami Prakash
 
Ad

Similar to Embedded Android : System Development - Part II (Linux device drivers) (20)

PDF
Android for Embedded Linux Developers
Opersys inc.
 
PDF
Hunting and Exploiting Bugs in Kernel Drivers - DefCamp 2012
DefCamp
 
PPTX
Char Drivers And Debugging Techniques
YourHelper1
 
PDF
Character drivers
pradeep_tewani
 
PDF
Automotive Grade Linux and systemd
Alison Chaiken
 
PDF
Native Android Userspace part of the Embedded Android Workshop at Linaro Conn...
Opersys inc.
 
PDF
Android Internals at Linaro Connect Asia 2013
Opersys inc.
 
PDF
Linux kernel modules
Dheryta Jaisinghani
 
PPTX
Writing Character driver (loadable module) in linux
RajKumar Rampelli
 
PDF
Introduction to char device driver
Vandana Salve
 
PDF
SELinux Kernel Internals and Architecture - FOSS.IN/2005
James Morris
 
PPT
Driver_linux
Sayanton Vhaduri
 
PDF
Android Internals
Opersys inc.
 
ODP
Basis Linux (aan de hand van LPIC-1)
Peter Martin
 
PDF
An Introduction To Linux
Ishan A B Ambanwela
 
PPT
Linux Device Driver for Writing a real world driver for embedded Linux
AchyuthShettigar2
 
PPTX
Lec 10-linux-review
abinaya m
 
PDF
Understanding The Boot Process
Dom Cimafranca
 
ODP
Grub and dracut ii
plarsen67
 
PDF
Leveraging Android's Linux Heritage at AnDevCon IV
Opersys inc.
 
Android for Embedded Linux Developers
Opersys inc.
 
Hunting and Exploiting Bugs in Kernel Drivers - DefCamp 2012
DefCamp
 
Char Drivers And Debugging Techniques
YourHelper1
 
Character drivers
pradeep_tewani
 
Automotive Grade Linux and systemd
Alison Chaiken
 
Native Android Userspace part of the Embedded Android Workshop at Linaro Conn...
Opersys inc.
 
Android Internals at Linaro Connect Asia 2013
Opersys inc.
 
Linux kernel modules
Dheryta Jaisinghani
 
Writing Character driver (loadable module) in linux
RajKumar Rampelli
 
Introduction to char device driver
Vandana Salve
 
SELinux Kernel Internals and Architecture - FOSS.IN/2005
James Morris
 
Driver_linux
Sayanton Vhaduri
 
Android Internals
Opersys inc.
 
Basis Linux (aan de hand van LPIC-1)
Peter Martin
 
An Introduction To Linux
Ishan A B Ambanwela
 
Linux Device Driver for Writing a real world driver for embedded Linux
AchyuthShettigar2
 
Lec 10-linux-review
abinaya m
 
Understanding The Boot Process
Dom Cimafranca
 
Grub and dracut ii
plarsen67
 
Leveraging Android's Linux Heritage at AnDevCon IV
Opersys inc.
 
Ad

More from Emertxe Information Technologies Pvt Ltd (20)

Recently uploaded (20)

PDF
Draugnet: Anonymous Threat Reporting for a World on Fire
treyka
 
PDF
Kubernetes - Architecture & Components.pdf
geethak285
 
PDF
ICONIQ State of AI Report 2025 - The Builder's Playbook
Razin Mustafiz
 
PDF
TrustArc Webinar - Navigating APAC Data Privacy Laws: Compliance & Challenges
TrustArc
 
PDF
GDG Cloud Southlake #44: Eyal Bukchin: Tightening the Kubernetes Feedback Loo...
James Anderson
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PPTX
Securing Model Context Protocol with Keycloak: AuthN/AuthZ for MCP Servers
Hitachi, Ltd. OSS Solution Center.
 
PDF
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
PPTX
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PPTX
CapCut Pro PC Crack Latest Version Free Free
josanj305
 
PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Pitch ...
Michele Kryston
 
PDF
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
PPTX
2025 HackRedCon Cyber Career Paths.pptx Scott Stanton
Scott Stanton
 
PDF
99 Bottles of Trust on the Wall — Operational Principles for Trust in Cyber C...
treyka
 
PPTX
Practical Applications of AI in Local Government
OnBoard
 
PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
 
PPTX
Wondershare Filmora Crack Free Download 2025
josanj305
 
Draugnet: Anonymous Threat Reporting for a World on Fire
treyka
 
Kubernetes - Architecture & Components.pdf
geethak285
 
ICONIQ State of AI Report 2025 - The Builder's Playbook
Razin Mustafiz
 
TrustArc Webinar - Navigating APAC Data Privacy Laws: Compliance & Challenges
TrustArc
 
GDG Cloud Southlake #44: Eyal Bukchin: Tightening the Kubernetes Feedback Loo...
James Anderson
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
Securing Model Context Protocol with Keycloak: AuthN/AuthZ for MCP Servers
Hitachi, Ltd. OSS Solution Center.
 
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
CapCut Pro PC Crack Latest Version Free Free
josanj305
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Pitch ...
Michele Kryston
 
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
2025 HackRedCon Cyber Career Paths.pptx Scott Stanton
Scott Stanton
 
99 Bottles of Trust on the Wall — Operational Principles for Trust in Cyber C...
treyka
 
Practical Applications of AI in Local Government
OnBoard
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
 
Wondershare Filmora Crack Free Download 2025
josanj305
 

Embedded Android : System Development - Part II (Linux device drivers)

  • 1. Team Emertxe Linux Device Drivers An Introduction
  • 3. Familiarity Check ● Good C & Programming Skills ● Linux & the Filesytem – Root, User Space Headers & Libraries ● Files – Regular, Special, Device ● Toolchain – gcc & friends ● Make & Makefiles ● Kernel Sources (Location & Building)
  • 4. The Flow ● Introduction – Linux kernel Ecosystem – Kernel Souce Organization – Command set and Files – Writing the first driver (Module) ● Character Drivers – Device files – Device access from user space (End to End flow) – Registering the driver – File Operations and registration – Data transfer between User and Kernel space – ioctl ● Memory & Hardware ● Time & Timings ● USB Drivers ● Interrupt Handling ● Block Drivers ● PCI Drivers ● Debugging
  • 5. The Flow... ● Introduction – Linux kernel Ecosystem – Kernel Souce Organization – Command set and Files – Writing the first driver (Module) ● Character Drivers – Device files – Device access from user space (End to End flow) ● Memory & Hardware ● Time & Timings ● USB Drivers ● Interrupt Handling ● Block Drivers ● PCI Drivers ● Debugging
  • 6. Hands-On ● Your First Driver ● Character Drivers – Null Driver – Memory Driver – UART Driver for Customized Hardware ● USB Drivers – USB Device Hot-plug-ability – USB to Serial Hardware Driver ● Filesystem Modules – VFS Interfacing – “Pseudo” File System with Memory Files
  • 7. Linux Driver Ecosystem bash gvim X Server gcc firefox ` ` Process Management ssh Memory Management File Systems Device Control Networking Architecture Dependent Code Character Devices Memory Manager Filesystem Types Block Devices Network Subsystem IF Devices Concurrency MultiTasking Virtual Memory Files & Dirs: The VFS Ttys & Device Access Connectivity CPU Memory Disks & CDs Consoles, etc Network Interfaces
  • 8. Kernel Source Organization Kernel Source include net drivers block fs mm kernel arch char mtd/ide net pci ...usbserial asm-<arch>linux arm powerpc sparc x86 ...
  • 9. The Locations & Config Files ● Kernel Source Path: /usr/src/linux ● Std Modules Path: – /lib/modules/<kernel version>/kernel/... ● Module Configuration: /etc/modprobe.conf ● Kernel Windows: – /proc – /sys ● System Logs: /var/log/messages
  • 11. The Kernel's C ● ctor & dtor – init_module, cleanup_module ● printf – printk ● Libraries – <kernel src>/kernel ● Headers – <kernel src>/include
  • 12. The Init Code static int __init mfd_init(void) { printk(KERN_INFO "mfd registered"); ... return 0; } module_init(mfd_init);
  • 13. The Cleanup Code static void __exit mfd_exit(void) { printk(KERN_INFO "mfd deregistered"); ... } module_exit(mfd_exit);
  • 14. Usage of printk ● <linux/kernel.h> ● Constant String for Log Level – KERN_EMERG "<0>" /* system is unusable */ – KERN_ALERT "<1>" /* action must be taken immediately */ – KERN_CRIT "<2>" /* critical conditions */ – KERN_ERR "<3>" /* error conditions */ – KERN_WARNING "<4>" /* warning conditions */ – KERN_NOTICE "<5>" /* normal but significant condition */ – KERN_INFO "<6>" /* informational */ – KERN_DEBUG "<7>" /* debug-level messages */ ● printf like arguments
  • 15. The Other Basics & Ornaments ● Headers – #include <linux/module.h> – #include <linux/version.h> – #include <linux/kernel.h> ● MODULE_LICENSE("GPL"); ● MODULE_AUTHOR("Emertxe"); ● MODULE_DESCRIPTION("First Device Driver");
  • 16. Building the Module ● Our driver needs – The Kernel Headers for Prototypes – The Kernel Functions for Functionality – The Kernel Build System & the Makefile for Building ● Two options – Building under Kernel Source Tree ● Put our driver under drivers folder ● Edit Kconfig(s) & Makefile to include our driver – Create our own Makefile to do the right invocation
  • 17. Our Makefile ifneq (${KERNELRELEASE},) obj-m += <module>.o else KERNEL_SOURCE := <kernel source directory path> PWD := $(shell pwd) default: $(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) modules clean: $(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) clean endif
  • 18. Try Out your First Driver
  • 20. Major & Minor Number ● ls -l /dev ● Major is to Driver; Minor is to Device ● <linux/types.h> (>= 2.6.0) – dev_t: 12 & 20 bits for major & minor ● <linux/kdev_t.h> – MAJOR(dev_t dev) – MINOR(dev_t dev) – MKDEV(int major, int minor)
  • 21. Registering & Unregistering ● Registering the Device Driver – int register_chrdev_region(dev_t first, unsigned int count, char *name); – int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int cnt, char *name); ● Unregistering the Device Driver – void unregister_chrdev_region(dev_t first, unsigned int count); ● Header: <linux/fs.h>
  • 22. The file operations ● #include <linux/fs.h> ● struct file_operations – int (*open)(struct inode *, struct file *); – int (*release)(struct inode *, struct file *); – ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); – ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); – struct module owner = THIS_MODULE; / linux/module.h> */ – loff_t (*llseek)(struct file *, loff_t, int); – int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
  • 23. User level I/O ● int open(const char *path, int oflag, ... ) ● int close(int fd); ● ssize_t write(int fd, const void *buf, size_t nbyte) ● ssize_t read(int fd, void *buf, size_t nbyte) ● int ioctl(int d, int request, ...) – The ioctl() function manipulates the underlying device parameters of special files. – The argument d must be an open file descriptor. – The second argument is a device-dependent request code.
  • 24. The file & inode structures ● struct file – mode_t f_mode – loff_t f_pos – unsigned int f_flags – struct file_operations *f_op – void * private_data ● struct inode – unsigned int iminor(struct inode *); – unsigned int imajor(struct inode *);
  • 25. Registering the file operations ● #include <linux/cdev.h> ● 1st way initialization: – struct cdev *my_cdev = cdev_alloc(); – my_cdev->owner = THIS_MODULE; – my_cdev->ops = &my_fops; ● 2nd way initialization: – struct cdev my_cdev; – cdev_init(&my_cdev, &my_fops); – my_cdev.owner = THIS_MODULE; – my_cdev.ops = &my_fops;
  • 26. Registering the file operations... ● The Registration – int cdev_add(struct cdev *cdev, dev_t num, unsigned int count); ● The Unregistration – void cdev_del(struct cdev *cdev);
  • 27. Registering/Unregistering Old Way ● Registering the Device Driver – int register_chrdev(undigned int major, const char *name, struct file_operations *fops); ● Unregistering the Device Driver – int unregister_chrdev(undigned int major, const char *name);
  • 28. The read flow struct file ------------------------- f_count f_flags f_mode ------------------------- f_pos ------------------------- ... ... ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t *off) Buffer (in the driver) Buffer (in the application or libc) Kernel Space (Non-swappable) User Space (Swappable) copy_to_user
  • 29. The /dev/null read & write ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t *off) { ... return read_cnt; } ssize_t my_write(struct file *f, char __user *buf, size_t cnt, loff_t *off) { ... return wrote_cnt; }
  • 30. The mem device read ssize_t my_read(struct file *f, char __user *buf, size_t cnt, loff_t *off) { ... if (copy_to_user(buf, from, cnt) != 0) { return -EFAULT; } ... return read_cnt; }
  • 31. The mem device write ssize_t my_write(struct file *f, char __user *buf, size_t cnt, loff_t *off) { ... if (copy_from_user(to, buf, cnt) != 0) { return -EFAULT; } ... return wrote_cnt; }
  • 32. Dynamic Device Node & Classes ● Class Operations – struct class *class_create(struct module *owner, char *name); – void class_destroy(struct class *cl); ● Device into & Out of Class – struct class_device *device_create(struct class *cl, NULL, dev_t devnum, NULL, const char *fmt, ...); – void device_destroy(struct class *cl, dev_t devnum);
  • 33. The I/O Control API ● int (*ioctl)(struct inode *, struct file *, unsigned int cmd, unsigned long arg) ● int (*unlocked_ioctl)(struct file *, unsigned int cmd, unsigned long arg) ● Command – <linux/ioctl.h> -> ... -> <asm-generic/ioctl.h> – Macros ● _IO, _IOR, _IOW, _IOWR – Parameters ● type (Magic character) [15:8] ● number (index) [7:0] ● size (param type) [29:16]
  • 34. The I/O Control API ● Macro Usage _IO(type, index) [_IOR | _IOW | _IOWR](type, index, datatype/size)
  • 35. Module Parameters ● <linux/moduleparam.h> – Macros ● module_param(name, type, perm) ● module_param_array(name, type, num, perm) ● Perm (is a bitmask) – 0 – S_IRUGO – S_IWUSR | S_IRUGO – Loading ● insmod driver.ko name=10
  • 38. Physical Vs Virtual Memory ● The kernel Organizes Physical memory in to pages – Page size Depends on Arch ● X86-based 4096 bytes ● On 32-bit X86 system Kernel total Virtual address space – Total 4GB (pointer size) – Kernel Configuration Splits 4GB in to ● 3BG Virtual Sp for US ● 1GB Virtual Sp for Kernel – 128MB KDS – Virtual Address also called “Logical Address”
  • 39. Memory Access from Kernel Space ● Virtual Address on Physical Address – #include <linux/gfp.h> ● unsigned long __get_free_pages(flags, order); etc ● void free_pages(addr, order); etc – #include <linux/slab.h> ● void *kmalloc(size_t size, gfp_t flags); – GFP_ATOMIC, GFP_KERNEL, GFP_DMA ● void kfree(void *obj); – #include <linux/vmalloc.h> ● void *vmalloc(unsigned long size); ● void vfree(void *addr);
  • 40. Memory Access from Kernel Space... ● Virtual Address for Bus/IO Address – #include <asm/io.h> ● void *ioremap(unsigned long offset, unsigned long size); ● void iounmap(void *addr); ● I/O Memory Access – #include <asm/io.h> ● unsigned int ioread[8|16|32](void *addr); ● unsigned int iowrite[8|16|32](u[8|16|32] value, void *addr); ● Barriers – #include <linux/kernel.h>: void barrier(void); – #include <asm/system.h>: void [r|w|]mb(void);
  • 42. I/O Accesses from Kernel Space ● I/O Port Access – #include <asm/io.h> ● unsigned in[b|w|l](unsigned port); ● void out[b|w|l](unsigned [char|short|int] value, unsigned port);