io port / io memory

来源:互联网 发布:这样开淘宝网店 编辑:程序博客网 时间:2024/05/16 00:58

io port 的访问似乎不需要总线

9.2.1. I/O Port Allocation

As you might expect, you should not go off and start pounding on I/O ports without first ensuring that you have exclusive access to those ports. The kernel provides a registration interface that allows your driver to claim the ports it needs. The core function in that interface is request_region:

#include <linux/ioport.h>struct resource *request_region(unsigned long first, unsigned long n,                                 const char *name);

9.2.2. Manipulating I/O ports

After a driver has requested the range of I/O ports it needs to use in its activities, it must read and/or write to those ports. To this end, most hardware differentiates between 8-bit, 16-bit, and 32-bit ports. Usually you can't mix them like you normally do with system memory access.[2]

[2] Sometimes I/O ports are arranged like memory, and you can (for example) bind two 8-bit writes into a single 16-bit operation. This applies, for instance, to PC video boards. But generally, you can't count on this feature.

A C program, therefore, must call different functions to access different size ports. As suggested in the previous section, computer architectures that support only memory-mapped I/O registers fake port I/O by remapping port addresses to memory addresses, and the kernel hides the details from the driver in order to ease portability. The Linux kernel headers (specifically, the architecture-dependent header<asm/io.h>) define the following inline functions to access I/O ports:


unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);


而io memory 则需要

The way to access I/O memory depends on the computer architecture, bus, and device being used, although the principles are the same everywhere. The discussion in this chapter touches mainly on ISA and PCI memory, while trying to convey general information as well



Why linux can access pci devices without having to have a probe:

That is, the firmware initializes PCI hardware at system boot, mapping each region to a different address to avoid collisions.[2] The addresses to which these regions are currently mapped can be read from the configuration space, so the Linux driver can access its devices without probing. After reading the configuration registers, the driver can safely access its hardware.

三个地址空间:memory locations, I/O ports是给系统用的,需要probe ?  configuration registers 是geographical addressing,所以不需要probe, 可以通过这个地址空间来访问pci 设备内的register

The hardware circuitry of each peripheral board answers queries pertaining to three address spaces: memory locations, I/O ports, and configuration registers. The first two address spaces are shared by all the devices on the same PCI bus (i.e., when you access a memory location, all the devices on that PCI bus see the bus cycle at the same time). The configuration space, on the other hand, exploitsgeographical addressing. Configuration queries address only one slot at a time, so they never collide.

The PCI configuration space consists of 256 bytes for each device function (except for PCI Express devices, which have 4 KB of configuration space for each function), and the layout of the configuration registers is standardized.Four bytes of the configuration space hold a unique function ID, so the driver can identify its device by looking for the specific ID for that peripheral.[3] In summary, each device board is geographically addressed to retrieve its configuration registers; the information in those registers can then be used to perform normal I/O access, without the need for further geographic addressing.

[3] You'll find the ID of any device in its own hardware manual. A list is included in the filepci.ids, part of thepciutils package and the kernel sources; it doesn't pretend to be complete but just lists the most renowned vendors and devices. The kernel version of this file will not be included in future kernel series.

notice that the fourth bytes: 

Figure 12-2. The standardized PCI configuration registers



comment: in code: 

struct pci_device_id {
unsigned int vendor, device;
unsigned int subvendor, subdevice;
unsigned int class, class_mask;
unsigned long driver_data;
};

static struct pci_device_id pciidlist[] = {{0x8086, 0x08c7, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xFFFF00, CHIP_MDFLD_0130},}

It should be clear from this description that the main innovation of the PCI interface standard over ISA is the configuration address space. Therefore, in addition to the usual driver code, a PCI driver needs the ability to access the configuration space, in order to save itself from risky probing tasks.

最后一段讲了 pci跟isa 最大的不同,最先进的地方,就是这个configuration 地址空间。


原创粉丝点击