The Linux PCI Interface - PowerPoint PPT Presentation

About This Presentation
Title:

The Linux PCI Interface

Description:

Bits 0..3 have some special meanings. So we will need to examing bits 4..31 ... Changes were made to exported symbols (e.g., sys_call_table) Need a work-around' ... – PowerPoint PPT presentation

Number of Views:81
Avg rating:3.0/5.0
Slides: 21
Provided by: professora5
Learn more at: https://www.cs.usfca.edu
Category:

less

Transcript and Presenter's Notes

Title: The Linux PCI Interface


1
The Linux PCI Interface
  • An introduction to the PCI configuration space
    registers

2
Some background on PCI
  • ISA Industry Standard Architecture (1981)
  • PCI Peripheral Component Interconnect
  • An Intel-backed industry initiative (1992-9)
  • Main goals
  • Improve data-xfers to/from peripheral devices
  • Eliminate (or reduce) platform dependencies
  • Simplify adding/removing peripheral devices
  • Lower total consumption of electrical power

3
Features for driver-writers
  • Support for auto-detection of devices
  • Device configuration is programmable
  • Introduces PCI Configuration Space
  • A nonvolatile data-structure of device info
  • A standard header layout 64 longwords
  • Linux provides some interface functions
  • include ltlinux/pci.hgt

4
pci_dev_struct
  • Linux extracts info from PCI Config. Space
  • Stores the info in linked-lists of structures
  • Examples
  • Name of the devices manufacturer
  • Name and release version of the product
  • Hardware resources provided by the product
  • System resources allocated to the product
  • (Linux provides search-and-extract routines)

5
The lspci command
  • Linux scans PCI Configuration Space
  • It builds a list of pci_dev_struct objects
  • It exports partial info using a /proc file
  • You can view this info using a command
    /sbin/lspci
  • Or you can directly view the /proc/pci file
  • cat /proc/pci

6
An illustrative example vram.c
  • Lets write another character device-driver
  • It will allow read/write access to video ram
  • Very analogous to our prior ram.c driver
  • Some differences
  • Devices memory resides on PCI the bus
  • Can safely allow writing as well as reading
  • Hardware uses memory in nonstandard ways
  • We really need vendors programmer manual

7
init_module()
  • Drivers first job is device detection
  • PCI devices are identified by numbers
  • Device classes also have ID-numbers
  • VGA device-class 0x030000
  • 03 means a display device
  • 00 means VGA compatible
  • 00 means revision-number

8
pci_find_class()
  • Define the manifest constant
  • define VGA_CLASS 0x030000
  • Declare a null-pointer
  • struct pci_dev_struct devp NULL
  • Call pci_find_class() function
  • devp pci_find_class( VGA_CLASS, devp )
  • Check for device-not-found
  • if ( devp NULL ) return ENODEV

9
Locate the VGA frame buffer
  • In PCI Configuration Space
  • offset 0x10 base_address0
  • offset 0x14 base_address1
  • offset 0x18 base_address2
  • . . . etc. . . .
  • (complete layout on page 475 in textbook)
  • A convenient Linux extraction-function
  • fb_base pci_resource_start( devp, 0 )

10
How big is the frame buffer?
  • Size of video memory varies with product
  • Driver needs to determine memory-size
  • PCI a standard way to determine size
  • (But product might provide support for larger
    vram than is currently installed)
  • Two-step size-detection method
  • First determine maximum supported size
  • Then check for redundant addressing

11
Maximum memory-size
  • Some bits in base_address0 are wired
  • But other bit-values are programmable
  • Bits 0..3 have some special meanings
  • So we will need to examing bits 4..31
  • Find least significant programmable bit
  • It tells the maximum supported memory

12
Programming algorithm
  • Get configuration longword at offset 0x10
  • Save it (so that we can restore it later)
  • Write a new value all bits set to 1s
  • Read back the longword just written
  • The hard-wired bits will still be 0s
  • We will scan for first bit thats 1
  • Be sure to restore the original longword

13
Loop to find the lowest 1
  • Implementing the PCI size-test
  • pci_write_config_dword( devp, 0x10, 0 )
  • pci_read_config_dword( devp, 0x10, val)
  • int i
  • for (i 4 i lt 32 i)
  • if ( val ( 1 ltlt i ) ) break
  • fb_maxsize ( 1 ltlt i )

14
Checking for memory wrap
  • Do vram bytes have multiple addresses?
  • We use a quick-and-dirty check
  • write to one address, read from another
  • If what we read didnt change no wrap!
  • Some assumptions we make
  • Memory-size will be a power of 2
  • If two bytes differ, all between them do, too
  • (Should we question these assumptions?)

15
Device-memory read and write
  • The CPU understands virtual addresses
  • They must be mapped to bus addresses
  • The kernel must setup page-table entries
  • Linux kernel provides functions
  • vaddr ioremap( physaddr, memsize )
  • iounmap( vaddr )
  • Alternative can use ioremap_nocache()

16
For copying ram to/from vram
  • Linux provides special memcpy functions
  • memcpy_fromio( ram, vram, nbytes )
  • memcpy_toio( vram, ram, nbytes )

17
Our vram.c driver
  • We imitate the code in our ram.c driver
  • We use temporary mappings (one page)
  • Our read() and write() are very similar
  • One notable difference
  • read() is supposed to return 0 in case
  • the files pointer is at the end-of-file
  • (This defect should be corrected in ram.c)

18
Warning about Red Hat 9.0
  • Red Hat 9.0 is now available in stores
  • It advertises kernel version 2.4.20
  • But its not identical to 2.4.20 in our class
  • Our demo modules do not always work
  • Changes were made to kernel structures
  • (e.g., task_struct)
  • Changes were made to exported symbols
  • (e.g., sys_call_table)

19
Need a work-around
  • Our vram.c doesnt create its device-node
  • Requires users to create a node manually
  • We hard-coded the device major number
  • So decisions differ from our past practice

20
Exercises
  • Get vram.c from our class website
  • Compile and install the vram.c driver
  • Create the device special file /dev/vram
  • Change file-attributes (to allow writing)
  • Try copying video frame-buffer to a file
  • Use dump.cpp to view that binary file
  • Try using fileview.cpp to view video ram
Write a Comment
User Comments (0)
About PowerShow.com