lesson13

yellvillepotatocreekΛογισμικό & κατασκευή λογ/κού

2 Δεκ 2013 (πριν από 4 χρόνια και 29 μέρες)

90 εμφανίσεις

The ‘ioctl’ driver
-
function

On implementing ‘show’ and ‘hide’
for the SiS 315 hardware cursor

‘struct file_operations’


For a Linux device
-
driver’s ‘init_module()’
function, there are two main actions:


Initializing the driver’s global data
-
structures
(this includes verifying the device’s presence)


Registering the driver’s service
-
functions with
the kernel (i.e., the ‘file_operations’ structure)


The driver’s ‘cleanup_module()’ function
has the duty to ‘unregister’ those services


Driver services


For character
-
mode device
-
drivers (such
as our ‘dram.c’, ‘mbr.c’, and ‘vramm.c’),
we have implemented some (or all) of the
following service
-
functions (i.e., ‘methods’)



read()



llseek()



write()



mmap()

The ‘file’ paradigm


The UNIX approach to device
-
control is to
create objects that represent i/o
-
devices,
but which behave like ‘files’ do, insofar as
the application programmer is concerned


So ‘read()’, ‘llseek()’, ‘write()’ and ‘mmap()
use the same function
-
call syntax


and in
most respects the same semantics


for
both ‘files’ and ‘devices’

An imperfect paradigm


But often there are a few ways in which
the file
-
object paradigm doesn’t quite fit
with important features of an i/o device


In these cases, device
-
drivers can provide
a ‘workaround’ that allows applications to
perform device
-
actions that deviate from
customary ‘read/write/seek’ file
-
like actions


This ‘workaround’ mechanism is ‘ioctl()’

The graphics display


Our PC’s graphics display device offers an
easy example of desirable behavior that is
outside the traditional ‘file’ paradigm


In order to display graphical images that
are full
-
screen renderings of artistic work,
we want to avoid seeing a mouse
-
cursor
(it’s an ugly and disruptive and distraction)


How can a program ‘turn off’ that cursor?

The GPU ‘resources’


The SiS 315 graphics processing units in
our workstations are each equipped with
32
-
megabytes of video display memory
(designated as PCI resource 0)


These graphics adapters also implement a
set of memory
-
mapped registers known as
the 2D graphics engine (and designated
as PCI resource 1)

‘pci_resource_start()’


Device
-
drivers can use this Linux kernel
function to discover the physical address
where resource 0, or resource 1, resides


struct pci_dev

*devp = NULL:


devp = pci_find_device( VEN, DEV, devp );


vram = pci_resource_start( devp, 0 );


mmio = pci_resource_start( devp, 1 );

SiS 315 information


Programming manual for the SiS 315 GPU
is not usually made available to the public


But some information can be derived from
reading Linux device
-
driver source
-
code


Examples are:


The ‘/usr/src/linux/drivers/video/sis’ directory


Also download the ‘svgalib
-
1.9.17’ package


Graphics Cursor


cursor
-
image source
-
offset

31 30

0

0x8500

cursor visibility control bit: 0=hide, 1=show


cursor
-
image horizontal coordinate

0x850C

0x8510

cursor starting command bit: 0=no, 1=yes


cursor
-
image vertical coordinate

Algorithm to hide cursor


Map physical page containing the registers
to a virtual address (with ‘ioremap()’)


Read current values of these registers


Clear bit #30 (to make cursor
invisible
)


Set bit #31 (to initiate a new command)


Write these adjusted register values


Undo the mapping (with ‘iounmap()’)

Algorithm to show cursor


Map physical page containing the registers
to a virtual address (with ‘ioremap()’)


Read current values of these registers


Set bit #30 (to make cursor
visible
)


Set bit #31 (to initiate a new command)


Write these adjusted register values


Undo the mapping (with ‘iounmap()’)


The ‘ioctl.c’ module


These techniques are demonstrated in this
device
-
driver module’s ‘ioctl()’ function


Two IOCTL commands are implemented


#define CURSOR_HIDE

0


#define CURSOR_SHOW

1


Applications can open the device
-
file, then
use an ioctl
-
command; for example:


int fd = open( “/dev/vram”, O_RDWR );


ioctl( fd, CURSOR_HIDE);

In
-
class exercise #1


Try adding new IOCTL commands to the
‘ioctl.c’ driver which lets applications find
or move the cursor’s screen
-
position;



#define CURSOR_FIND

2



#define CURSOR_MOVE

3



struct { long x, y; } location;




ioctl( fd, CURSOR_FIND, &location );



location.x += 40;


location.y += 40;



ioctl( fd, CURSOR_MOVE, &location );

In
-
class exercise #2


We are not told what function is served by
two of the SiS engine’s i/o locations:


0x8500 (longword) cursor
-
image source
-
offset


0x8504 (longword) <??? Unknown ???>


0x8508 (longword) <??? Unknown ???>


0x850C (longword) cursor
-
image horiz
-
coord


0x8510 (longword) cursor
-
image vertl
-
coord


So can you ‘discover’ their purpose?