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!