Basic knowledge of Linux driver development

Source: Internet
Author: User
Tags ranges
One of the purposes of the device drivers (Device Driver) Operating System is to conceal the particularity of the hardware devices. For example, the virtual file system presents a unified attempt to install the file system, which is irrelevant to the underlying physical device. This chapter describes how Lin UX manages physical devices in the system. CPU is not the only smart device in the system. Every physical device is controlled by its own hardware. The keyboard, mouse, and serial port are controlled by the superio chip, the IDE disk is controlled by the IDE controller, and the SCSI disk is controlled by the SCSI controller. Each hardware controller consists of its own control and state controller (CSR). Different devices are different. The CSR of an adaptec 2940 SCSI controller is totally different from that of the NCR 810 SCSI controller. CSR is used to start and stop a device, initialize the device, and diagnose its problems. The code for managing these hardware controllers is not placed in every application, but at the core of Linux. These software pins that process or manage hardware controllers are used as device drivers. Linux core device drivers are essentially shared libraries for privileged low-level hardware control routines with resident memory. It is a feature of Linux device drivers that process the devices they manage. A basic feature of UNIX is that it abstracts the processing of devices. All hardware devices look like regular files: they can be opened, closed, and read/write using the same standard system calls as operating files. Each device in the system uses a special device file. For example, the first IDE hard disk in the system is represented by/dev/had. For block (Disk) and character devices, these device special files are created using the mknod command and described using the master (Major) and secondary (minor) device numbers. Network devices are also expressed in special device files, but they are created when Linux finds and initializes the network controllers in the system. All devices controlled by the same device driver are numbered by a common major device. The sub-device number is used to distinguish between different devices and their controllers. For example, different partitions of the primary IDE disk are numbered by a different sub-device. Therefore, for/dev/hda2, the primary device Number of the 2nd partition of the primary IDE disk is 3, and the secondary device number is 2. In Linux, the main device number table and some system tables (such as the character device table chrdevs) are used to call the special files of the device (such as installing a file system on a block device) maps to the device driver of the device. See fs/devices. c Linux support three types of hardware devices: character, block, and network. Character devices read and write directly without a buffer, such as the serial ports/dev/cua0 and/dev/cua1 of the system. A block device can only read and write data in multiples of one block (generally 512 bytes or 1024 bytes. Block devices access through buffer cache and can access them randomly. That is to say, any block can be read and written without considering where it is located. Block devices can access through special files of their devices, but more often, they are accessed through the file system. Only one block device supports one installed file system. Network devices are accessed through the BSD socket interface. The network subsystem is described in the network chapter (chapter 10th. Linux has many different device drivers (which is also one of the power of Linux), but they all have some general attributes: the kernel code device driver is similar to other code in the core, it is part of kenel and may seriously damage the system if an error occurs. A wrong driver may even destroy the system, damage the file system, and lose data. The kenel interfaces device driver must provide a standard interface to the Linux core or its subsystem. For example, the Terminal Driver provides a file I/O interface to the Linux core, and the SCSI Device Driver provides the SCSI device interface to the SCSI subsystem, interfaces for file I/O and Bu ffer cache are provided to the core. Kernel mechanisms and services device drivers use standard core services such as memory allocation, interrupt forwarding, and waiting queues to complete the work loadable Linux most device drivers can be loaded as core modules as needed, uninstall it when it is no longer needed. This makes the core very adaptive and efficient for system resources. The retriable Linux device driver can be built on the core. Which devices can be configured to the core during core compilation. Dynamic is started in the system. When each device starts program initialization, it looks for the hardware devices it manages. It does not matter if the device controlled by a device driver does not exist. At this time, the driver of this device is redundant and occupies a small amount of system memory, without causing harm. 8.1 poling and interrupts (polling and interruption) when each command is sent to the device, for example, "moving the reading head to the 42nd sector of a floppy disk", the device driver can choose how to determine whether the command is executed. The device driver can poll the device or interrupt the device. Polling a device usually means that it keeps reading its status register until the device status changes to indicate that it has completed the request. Because the device driver is a part of the core, if the driver is always polling, the core cannot run anything else before the device completes the request, causing heavy losses. Therefore, the polling device driver uses a system timer to allow the system to call a routine in the device driver later. This timer routine checks the command status, and the Linux floppy disk driver works like this. Polling using a timer is the best way to get close, and the more effective way is to use interruption. The Interrupt Device Driver issues a hardware interrupt when the hardware device it controls needs services. For example, an Ethernet device driver is interrupted when the device receives an Ethernet packet on the network. Linux core needs the ability to forward interruptions from hardware devices to the correct device driver. This is achieved by registering the interrupt it uses with the core by the device driver. It registers the address of the interrupt handler routine and the interrupt number it wants. You can use/proc/interrupts to see which interrupts are used by the device driver and how many times each type of interrupt is used: 0: 727432 timer 1: 20534 keyboard 2: 0 cascade 3: 79691 + Serial 4: 28258 + Serial 5: 1 sound blster 11: 20868 + aic7xxx 13: 1 math error 14: 247 + ide0 15: 170 + ide1 requests for resource interruptions occur at the time of driver initialization. Some interruptions in the system are fixed, which is a legacy of the ibm pc architecture. For example, the disk controller is always interrupted by 6. Other interruptions, such as PCI device interruptions, are dynamically allocated at startup. In this case, the device driver must first find the interrupt Number of the device it controls before requesting the interrupt (processing permission ). For PCI interruptions, Linux supports standard pci bios callbacks to determine device information in the system, including their IRQ. How an interrupt is forwarded to the CPU depends on the architecture. However, in most systems, interruptions are transmitted in a special mode, and other interruptions occur in the stop system. The device driver should do as little work as possible in its interrupt handling routine, so that the Linux core can end the interrupt and return to the place before the interrupt. Device drivers that need to do a lot of work after receiving the interruption can use the core bottom half handler or the task queue to sort the routines behind for future calls. 8.2 Direct Memory Access (DMA) when there is a small amount of data, it works quite well to transmit data to or through a device using a device driver that interrupts the driver. For example, a 9600 baud rate modem can transmit about one character every millisecond (1/1000 seconds. If the interruption delay occurs, it takes less time (for example, 2 ms) from the interruption of the hardware device to the start of calling the interrupt handler in the device driver ), therefore, data transmission is very small for the entire system image. The 9600 baud rate modem data can only occupy 0.002% of the CPU processing time. However, for high-speed devices, such as hard drive controllers or Ethernet devices, the data transmission rate is quite high. A scsi device can transmit up to 40 MB of information per second. Direct Memory Access, or DMA, is invented to solve this problem. A DMA controller allows the device to create tree data and system memory without the intervention of the processor. The isa dma controller of a PC consists of eight DMA channels, seven of which can be used for device drivers. Each DMA channel is associated with a 16-bit address register and a 16-bit count register ). In order to initialize a data transmission, the device driver needs to establish the address and count register of the DMA channel, plus the data transmission direction, read or write. When the transmission ends, the device interrupts the PC. In this way, when transmission occurs, the CPU can do other things. When using DMA, the device driver must be careful. First, all DMA controllers do not know the virtual memory. They can only access the physical memory in the system. Therefore, the memory required for DMA transmission must be contiguous blocks in the physical memory. This means that you cannot perform DMA access to the virtual address space of a process. However, you can also lock the physical process to the memory when performing the DMA Operation. Second, the DMA controller cannot access all the physical memory. The address register of the DMA channel indicates the first 16 bits of the DMA address, followed by the 8 bits from the page register ). This means that the DMA request is limited to 16 MB of memory at the bottom. DMA channels are scarce resources and only seven cannot be shared between device drivers. Like an interrupt, the device driver must be able to identify which DMA channel it can use. Like an interrupt, some devices have fixed DMA channels. For example, a software Drive Device always uses DMA Channel 2. Sometimes, the DMA channel of a device can be set with a jumper: Some Ethernet devices use this technology. Some more flexible devices can tell it (through their CSR) which DMA channel to use, then the device driver can simply find an available DMA channel. Linux uses the dma_chan Data Structure Vector table (one for each DMA channel) to track the usage of the DMA channel. The dma_chan data structure has only two Yu: A character pointer that describes the owner of the DMA channel, and a flag that shows whether the DMA channel is allocated. When you cat/proc/DMA, The dma_c Han vector table is displayed. 8.3 memory (memory) device drivers must use the memory with caution. Because they are part of the core of Linux, they cannot use virtual memory. Each time the device driver is running, it may have received an interrupt or scheduled but Tom half handler or task queue. The current process may change. The device driver cannot depend on a running special process. Like the rest of the core, the device driver uses a Data Structure to track the devices it controls. These data structures can be statically allocated in the Code part of the device driver, but this will make the core unnecessary increase and waste. Most device drivers allocate core, non-Paging memory to store their data. Linux core provides core memory allocation and release routines, which are used by the device driver. Core Memory is allocated based on the power of 2. For example, 128 or 512 bytes, even if the number of Device Driver requests is not so large. The number of bytes requested by the device driver is rounded up according to the size of the next block. This makes it easier to recycle the core memory, because smaller idle blocks can be combined into larger blocks. Linux requires more additional work when requesting the core memory. If the total number of idle memory is too small, physical pages need to be discarded or written to swap devices. Generally, Linux suspends the requester and places the process in a waiting queue until there is enough physical memory. Not all Device Drivers (or Linux core code) want this to happen, and the core memory allocation routine can request failure if the memory cannot be allocated immediately. If the device driver wishes to allocate memory for DMA access, it also needs to point out that the memory can be DMA. This is because the Linux core needs to understand which memory can be continuously used for DMA in the system, rather than the device driver. 8.4 interfacing device drivers with the kernel (device drivers and core interfaces) the Linux core must be able to work in a standard way. Each type of device drivers, including characters, blocks, and networks, provides common interfaces for the core to use when requesting their services. These general interfaces mean that the core can look at very different devices and their device drivers in a completely identical way. For example, the behavior of SCSI and IDE disks is very different, but the Linux core uses the same interface for them. Linux is very dynamic. Every time a Linux core is started, it may encounter different physical devices and thus require different device drivers. Linux allows you to include the device driver through the configuration script at the core build time. When these device drivers are initialized, they may not find any hardware they can control. Other drivers can be loaded as core modules as needed. To handle this dynamic nature of device drivers, device drivers register with the core during their initialization. Linux maintains a list of registered device drivers as part of the interfaces with these drivers. These lists include the pointer of a routine and the information of interfaces that support this type of device. 8.4.1 character devices (character device) character device. It is the simplest Linux Device and can be accessed like a file. The application uses standard system calls to open, read, write, and close a file, as if the device was a common file. Even the modem used by the PPP daemon connecting to a Linux system to access the Internet. When a character device is initialized, its device driver registers with the Linux core and adds a device_struct Data Structure entry to the chrdevs table. The identifier of the master device of the device (for example, for tty devices, it is 4) and used as the index of this vector table. The identifier of the primary device of a device is fixed. Each entry in the chrdevs vector table, a Devi ce_struct data structure, contains two elements: a pointer to the name of a registered device driver and a pointer to a group of file operations. This file operation is located in the character device driver of the device. Each operation processes specific file operations such as opening, reading, writing, and closing. The content of the character device in/proc/devices comes from the chrdevs vector table. For details, see include/Linux/major. h when a special character file representing a character device (for example,/dev/cua0) is opened, the core must do something to remove the file operation routine using the correct character device driver. Like common files or directories, each special file on a device is expressed by a vfs I node. The VFS inode of this special file (in fact, all the special files of the device) includes the major and minor identifier of the device. This vfs I node is created by the underlying File System (such as ext2) based on the actual file system when searching for special files on this device. For details, see fs/ext2/inode. c ext2_read_inode (). Each vfs I node is associated with a group of file operations, depending on the file system objects represented by the I node. No matter when a vfs I node represents a special character file is created, its file operations are set to the default operations of character devices. There is only one file operation: open operation. When an application opens a special file with this character, common open file operations use the device's primary device identifier as an index in the chrde vs vector table to retrieve the file operation block of this special device. It also creates a file data structure that describes the Special file of this character, so that its file operations point to the operations in the device driver. All file system operations of the application are mapped to the file operations of the character device. For details, see fs/devices. c chrdev_open () def_chr_fops 8.4.2 Block devices (Block devices) Block devices can also be accessed like files. This mechanism provides the correct file operation group for open block special files is very similar to that of character devices. Linux uses blkdevs to maintain registered block device files to the table. Like the chrdevs vector table, it uses the device's master device number as the index. Its entries are also the device_s truct data structure. Different from character devices, Block devices are classified. SCSI is one type, while IDE is another type. Class registers with the Linux core and provides file operations to the core. A device driver of a device type provides class-related interfaces to this type. For example, the SCSI device driver must provide interfaces to the SCSI subsystem so that the SCSI subsystem can provide file operations for such devices to the core. For details, see fs/devices. C each block device driver must provide common file operation interfaces and buffer cache interfaces. Each block Device Driver fills in its blk_dev_struct data structure in the blk_dev vector table. The index of this vector table is still the device's master device number. This blk_dev_struct data structure includes the address of a request routine and a pointer pointing to a list of request data structures, each of which expresses a request for the buffer cache to read and write a piece of data to the device. See Drivers/block/ll_rw_blk.c include/Linux/blkdev. h each time the buffer cache wants to read and write a piece of data to or from a registered device, it adds a request data structure in its blk_dev_struc. Figure 8.2 shows that each request has a pointer pointing to one or more buffer_head data structures, and each request is a read/write request. This buffer_head data structure is locked (buffer cache), and a process may be waiting for the blocking process in this buffer zone to complete. Each request structure is allocated from a static table and all_request table. If the request is added to an empty request list, the request queue is processed by calling the req uest function of the driver. Otherwise, the driver simply processes every request in the Request queue. Once the device driver completes a request, it must delete each buffer_head structure from the reques T structure, mark them as the latest, and then unlock. Unlocking buffer_head will wake up any process waiting for this blocking operation to complete. This example includes File Parsing: You must wait for the ext2 File System to read data blocks that include the next ext2 directory entry from the block device that includes the file system, this process will sleep in the buff_head queue of the directory entry to be included until the device driver wakes it up. The request data structure is marked as idle and can be used by another block request. 8.5 hard disks (hard disk) stores data on a rotating disk, providing a more permanent way to store data. In order to write data, a tiny head magnetization a tiny point on the disk surface. The head can be used to detect whether a specified particle is magnetized, so that data can be read. A disk drive consists of one or more disks, each of which is made of smooth glass or ceramics and covers the last layer of fine metal oxides. The disk is placed on a central axis and rotated at a stable speed. The rotation speed ranges from 3000 to 1000 rpm (RPM) based on different models ). The read/write head of a disk is responsible for reading and writing data. Each disk has one pair and each other. The read/write head does not have physical contact with the disk surface, but floats on a thin air cushion (100,000 points. The read/write head moves on the disk surface using a drive. All the heads are glued together and moved together on the disk surface. The surface of each disk is divided into multiple narrow concentric rings, called tracks ). Track 0 is the outermost track, and the highest numbered track is the track closest to the central axis. A cylinder is a combination of the same number channels. Therefore, all the 5th channels on each side of each disk are 5th cylinders. Because the number of cylinders is the same as the number of tracks, the disk size is often described by the cylinder. Each track is divided into sectors. One slice is the smallest data unit that can be read and written from the hard disk, that is, the disk block size. The slice size is usually 512 bytes, And the slice size is usually set during disk formatting. The size of a disk (geometry) is usually used to describe the number of cylinders, the number of magnetic heads, and the number of Fan partitions. For example, when Linux is started, describe my IDE disk: HDB: Conner peripherals 540 MB-cfs540a, 516 MB w/64kb cache, CHS = 1050/16/63 which means it consists of 1050 cylindrical (track), 16 heads (8 disks) and 63 sectors/track. For a 512-byte sector or block size, the disk capacity is 529200 kb. This is not in line with the declared 516 m storage capacity of the disk, because some sectors are used to store the partition information of the disk. Some disks can automatically find bad sectors and reindex them. Hard disks can be further divided into partitions. A partition is a group of sectors allocated for a specific purpose. Disk Partitions allow a disk to be used for several operating systems or multiple purposes. Most Linux systems on a single disk are divided into three partitions: one contains the DOS file system, the other ext2 file system, and the third is the swap partition. The partition of the hard disk is described in the Partition Table. Each entry describes the start and end positions of the partition with the head, sector, and cylindrical number. For DoS disks formatted with fdisk, there can be four primary disk partitions. Not all four entries in the partition table must be used. Fdisk supports three types of partitions: Primary partition, extended partition, and logical partition. An extended partition is not a real partition. It can contain any number of logical partitions. Extended partitions and logical partitions were invented to break through the limits of four primary partitions. Below is the output of fdisk of a disk with two primary partitions: Disk/dev/SDA: 64 heads, 32 sectors, 510 cylinders Units = cylinders of 2048*512 bytes device boot begin start end blocks ID system/dev/sda1 1 1 478 489456 83 Linux NATIVE/dev/sda2 479 479 510 82 Linux swap expert command (M for help): P Disk/dev/SDA: 64 heads, 32 sectors, 510 cylinders Nr af HD sec cyl start size Id 1 00 1 1 0 63 32 477 32 978912 83 2 00 0 1 478 63 32 509 978944 65536 82 3 00 0 0 0 0 0 0 00 4 00 0 0 0 0 0 0 0 00 it shows the first partition starting from the cylindrical or track 0, head 1 and fan area 1 until the cylinder 477, Sector 32 and head 63. Because a track consists of 32 sectors and 64 read/write heads, the cylinders of this partition are completely included. By default, fdisk alignment the partition on the boundary of the cylinder. It starts from the outermost cylinder (0) and is oriented toward the central axis, expanding 478 cylinder. 2nd partitions, swap partition, start with the next cylindrical (478) and expand to the innermost cylindrical disk. During initialization, Linux maps the hardware topology of the system. It identifies the number of hard disks in the system and the type of the hard disk. Linux also finds out how each disk is partitioned. These are all lists of gendisk data structures pointed to by the gendisk_head pointer list. For each disk subsystem, such as IDE, A gendisk data structure is generated during initialization to indicate the disks it finds. This process takes place at the same time as the file operations it registers for and adds its entries to the blk_dev data structure. Each gendisk data structure is composed of a unique master device number, which is the same as that of a special device. For example, the SCSI disk subsystem creates an independent gendisk entry ("SD") with the primary device number being 8 (the primary device Number of all SCSI disk devices ). Figure 8.3 shows two gendisk entries, the first is the SCSI disk subsystem, and the second is the IDE disk controller. Here is ide0, the main ide controller. Although the disk subsystem will create a corresponding gendisk entry during initialization, Linux is only used for partition check. Each disk subsystem must maintain its own data structure so that it can map the device's primary device number and secondary device number to the physical disk partition. No matter when a block device is read/written, whether it is through buffer cache or file operations, the core is based on it in a special block device file (for example,/dev/SD A2) the primary device number and secondary device number found in to direct the operation to the appropriate device. Is a device driver or subsystem that maps device numbers to real physical devices. 8.5.1 IDE disks (IDE disk) The most common disk in Linux today is the integrated disk electronic ). Like SCSI, IDE is a disk interface rather than an I/O bus. Each ide controller can support a maximum of two disks, one is the master and the other is the slave. The master and slave usually use jumper settings on the disk. The first ide controller in the system is called the primary ide controller, and the next is called the subordinate controller. The IDE can transmit data from/to the disk at 3.3 Mb/s. the maximum size of the IDE disk is 538 MB. The extended ide or Eide increases the maximum disk size to 8.6 GB, and the data transmission rate is as high as 16.6 Mb/s. IDE and Eide disks are cheaper than SCSI disks, and most modern PCs have one or more ide controllers on the motherboard. Linux names the IDE disk according to the order of the controller it discovers. The master disk on the master controller is/dev/h ad, and the slave disk is/dev/HDB. /Dev/HDC is the master disk on the IDE controller. The ID e subsystem registers the IDE controller with Linux instead of the disk. The primary identifier of the primary ide controller is 3, and the secondary ide controller is 22. This means that if a system has two ide controllers, there will be ide subsystem entries in index 3 and 22 in BLK _ Dev and blkdevs vector tables. The special files on the IDE disk reflect the numbers: the disk/dev/had and/dev/HDB are connected to the master ide controller, and the master device number is 3. The core uses the primary device identifier as the index. All file or buffer cache operations performed on the IDE subsystem of these special files are directed to the corresponding ide subsystem. When executing a request, the IDE subsystem determines which IDE disk the request is. To this end, the IDE subsystem uses the sub-device number in the device special file, which allows it to direct requests to the correct partition of the correct disk. /Dev/HDB, the device identifier of the slave IDE disk on the primary ide controller is (3, 64 ). The device identifier of its first partition (/dev/hdb1) is (3, 65 ). 8.5.2 initializing most of the history of the IDE subsystem (initializing the IDE subsystem) ibm pc has an IDE disk. During this period, the interfaces of these devices have changed. This makes the initialization process of the IDE subsystem more complex than it was when it first appeared. The maximum number of IDE controllers supported by Linux is 4. Each controller is represented by an ide_hwif_t data structure in the ide_hwifs vector table. Each ide_hwif_t data structure contains two ide_drive_t data structures, which indicate the master and slave ide drives that may be supported, respectively. During ide subsystem initialization, Linux first displays the disk information recorded in the system's CMOS memory. This kind of battery backup will not lose its content when the PC is shut down. The CMOS memory is actually running on the system's real-time clock device, whether your PC is on or off. The location of the CMOS memory is set by the system bios. It also tells the Linux System What ide controller and drive are found. Linux obtains the disk size (geometry) from the bios and uses this information to set the data structure of the drive's ide_hw if_t. Most modern PCS use a PCI chipset, such as Intel's 82430 VX chipset, including a PCI Eide controller. The IDE subsystem uses the pci bios callback to locate the PCI (e) ide controller in the system. Then, call the query routines of these chipsets. Once an IDE interface or controller is found, set its ide_hwif_t to reflect the controller and the above disk. During the operation, the IDE driver writes commands to the IDE command registers in the I/O memory space. The default I/o address of the control and status registers of the primary ide controller is 0x1f0-0x1f7. These addresses were previously agreed upon by ibm pc. The IDE driver registers each controller with the buffer cache and VFS of Linux and adds it to the blk_dev and blkdevs vector tables respectively. The IDE driver also requests proper interrupt control. Likewise, there are conventions for these interruptions. The primary ide controller is 14, and the secondary ide controller is 15. However, like all ide details, these can be changed with the core command line options. At startup, the IDE driver also adds a gendisk entry to the gendisk list for each found ide controller. This list will be used later to view the partition tables of all hard disks found at startup. The partition check code shows that each I de controller can control two IDE disks. 8.5.3 SCSI disks (SCSI disk) SCSI (Small Computer System Interface) bus is an effective point-to-point data bus with each bus supporting up to 8 devices, each host can have one or more. Each device must be uniquely identified and usually configured with a patch cord on the disk. Data can be transmitted synchronously or asynchronously between any two devices on the bus. data can be transmitted in 32-Bit Width at a speed of up to 40 MB/s. The SCSI bus can transmit data and status information between devices. transactions between the initiator and target involve up to eight different stages. You can determine the current stage through five signals on the SCSI bus. In these eight phases, bus free has no control over the bus and no transactions have occurred. Arbitration a scsi device attempts to gain control of the SCSI bus, which declares (assert) Its SCSI identifier on the address pin. The top-numbered SCSI identifier is successful. Selection a device successfully obtains control of the SCSI bus through arbitration, and now it must send signals to the SCSI target that it wants to send commands. It specifies the destination SCSI identifier on the address pin. The reselection SCSI device may be disconnected during request processing, and the target selects the initiator again. Not all SCSI devices support this phase. Command 6, 10, or 12-byte commands can be sent from the initiator to the target. Data in, data out at this stage, data is transmitted between the initiator and the target. Status completes all commands and enters this stage. Allow the target to send a status byte to the initiator, indicating success or failure. The additional information transmitted between the initiator and the target by message in and message out. The Linux SCSI subsystem consists of two basic elements, each of which is represented by a Data Structure: host, a SCSI host, a physical hardware, and a SCSI controller. The ncr810 pci scsi controller is an example of a SCSI host. If a Linux system has more than one SCSI controller of the same type, each instance is represented by a SCSI host. This means that a SCSI device driver may control more than one controller instance. SCSI host is usually the initiator of the SCSI command (initiato R ). Device SCSI devices are usually disks, but SCSI standards support a variety of types: tape, CD-ROM, and general (generic) SCSI devices. SCSI devices are usually the targets of SCSI commands. These devices must be treated differently. For example, removable media such as CD-ROM or tape, Linux needs to detect whether the media is taken out. Different disk types have different master device numbers, allowing Linux to direct block device requests to the appropriate SCSI type. Initializing the SCSI subsystem (initialize the SCSI subsystem) initialization of the SCSI subsystem is quite complex, reflecting the dynamic nature of the SCSI bus and devices. Linux initializes the SCSI subsystem at startup: it searches for the SCSI controller (SCSI host) in the system, detects every SCSI bus, and finds every device. Then initialize these devices so that the rest of the Linux core can be accessed through common files and buffer cache Block devices. This initialization process has four phases: first, Linux finds out which SCSI host adapter or controller has controllable hardware to which the core is established when the core is established. Each built-in SCSI host has a scsi_host_template entry in the buildin_scsi_hosts vector table. The scsi_host_template data structure includes the pointer of the routine, which can perform actions related to the SCSI host, such as detecting the s csi device attached to the SCSI host. These routines are called during the SCSI subsystem configuration and are part of the SCSI device drivers that support this host type. For each SCSI controller (with actual SCSI device adhesion), its scsi_host_template data structure is added to the scsi_hosts list, indicating a valid SCSI host. Each instance of the detected host type is represented by a SCSI _ host data structure in the scsi_hostlist. For example, if a system has two ncr810 pci scsi controllers, there will be two scsi_host entries in this list, one for each controller. The scsi_host_t emplate that each scsi_host points to indicates its device driver. Now every SCSI host is found, and the SCSI subsystem must find all SCSI devices on each host bus. The SCSI device number ranges from 0 to 7. Each device number or SCSI identifier is unique on the SCSI bus to which it is attached. SCSI identifiers are usually set using jumpers on the device. The SCSI initialization code sends the test_unit_ready command to each device to find every SCSI device on the SCSI bus. When a device responds, it sends an enquiry command to identify the device. This gives l inux the name and model and revision number of the vendor device. SCSI commands are represented by a scsi_cmnd data structure. These commands are passed to the device driver program by calling the device driver routine in the scsi_host_template data structure of the SCSI host. Each SCSI device is represented by a scsi_device data structure, and each one points to its parent scsi_host. All scsi_device data structures are added to the scsi_devices list. Figure 8.4 shows the relationship between the main data structure and other data structures. There are four SCSI device types: disk, tape, CD, and general (generic ). Each SCSI type is registered with the core and has different primary block device types. However, they are registered only when one or more specified SCSI device types are found. Each SCSI type, such as a SCSI disk, maintains its own device table. It uses these tables to direct core block operations (files or buffer caches) to the correct device driver or SCSI host. Each SCSI type is represented by a scsi_type_template data structure. It includes information about this type of SCSI device and the address of the routine that executes multiple tasks. The SCSI subsystem uses these templates to call the SCSI type routines of each SCSI device type. In other words, if the SCSI subsystem wants to attach a SCSI disk device, it will call a SCSI disk type routine. If one or more SCSI devices of a certain type are detected, the data structure of scsi_type_templates is added to the SCSI _ devicelist list. The final stage of SCSI subsystem Initialization is to call the complete function of each registered scsi_device_template. For SCSI disks, all SCSI disks are rotated and their disk sizes are recorded. It also adds 8.3 To The Link List of the disk that represents the increase of the gendisk data structure of all SCSI disks. Delivering block device requests (pass block Device Requests) Once Linux initializes the SCSI subsystem, the SCSI device can be used. Each valid SCSI device type is registered in the core, so Linux can direct block device requests to it. These requests may be executed through the buffer cache request of blk_dev or through the blkdevs file. Take a SCSI disk drive with one or more ext2 File System partitions as an example. How does the core Buffer request be directed to the correct SCSI disk when its ext2 partition is installed? Each request to read/write a piece of data from/to a SCSI disk partition adds a new request data structure to the current_request list of the SCSI disk in the blk_dev vector table. If the request list is being processed, the buffer cache does not need to be processed. Otherwise, the SCSI disk subsystem must process its request queue. Each SCSI disk in the system is represented by a scsi_disk data structure. They are stored in the rscsi_disks vector table and indexed using part of the sub-device Number of the SCSI disk partition. For example, the main device Number of/dev/sdb1 is 8 and the next device number is 17, so it is 1. The data structure of each scsi_dis k Includes a pointer to the scsi_device data structure of the device. Scsi_dev ice points to another scsi_host data structure that "owns it. The request data structure in the buffer cache is converted into the scsi_cmd data structure that describes the SCSI command to be sent to the SCSI device, and queued in the scsi_host data structure that indicates the device. Once appropriate data blocks are read/written, they are processed by their respective SCSI device drivers. 8.6 network devices (network device) A network device, as long as it is related to the Linux network subsystem, is a entity for sending and receiving data packets. It is usually a physical device, such as an Ethernet Card. However, some network devices are software-only, such as loopb ack devices, used to send data to themselves. Each network device is represented by a device data structure. The Network Device Driver registers the device it controls with Linux when the core starts network initialization. The device data structure includes the information of the device and the address of the function that allows a large number of supported network protocols to use the service of the device. Most of these functions are related to data transmission using this network device. The device uses a standard network support mechanism to transmit received data to the appropriate protocol layer. All network data (packets) transmitted and received are expressed in the SK _ buff data structure, which is a flexible data structure and allows the network protocol header to be easily added and deleted. The network protocol layer describes how to use network devices and how to use the sk_buff data structure to transmit data back and forth. This chapter focuses on the device data structure and how network devices are discovered and initialized. See include/Linux/netdevice. h device data structure includes the information of network devices: names are not like block and character devices, and their special files are created using the mknod command, special network device files appear naturally when the system's network device discovers and initializes them. Their names are standard, and each name represents its device type. Multiple devices of the same type are numbered from 0 to upward. Therefore, the Ethernet device numbers are/dev/eth0,/dev/eth1,/dev/eth2, and so on. Some common network devices are: /dev/ethn Ethernet device/dev/SLN slip device/dev/pppn PPP device/dev/LO loopback device bus information this is required by the device driver control device. IRQ is the interruption of device usage. Base address is the address of Device Control and Status Register in I/O memory. The DMA channel is the DMA channel number used by the network device. All this information is set during device initialization at startup. Interface flags describes the features and capabilities of this network device. Iff_up interface up, running the debug option of iff_broadcast device's broadcast address valid iff_debug device open iff_loopback this is a loopback device iff_pointtopoint this is a point-to-point connection (slip and PPP) iff_notrailers no network trailers iff_running allocates resources iff_noarp does not support ARP Protocol if_promisc devices in promiscuous mode. It receives all packets regardless of their addresses. Iff_allmulti receives all IP multicast frames iff_multicast can receive IP multicast frames protocal information each device describes how it can be used by the network protocol layer: MTU does not include the link layer header that needs to be added. This network can transmit the maximum package size. This maximum value is used for protocol layer such as IP to select a suitable package size for sending. The family displays the protocol families that the device supports. All Linux network devices support af_inet and the Internet address family. The type hardware interface type describes the media that the network device connects. Linux network devices support multiple media types. Including Ethernet, X.25, Token Ring, slip, PPP, and Apple localtalk. The addresses device data structure stores some IP addresses related to the network device, including the IP address packet queue. This is a sk_buff package queue, wait for the network device to transmit support functions each device provides a set of standard routines for the protocol layer to call, as part of the interface for the device link layer. Includes setting and frame transmission routines, as well as adding standard frame headers and collecting statistics. These statistics can be seen in ifcnfig 8.6.1 initializing network devices (initialize network device) network device drivers can be built into the Linux core like other Linux device drivers. Each possible network device is represented by a device data structure in the network device list pointed to by the dev_base list pointer. If you need device-related operations, the network layer calls one of the network device service routines (placed in the device data structure. However, in the initial stage, each device data structure only contains the address of the initialization or probe routine. The Network Driver must solve two problems. First, not all network device drivers built on Linux core will have control devices; second, Ethernet devices in the system are always called/dev/eth0,/dev/eth1, etc, no matter what the underlying device driver is. The "lost" network device problem is easy to solve. When you call the initialization routine of each network device, it returns a status that shows whether it has located an instance of the controller it drives. If the driver does not find any device, the entries in the device list directed by dev_base will be deleted. If the driver finds a device, it fills the rest of the device data structure with the device information and the address of the supported functions in the network device driver. The second problem is to dynamically allocate Ethernet devices to the special files of standard/dev/ethn devices in a more elegant way. There are eight standard entries in the device list: eth0, eth1 to eth7. The initialization routines of all entries are the same. It tries to establish drivers on each Ethernet device at the core until a device is found. When the driver finds its Ethernet device, it fills in its current ethn Devic e data structure. At this time, the network driver also needs to initialize the physical hardware it controls and find out the IRQ and DMA it uses. The driver may find several instances of the network device it controls. In this case, it occupies several/dev/ethn device data structures. Once all eight standard/dev/ethn instances are allocated, no more Ethernet devices will be detected.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.