Design of PCI driver based on Linux Platform (3)

Source: Internet
Author: User
Article title: Linux-based PCI device driver design (3 ). Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
2.4 access to I/O and memory space
The configuration item PCI_BASE_ADDRESS_0 to PCI_BASE_ADDRESS_5 indicates the six IP address segments of the PCI peripherals (the section here refers to a pci ip address range). each segment can be composed of memory or I/O locations, or does not exist at all. Because I/O space on the PC is already quite crowded, and some processors (such as Alpha) do not have I/O space, therefore, most devices use a memory segment to replace their I/O ports.
The I/O space defined by PCI is a 32-bit address space. if the device uses a 64-bit address bus, therefore, it can use two consecutive PCI_BASE_ADDRESS registers in 64-bit memory space for each segment to declare the segment.
Then, we can use the function mentioned above to read and write the segment address, for example:
Pcibios_read_config_dword (bus, fun, PCI_BASE_ADDRESS_0, & port );
Read the address indicated by PCI_BASE_ADDRESS_0 to the port.
Pcibios_write_config_dword (bus, fun, PCI_BASE_ADDRESS_3, val );
Write the val value to PCI_BASE_ADDRESS_3.
How to access the I/O port?
If you have obtained the I/O port address, you can use the function defined in the Linux kernel header file to access the I/O port:
Unsigned char inb (unsigned short port );
Void outb (unsigned char byte, unsigned short port );
Read and write eight-bit ports by byte.
Unsigned short inw (unsigned short port );
Void outw (unsigned short word, unsigned short port );
Read and write 16-bit ports by word width.
Unsigned long inl (unsigned short port );
Void outl (unsigned long word, unsigned short port );
Read and write 32-bit ports by double-word.
Note that the port parameter is defined as unsigned short on the x86 platform, but unsigned long on the Alpha platform.
Chapter 3 available kernel modules:
3.1 Linux kernel and driver
In Linux, several concurrent processes execute different tasks. Each process may have access to system resources. The kernel is a whole piece of executable code that processes all such requests. The kernel can be divided into the following parts: Process Management, memory management, file system, device control, and network.
Linux has a good feature, that is, the kernel code can be extended through the loading module, that is, the system function can be added at any time. The PCI device driver discussed in this article is actually a module loaded into the kernel.
Most of the users studying Linux kernels around the world are writing device drivers. Although each driver is different and you need to know the specific details of your device, many of the principles and basic technical skills of these device drivers are the same.
When writing drivers, programmers should pay attention to the following issues: different users have different requirements. when programmers write kernel code to access hardware, they cannot force users to adopt certain policies. The device driver should only handle the hardware and leave the hardware to the application. We can look at the driver we have written in this way: it is the software between the application layer and the actual device. Programmers can make different drivers provide different capabilities, and even the same device can provide different capabilities, as long as they use different drivers.
3.2 modules and applications
3.2.1 Differences between kernel modules and applications
An application completes a task from start to end. a module is a code block that dynamically connects to the core at any time after the system starts. it can be deleted and detached from the core when the system no longer needs them. The init_module () (Module entry point) is called when a module is loaded. Its task is to prepare for calling the function of the module in the future. The second entry point of the module is cleanup_module, it is called only when the module is downloaded. Being able to uninstall is one of the excellent features of modularization, which can reduce the development time of program developers: The driver can be tested without having to take a long time on/off each time.
There is another difference between kernel programming and application programming, that is, the consequences of errors are different: during application development, segment violations are harmless, the debugger can be used to easily track errors that cause problems. However, kernel failure is fatal. even if the entire system is not crashed, the current process may not continue to run.
When it comes to the differences between kernel modules and applications, you must pay attention to the "namespace pollution" problem: when there are many functions and global variables, their names are no longer meaningful enough to easily distinguish each other. When writing an application, the programmer must spend a lot of energy remembering some "reserved" names and searching for new unique names for new symbols. When writing the kernel code, if the "namespace pollution" problem occurs, it is simply intolerable for programmers, because even the smallest module is connected to the entire kernel. To prevent such problems, you can declare all the symbols you have defined as static. In addition, you can declare a symbol table to avoid using static declaration for all symbols.
3.2.2 User space and kernel space
The operating system should provide a computer hardware consistent view for the program. at the same time, the operating system has independent operations of the processing program, and prevent unauthorized access to resources. This requires the CPU to have a protection mechanism that prevents system software from interfering with application software, which can be implemented by each modern processor. The solution is to implement different operation modes (or levels) within the CPU. different levels have different permissions, and some operations cannot be used at the lowest level, the program code can only be switched from one level to another. In Linux, the execution state is the highest level (also known as "administrator state") and the lowest level (also known as "user state "), they correspond to "kernel space" and "user space" respectively ". The module runs in the "kernel space", while the application runs in the "user space.
3.3 Basic structure of the module
The kernel module must contain at least two functions: init_module and cleanup_module. The first function is called when the module is added to the kernel. The second function is called when the module is deleted. Generally, init_module registers all the new functions provided by the module to the kernel, that is, the new functions that can be used by applications. The task of the cleanup_module function is to clear everything init_module has done, so that this module is safely uninstalled.
  
  
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.