A device-driver for Video Memory Introduction to basic principles of

advertisement

A device-driver for

Video Memory

Introduction to basic principles of the PC’s graphics display

Raster Display Technology

The graphics screen is a twodimensional array of picture elements (‘pixels’)

These pixels are redrawn sequentially, left-to-right, by rows from top to bottom

Each pixel’s color is an individually programmable mix of red, green, and blue

Special “dual-ported” memory

VRAM CRT

CPU

RAM

32-MB of VRAM

1024-MB of RAM

Graphics programs

• What a graphics program must do is put appropriate bit-patterns into the correct locations in the VRAM, so that the CRT will show an array of colored dots which in some way is meaningful to the human eye

• Thus, programmer must understand what the CRT will do with the contents of VRAM

How much VRAM is needed?

• This depends on (1) the total number of pixels, and on (2) the number of bits-per-pixel

• The total number of pixels is determined by the screen’s width and height (measured in pixels)

• Example: when our “screen-resolution” is set to

1280-by-1024, we are seeing 1,310,720 pixels

• The number of bits-per-pixel (“color depth”) is a programmable parameter (varies from 1 to 32)

• Some types of applications also need to use extra VRAM (for multiple displays, or for “special effects” like computer game animations)

How ‘truecolor’ works longword alpha

24 red

16 green

8 blue

0

R

G

B pixel

The intensity of each color-component within a pixel is an 8-bit value

Intel uses “little-endian” order

VRAM

0 1 2 3

B G R

4 5 6 7

B G R

8 9 10

B G R

Video Screen

Recall our ‘dram.c’ driver

• Earlier we wrote a simple character-mode devicedriver (named ‘dram.c’) that let an application program read the contents of the processor’s physical memory (1 GB)

• That device driver’s ‘read()’ function used the Linux kernel’s ‘kmap()’ function to map pages of physical memory to kernel space

We want a ‘vram.c’ driver

• We can create a similar device-driver that will let an application read, and also write, to our system’s video display memory

• But a few new issues will arise:

– Where is physical video memory located?

– How do we ‘map’ vram to virtual addresses?

– How can we trasfer data to and from vram?

Physical Memory Space (4GB)

0xFFFFFFFF

VRAM

1-GigaByte

0x40000000

DRAM

0x00000000

Mapping a device’s memory

• We use a pair of special kernel functions to ‘map’ and ‘unmap’ segments of vram: void *virtaddr = ioremap ( physaddr, len ); void iounmap ( virtaddr );

Remember: device-memory is not tracked by the ‘struct page’ entries of ‘mem_map[]’

Virtual to Physical video memory video memory kernel space user space

High memory

Zone normal physical address-space virtual address-space

Doing data-transfers

• Instead of using the ‘copy_to_user()’ and

‘copy_from_user()’ kernel-functions, data is transferred to and from device-memory using this pair of Linux kernel functions: void memcpy_fromio ( buf, dev, length); void memcpy_toio ( dev, buf, length );

Finding a device’s memory

• Modern peripheral devices for PCs do not employ standard fixed memory-addresses

• Device-memory gets physically mapped to unused areas in the CPU’s address-space during the ‘system configuration’ process

• The locations and sizes of device-memory are ‘remembered’ in non-volatile batterypowered RAM (‘configuration memory’)

Kernel’s PCI functions

• Linux provides a set of kernel functions for device-drivers to use when locating where a device’s memory was physically mapped

• The PCI functions (Peripheral Component

Interconnect) are based on industry-wide standards based on committee consensus

• Devices use an identification-number pair:

#define VENDOR_ID 0x1039

#define DEVICE_ID 0x6325

Functions we need struct pci_dev {

// contains many fields

}; struct pci_dev *devp = NULL; devp = pci_find_device ( VID, DID, devp );

Base-address and Length

• For the SiS-315 Graphics Processor used in our classroom and lab workstations, the display memory is ‘resource number 0’ unsigned long base, size; base = pci_resource_start( devp, 0 ); size = pci_resource_len( devp, 0 );

NOTE: Our machines have 32MB of VRAM

(although are capable of addressing 128MB)

In-class exercise

• We created a ‘vramdraw.cpp’ application that exercises our ‘vram.c’ device-driver’s

‘read()’, ‘write()’, and ‘llseek()’ methods – but it has a noticable programming ‘bug’.

• Your job is to analyze carefully the driver’s code and the program’s code, in order to find the bug – and then fix it!

Download