Chapter Three' Char Driver - PowerPoint PPT Presentation

1 / 16
About This Presentation
Title:

Chapter Three' Char Driver

Description:

Chapter Three' Char Driver – PowerPoint PPT presentation

Number of Views:42
Avg rating:3.0/5.0
Slides: 17
Provided by: camarsK
Category:
Tags: chapter | char | dptr | driver | three

less

Transcript and Presenter's Notes

Title: Chapter Three' Char Driver


1
Chapter Three. Char Driver
  • CS 230
  • Joonwon Lee

2
Introduction
  • Design and Write a compete char driver
  • easier than block driver
  • you can understand basic driver mechanism
  • scull
  • simple char utility for loading localities
  • use memory as if it were a device
  • usual operations for a device are read and write,
    anyway
  • allocate memory using kmalloc
  • you can download the source from www.oreilly.com

3
Scull Overview
  • types of devices implemented by scull
  • global and persistent scull0-3
  • data written can be shared
  • data is not lost after close operation
  • fifo devices scullpipe0-3
  • one process reads what is being written by
    another process
  • multiple reads content for the data
  • blocking without interrupt
  • drivers block usually with device interrupts
  • scullsingle allow only one process
  • scullpriv private to each virtual console
  • sculluid, scullwid
  • allow only one user at a time
  • scullid generates error msg while the latter
    blocks processes

4
Major and Minor Number
  • look at /dev using ls l command
  • the first c means it is a char device
  • while b means that it is a block device
  • the numbers after the owner are them
  • a major number identifies a device driver
  • there can be several devices controlled by one
    driver
  • upto 128 elements
  • a minor number identifies a device
  • since a driver(a major number) controls several
    devices
  • used only by the driver
  • 0-255

5
Registering a new driver
  • register_chrdev (major, name, fops)
  • tells the kernel to remember the major number and
    the name of the device driver associated with it.
  • fops is a pointer to a table of operations (open,
    read, )
  • a user request (syscall) is mapped to one of
    functions indexed in the jump table
  • when major 0, it returns a dynamically
    allocated major number
  • unregister_chrdev(major, name)
  • mknod /dev/name c 127 0
  • the name should be the same
  • now users can access the device

result register_chrdev(smajor, scull,
scull_fops) if (result lt 0) printk(w_level
scull cannot get a major d\n major)
return result if (smajor 0) smajor result
6
File Operations
  • file_operations structure defines a set of
    operations for a device
  • refer page 50-51 for exact argument types for
    each functions
  • ioctl defines commands specific to the device
  • mmap memory mapped IO
  • release invoked when the node is closed
  • 4 NULLs
  • fsync flush the device
  • fasync for async operation
  • check_media_change change diskettes
  • revalidate validate the buffer

struct file_operations scull_fops
scull_lseek, scull_read, scull_write, NULL,
/ readdir / NULL, / select
/ scull_ioctl, NULL, /mmap
/ scull_open, scull_release, / insert 4
NULLs here /
7
Open in General
  • what is does
  • initialize the device
  • increment the usage count
  • identify minor number
  • inode-gti_rdev
  • updates filp-gtf_op according to the minor number
  • pointer to the actual open routine
  • open routine varies depending on the device type
  • filp? a pointer to the file structure (file
    structure? next slide)

8
file
  • a data structure created by the kernel at open a
    device
  • it is different from files used by applications
  • a pointer to file is passed to any operations on
    this device
  • released at close
  • defines
  • f_mode read or write
  • f_pos position (64 bit)
  • f_flags read only, nonblock, sync
  • f_inode inode used by the kernel
  • f_op operations allowed on this device like
    scull_fops
  • private_data
  • data area used by a driver

9
scull_open( )
  • there are 6 types of devices for scull
  • scull0-3, scullpipe0-3, scullsingle, scullpriv,
    sculluid, scullwid
  • set of operations for each of them are different
  • how can they be differentiated? use some bits of
    the minor
  • high 4bits type
  • low 4 bits device number
  • scull_fop_array
  • array of pointers
  • a pointer points to the set of operations allowed
    for each device

struct file_operations scull_fop_array
scull_fops, / type 0 scull0-3
/ scull_priv_fops, / private
/ scull_pipe_fops, / pipe / scull_sngl_fops
, / single / scull_user_fops, /sculluid
/ scull_wuser_fops /scullwid /
10
scull_open( ) code
int scull_open(struct inode inode, struct file
filp) int type (MINOR(inode-gti_rdev)
gtgt4) / high 4 bits / int num
(MINOR(inode-gti_rdev) 0xf) / low 4 bits /
Scull_Dev dev / explained later / if
(type) / all except type 0 / filp-gtf_op
scull_fop_arraytype return filp-gtf_op-gtopen(in
ode, filp) / device driver for the type
0 goes here /
  • scull_open was defined at scull_fops that was
    used by register_chedev( )
  • you can use the same scull_open for all the
    device types
  • MINOR is a macro to extract the minor number

11
open for type 0 device
/ device driver for the type 0 goes here /
i f (num gt scull_nr_devs) return ENODEV
dev scull_devicesnum if ( (filp-gtf_flags
O_ACCMODE) O_WRONLY) scull_trim(dev)
filp-gtprivate_data dev / store the 1st node
of the linked list / MOD_INC_USE_COUNT
return 0
  • no initialization because scull0-3 are memory
    devices
  • when open for write, trim to zero this is a
    scull decision
  • scull_nr_devs the number of available devices
  • scull_devices array of scull memory

12
Sculls Memory Usage for a device
Scull_Dev
Scull_Dev
Scull_Dev
next
next
next
. . . . .
data
data
data
quanta
quanta
quanta
quanta
quanta
quanta
quanta
quanta
quanta
. . . . .
. . . . .
. . . . .
quanta
quanta
quanta
qset
typedef struct Scull_Dev void data /
pointer to array(quantum set) / struct
Scull_Dev next int quantum / current
quantum size / int qset / current
quantum set size / unsigned long size
unsigned long access_key / for sculluid,
scullwid / unsigned int usage / lock
the device /
13
scull_trim( )
int scull_trim(Scull_Dev dev)
Scull_Dev next, dptr int qset
dev-gtqset / qset size / int i if
(dev-gtusage) return EBUSY for (dptr
dev dptr dptr next) / for every node in
the linked list / if (dptr-gtdata) / this
node is not empty / for (i 0 i lt qset
i) / for every pointer in qset / if
(dptr-gtdatai) / this quanta is not empry
/ kfree(dptr-gtdatai)
kfree(dptr-gtdata) / free the whole array
/ dptr-gtdata NULL next
dptr-gtnext if (dptr ! dev) kfree(dptr) /
free nodes except the 1st one /
dev-gtsize 0
14
Read and Write
  • reading/writing a device means data transfer
    between user and kernel space
  • pointer, memcpy cannot be used
  • Linux has functions for cross-space copy
  • defined in ltasm/segment.hgt
  • void memcpy_from(void to, const void from,
    unsigned long count)
  • void memcpy_tofs(void to, const void from,
    unsigned long count)
  • what if the space data is not in memory?
  • fault handler shows up ! your process sleeps!
  • any functions that access use space should be
    reentrant
  • Though you may request n bytes transfer, less
    than n bytes may be transferred
  • the device returns the actual number of bytes
    transferred
  • user code should check the return value and
    reissue the request if necessary

15
read( )
rw_t scull_read(struct inode inode, struct file
filp, char buf, count_t count) Scull_Dev
dev filp-gtprivate_data / the first node
stored at open / int qset dev-gtqsey
int quantum dev-gtquantum int itemsize
quantum qset / size of a node / unsigned
long f_pos filp-gtf_pos int item, s_pos,
q_pos, rest if (f_pos gt dev_size) return
0 / end of file / if (f_pos count gt
dev-gtsize) count dev-gtsize f_pos item
f_pos / itemsize / node number / rest
f_pos itemsize s_pos rest / quantum
/ quantum number / q_pos rest
quantum / location inside the quantum / dev
scull_follow(dev, item) / traverse the linked
list /
16
read( ) cont
if (!dev-gtdata) return 0 / no qset / if
(!dev-gtdatas_pos return 0 / no quantum /
if (count gt quantum q_pos) / this read
routine reads / count quantum qpos / only
upto the end of the quantum) / dev-gtusage
memcpy(buf, dev-gtdatas_posq_pos,
count) dev_usage-- / , -- for entrant
code / filp-gtf_pos count return
count
Write a Comment
User Comments (0)
About PowerShow.com