PCI device driver development under Linux

  
        

First, PCI bus system architecture

PCI is the abbreviation of Peripheral Component Interconnect, as a general bus interface standard, it has been widely used in current computer systems. Applications. PCI provides a complete set of bus interface specifications for the purpose of describing how peripheral devices in a computer system are connected together in a structured and controlled manner, while also depicting the electrical properties of peripheral devices when connected. Features and behavioral conventions, and define in detail how the various components in a computer system should interact correctly.

Whether in an Intel-based PC or on an Alpha-based workstation, PCI is undoubtedly the most widely used bus interface standard. Unlike the old ISA bus, PCI completely separates the bus subsystem from the storage subsystem in the computer system. The CPU completes the interaction with the bus subsystem through a device called PCI-Bridge, as shown in Figure 1. Shown.
Figure 1 PCI subsystem architecture

Due to the higher clock frequency, the PCI bus can achieve better overall performance than the ISA bus. The clock frequency of the PCI bus is generally in the range of 25MHz to 33MHz, and some can even reach 66MHz or 133MHz, while in 64-bit systems, the maximum can reach 266MHz. Although PCI devices mostly use 32-bit data buses, the 64-bit extended implementation has been given in the PCI specification, which makes the PCI bus better platform-independent. Now the PCI bus can be used for IA-32, Alpha. In the architecture of PowerPC, SPARC64 and IA-64.

The PCI bus has three very significant advantages, enabling it to accomplish the historical mission of eventually replacing the ISA bus:

Better performance when transferring data between computers and peripherals; Can be as independent as possible from a specific platform; plug and play can be easily implemented. Figure 2 is a schematic diagram of a typical PCI bus-based computer system with various parts of the system connected by a PCI bus and a PCI-PCI bridge. It is not difficult to see from the figure that the CPU and RAM need to be connected to the PCI bus 0 (ie, the main PCI bus) through the PCI bridge, and the graphics card with the PCI interface can be directly connected to the main PCI bus. The PCI-PCI bridge is a special PCI device that is responsible for connecting the PCI bus 0 and the PCI bus 1 (ie, from the PCI main line). Usually, the PCI bus 1 is called the downstream of the PCI-PCI bridge, and the PCI bus. 0 is called the upstream of the PCI-PCI bridge. Connected to the slave PCI bus in the figure are SCSI cards and Ethernet cards. To be compatible with the old ISA bus standard, the PCI bus can also be connected to the ISA bus via a PCI-ISA bridge to support previous ISA devices. A multi-function I/O controller is connected to the ISA bus to control the keyboard, mouse and floppy drive.
Figure 2 PCI system diagram

Here I only give a general introduction to the PCI bus system architecture, if the reader wants to know more, David A Rusling in The Linux Kernel (http://tldp. The org/LDP/tlk/dd/pci.html) has a more detailed introduction to the Linux PCI subsystem.

Second, the Linux driver framework

Linux regards all external devices as a special type of file, called "device file", if the system call is the Linux kernel and application The interface between the programs, then the device driver can be seen as the interface between the Linux kernel and external devices. The device driver shields the application from the implementation details of the hardware, allowing the application to operate the external device as if it were a normal file.

1. Character devices and block devices

Linux abstracts the processing of hardware. All hardware devices can be viewed like ordinary files: they can use the same standard as the operation files. The system calls the interface to perform open, close, read and write, and I/O control operations, and the main task of the driver is to implement these system call functions. All hardware devices in a Linux system are represented by a special device file. For example, the first IDE hard disk in the system is represented by /dev/hda. Each device file has two device numbers: one is the major device number, identifies the type of the device, and also identifies the driver used by the device; the other is the minor device number, which identifies the different hardware using the same device driver. device. The major device number of the device file must match the major device number that the device driver applied when logging in to the device, otherwise the user process will not be able to access the device driver.

There are two main types of device files under the Linux operating system: one is a character device and the other is a block device. A character device is a device that performs I/O operations one by one in byte units. When a read or write request is made to a character device, the actual hardware I/O occurs immediately. Generally, the cache in the character device is available. No, and does not support random access. The block device uses a system memory as a buffer. When the user process makes a read or write request to the device, the driver first checks the contents of the buffer, and if the data in the buffer can satisfy the user's request, the corresponding data is returned. Otherwise, the corresponding request function is called to perform the actual I/O operation. The block device is mainly designed for slow devices such as disks, and its purpose is to avoid spending too much CPU time to wait for the completion of the operation. In general, PCI cards are usually character devices.

The main device number of all hardware devices that have been registered (that is, the driver has been loaded) can be obtained from the /proc/devices file. Use the mknod command to create a device file of the specified type and assign it the corresponding major and minor device numbers. For example, the following command:

[root@gary root]# mknod /dev/lp0 c 6 0

A character device with a major device number of 6 and a minor device number of 0 will be created. The file /dev/lp0. When the application makes a system call to a device file, the Linux kernel calls the corresponding driver according to the device type and the major device number of the device file, and enters the core state from the user state, and then the driver determines the device. The minor device number, and finally complete the operation of the corresponding hardware.

2. Device Driver Interface

The I/O subsystem in Linux provides a uniform standard device interface to other parts of the kernel, which is via include/linux/fs. The data structure file_operations in h is done:

struct file_operations {

struct module *owner;

loff_t (*llseek) (struct file *, loff_t, int) ;

ssize_t (*read) (struct file *, char *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char *, size_t, loff_t * );;

int (*readdir) (struct file *, void *, filldir_t);

unsigned int (*poll) (struct file *, struct poll_table_struct *);

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

int (*mmap) (struct file *, struct vm_area_struct *);

Int (*open) (struct inode *, struct file *);

int (*flush) (struct file *);

int (*release) (struct inode *, struct file *);

int (*fsync) ( Struct file *, struct dentry *, int datasync);

int (*fasync) (int, struct file *, int);

int (*lock) (struct file *, int , struct file_lock *);

ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);

ssize_t (*writev) (struct file *, Const struct iovec *, unsigned long, loff_t *);

ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

unsigned long (*get_unmapped_area)(struct file *, unsigned long,

unsigned long, unsigned long, unsigned long);

};

When the application makes a device file such as When open, close, read, write, etc., the Linux kernel will access the functions provided by the driver through the file_operations structure. For example, when an application performs a read operation on a device file, the kernel will call the read function in the file_operations structure.

Copyright © Windows knowledge All Rights Reserved