Linux设备驱动程序学习(十)——PCI驱动程序
??前面介紹的是最底層的硬件控制,這部分將介紹高級(jí)總線架構(gòu)的一些綜述,總線由電氣接口和編程接口夠成。下面將重點(diǎn)介紹PCI總線的編程接口以及對(duì)應(yīng)的內(nèi)核函數(shù)。
PCI(外圍設(shè)備互聯(lián))接口
??PCI總線是當(dāng)今普遍使用在桌面以及更大型計(jì)算機(jī)上的外設(shè)總線,而且該總線是內(nèi)核中得到最好支持的總線。盡管許多計(jì)算機(jī)用戶將PCI看成是一種布置電子線路的方式,但實(shí)際上它是一組完整的規(guī)范,定義了計(jì)算機(jī)的各個(gè)不同部分之間該如何交互。
??PCI規(guī)范涵蓋了與計(jì)算機(jī)接口相關(guān)的大部分問(wèn)題。這里詳細(xì)介紹PCI驅(qū)動(dòng)程序如何尋找其硬件和獲得對(duì)它的訪問(wèn)。
??PCI架構(gòu)的三個(gè)主要目標(biāo):
- 獲得在計(jì)算機(jī)和外設(shè)之間傳輸數(shù)據(jù)時(shí)更好的性能;
- 盡可能的平臺(tái)無(wú)關(guān);
- 簡(jiǎn)化往系統(tǒng)中添加和刪除外設(shè)的工作。
PCI總線與配置空間
??PCI 總線體系結(jié)構(gòu)是一種層次式的體系結(jié)構(gòu)。在這種層次式體系結(jié)構(gòu)中,PCI 橋設(shè)備占據(jù)著重要的地位,它將父總線與子總線連接在一起,從而使整個(gè)系統(tǒng)看起來(lái)像一顆倒置的樹型結(jié)構(gòu)。樹的頂端是系統(tǒng)的 CPU,它通過(guò)一個(gè)較為特殊的 PCI 橋設(shè)備——Host/PCI 橋設(shè)備與根 PCI 總線連接起來(lái)。
??作為一種特殊的 PCI 設(shè)備,PCI 橋包括以下幾種:
- Host/PCI 橋:用于連接 CPU 與 PCI 根總線,第 1 個(gè)根總線的編號(hào)為0,內(nèi)存控制器也通常被集成到 Host/PCI 橋設(shè)備芯片中,橋通常也被稱為“北橋芯片組(North Bridge Chipset)”。
- PCI/ISA 橋:用于連接舊的 ISA 總線。通常,PCI 中的類似i8359A 中斷控制器這樣的設(shè)備也會(huì)被集成到 PCI/ISA 橋設(shè)備中,因此,PCI/I稱為“南橋芯片組(South Bridge Chipset)”。
- PCI-to-PCI 橋:用于連接 PCI 主總線(primary bus)與次總線(sPCI 橋所處的 PCI 總線稱為“主總線”(即次總線的父總線),橋設(shè)備所線稱為“次總線”(即主總線的子總線)。
??在 Linux 系統(tǒng)中,PCI 總線用 pci_bus 來(lái)描述,這個(gè)結(jié)構(gòu)體記錄了本 PCI 總線的信息以及本 PCI 總線的父總線、子總線、橋設(shè)備信息,這個(gè)結(jié)構(gòu)體的定義:
struct pci_bus{struct list_head node; /* 鏈表元素 node */struct pci_bus * parent; /*指向該 PCI 總線的父總線,即 PCI 橋所在的總線 */struct list_head children; /* 描述了這條 PCI 總線的子總線鏈表的表頭 */struct list_head devices; /* 描述了這條 PCI 總線的邏輯設(shè)備鏈表的表頭 */struct pci_dev * self; /* 指向引出這條 PCI 總線的橋設(shè)備的 pci_dev 結(jié)構(gòu) */struct resource * resource[PCI_BUS_NUM_RESOURCES];/* 指向應(yīng)路由到這條 PCI 總線的地址空間資源 */struct pci_ops * ops; /* 這條 PCI 總線所使用的配置空間訪問(wèn)函數(shù) */void *sysdata; /* 指向系統(tǒng)特定的擴(kuò)展數(shù)據(jù) */struct proc_dir_entry * procdir; /*該 PCI 總線在/proc/bus/pci 中對(duì)應(yīng)目錄項(xiàng)*/unsigned char number; /* 這條 PCI 總線的總線編號(hào) */16 unsigned char primary; /* 橋設(shè)備的主總線 */unsigned char secondary; /* PCI 總線的橋設(shè)備的次總線號(hào) */18 unsigned char subordinate; /*PCI 總線的下屬 PCI 總線的總線編號(hào)最大值*/19 char name[48];unsigned short bridge_ctl;unsigned short pad2;struct device * bridge;struct class_device class_dev;struct bin_attribute * legacy_io;struct bin_attribute * legacy_mem;};??系統(tǒng)中當(dāng)前存在的所有根總線都通過(guò)其 pci_bus 結(jié)構(gòu)體中的 node 成員鏈接成一條全局的根總線鏈表,其表頭由 list 類型的全局變量 pci_root_buses 來(lái)描述。而根總線下面的所有下級(jí)總線則都通過(guò)其 pci_bus 結(jié)構(gòu)體中的 node 成員鏈接到其父總線的children 鏈表中。這樣,通過(guò)這兩種 PCI 總線鏈表,Linux 內(nèi)核就將所有的 pci_bus 結(jié)構(gòu)體以一種倒置樹的方式組織起來(lái)。
PCI設(shè)備
??在 Linux 系統(tǒng)中,所有種類的 PCI 設(shè)備都可以用 pci_dev 結(jié)構(gòu)體來(lái)描述,由于一個(gè) PCI 接口卡上可能包含多個(gè)功能模塊,每個(gè)功能被當(dāng)作一個(gè)獨(dú)立的邏輯設(shè)備,因此,每一個(gè) PCI 功能,即 PCI 邏輯設(shè)備都唯一地對(duì)應(yīng)一個(gè) pci_dev 設(shè)備描述符。該結(jié)構(gòu)體為:
struct pci_dev{struct list_head global_list; /* 全局鏈表元素 */struct list_head bus_list; /* 總線設(shè)備鏈表元素 */struct pci_bus * bus; /* 這個(gè) PCI 設(shè)備所在的 PCI 總線的 pci_bus 結(jié)構(gòu) */struct pci_bus * subordinate; /* 指向這個(gè) PCI 設(shè)備所橋接的下級(jí)總線 */void *sysdata; /* 指向一片特定于系統(tǒng)的擴(kuò)展數(shù)據(jù) */struct proc_dir_entry * procent; /* 該 PCI 設(shè)備在/proc/bus/pci 中對(duì)應(yīng)的目錄項(xiàng) */unsigned int devfn; /* 這個(gè) PCI 設(shè)備的設(shè)備功能號(hào) */unsigned short vendor; /* PCI 設(shè)備的廠商 ID*/unsigned short device; /* PCI 設(shè)備的設(shè)備 ID */unsigned short subsystem_vendor; /* PCI 設(shè)備的子系統(tǒng)廠商 ID */unsigned short subsystem_device; /* PCI 設(shè)備的子系統(tǒng)設(shè)備 ID */unsigned int class; /* 32 位的無(wú)符號(hào)整數(shù),表示該 PCI 設(shè)備的類別, bit[7∶0]為編程接口,bit[15∶8]為子類別代碼,bit[23∶16]為基類別代碼,bit[31∶24]無(wú)意義 */u8 hdr_type; /* PCI 配置空間頭部的類型 */u8 rom_base_reg; /* 表示 PCI 配置空間中的 ROM 基地址寄存器在 PCI 配置空間中的位置 */struct pci_driver * driver; /* 指向這個(gè) PCI 設(shè)備所對(duì)應(yīng)的驅(qū)動(dòng) pci_driver結(jié)構(gòu) */u64 dma_mask; /* 該設(shè)備支持的總線地址位掩碼,通常是 0xffffffff */pci_power_t current_state; /* 當(dāng)前的操作狀態(tài) */struct device dev; /* 通用的設(shè)備接口 */ /* 定義這個(gè) PCI 設(shè)備與哪些設(shè)備相兼容 */unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];int cfg_size; /* 配置空間大小 */unsigned int irq;struct resource resource[DEVICE_COUNT_RESOURCE];/*表示該設(shè)備可能用到的資源,包括:I/O 端口區(qū)域、設(shè)備內(nèi)存地址區(qū)域以及擴(kuò)展 ROM 地址區(qū)域 */unsigned int transparent : 1; /* 透明 PCI 橋 */unsigned int multifunction : 1; /* 多功能設(shè)備 *//* keep track of device state */unsigned int is_enabled : 1; /* pci_enable_device 已經(jīng)被調(diào)用? */unsigned int is_busmaster : 1; /* 設(shè)備是主設(shè)備? */unsigned int no_msi : 1; /* 設(shè)備可不使用 msi? */u32 saved_config_space[16]; /* 掛起事保存的配置空間 */struct bin_attribute * rom_attr; /* sysfs ROM 入口的屬性描述 */int rom_attr_enabled;struct bin_attribute * res_attr[DEVICE_COUNT_RESOURCE]; /*資源的sysfs 文件*/};??在 Linux 系統(tǒng)中,所有的 PCI 設(shè)備都通過(guò)其 pci_dev 結(jié)構(gòu)體中的 global_list 成員鏈接一條全局 PCI 設(shè)備鏈表pci_devices。另外,同屬一條 PCI 總線上的所有 PCI 設(shè)備也通過(guò)其 pci_dev 結(jié)構(gòu)體中的 bus_list 成員鏈接成一個(gè)屬于這條 PCI 總線的總線設(shè)備鏈表,表頭則由該 PCI 總線的 pci_bus 結(jié)構(gòu)中的 devices 成員所定義。
PCI配置空間訪問(wèn)
??PCI設(shè)備上有三種地址空間:PCI的I/O空間、PCI的存儲(chǔ)空間和PCI的配置空間。CPU可以訪問(wèn)PCI設(shè)備上的所有地址空間,其中I/O空間和存儲(chǔ)空間提供給設(shè)備驅(qū)動(dòng)程序使用,而配置空間則由Linux內(nèi)核中的PCI初始化代碼使用,這些代碼用于配置 PCI 設(shè)備,比如中斷號(hào)以及 I/O 或內(nèi)存基地址
PCI 規(guī)范定義了 3 種類型的 PCI 配置空間頭部,其中 type 0 用于標(biāo)準(zhǔn)的 PCI 設(shè)備,type 1 用于 PCI 橋,type 2 用于 PCI CardBus 橋:
??pci_bus 結(jié)構(gòu)體中的 pci_ops 類型成員指針 ops 指向該 PCI 總線所使用的配置空間訪問(wèn)操作的具體實(shí)現(xiàn),pci_ops 結(jié)構(gòu)體的定義:
struct pci_ops{int(*read) (struct pci_bus * bus, unsigned int devfn, int where, int size, u32 * val); //讀配置空間int(*write) (struct pci_bus * bus, unsigned int devfn, int where, int size, u32 val); //寫配置空間};??read()和 write()成員函數(shù)中的 size 表示訪問(wèn)的是字節(jié)、2字節(jié)還是4字節(jié),對(duì)于write()而言,val 是要寫入的值;對(duì)于 read()而言,val 是要返回的讀取到的值的指針。通過(guò) bus 參數(shù)的成員以及 devfn 可以定位相應(yīng) PCI 總線上相應(yīng) PCI 邏輯設(shè)備的配置空間。在 Linux 設(shè)備驅(qū)動(dòng)中,可用如下一組函數(shù)來(lái)訪問(wèn)配置空間:
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); //讀字節(jié) int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); //讀字 int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val); //讀雙字 int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val); //寫字節(jié) int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 val); //寫字 int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 val); //寫雙字PCI設(shè)備驅(qū)動(dòng)結(jié)構(gòu)
??從本質(zhì)上講 PCI 只是一種總線,具體的 PCI 設(shè)備可以是字符設(shè)備、網(wǎng)絡(luò)設(shè)備、USB主機(jī)控制器等,因此,一個(gè)通過(guò) PCI 總線與系統(tǒng)連接的設(shè)備的驅(qū)動(dòng)至少包含以下兩部分:
- PCI 設(shè)備驅(qū)動(dòng)
- 設(shè)備本身的驅(qū)動(dòng)
??PCI 驅(qū)動(dòng)只是為了輔助設(shè)備本身的驅(qū)動(dòng),它不是目的,只是手段,PCI 設(shè)備本身含有雙重以上的身份。
pci_driver結(jié)構(gòu)體
??在 Linux 內(nèi)核中,用 pci_driver 結(jié)構(gòu)體來(lái)定義 PCI 驅(qū)動(dòng),該結(jié)構(gòu)體中包含了 PCI設(shè)備的探測(cè)/移除、掛起/恢復(fù)等函數(shù),其定義如下:
struct pci_driver{struct list_head node;char *name;struct module * owner;const struct pci_device_id * id_table; /*不能為 NULL,以便 probe 函數(shù)調(diào)用*//* 新設(shè)備添加 */int(*probe) (struct pci_dev * dev, const struct pci_device_id * id);void(*remove) (struct pci_dev * dev); /* 設(shè)備移出 */int(*suspend) (struct pci_dev * dev, pm_message_t state); /* 設(shè)備掛起 */int(*resume) (struct pci_dev * dev); /* 設(shè)備喚醒 *//* 使能喚醒事件 */int(*enable_wake) (struct pci_dev * dev, pci_power_t state, int enable);void(*shutdown) (struct pci_dev * dev);struct device_driver driver;struct pci_dynids dynids;};??對(duì) pci_driver 的注冊(cè)和注銷通過(guò)如下函數(shù)來(lái)實(shí)現(xiàn):
int pci_register_driver(struct pci_driver *driver); //注冊(cè) void pci_unregister_driver(struct pci_driver *driver); //銷毀??pci_driver 的 probe()函數(shù)要完成 PCI 設(shè)備的初始化及其設(shè)備本身身份(字符、TTY、網(wǎng)絡(luò)等)驅(qū)動(dòng)的注冊(cè)。當(dāng) Linux 內(nèi)核啟動(dòng)并完成對(duì)所有 PCI 設(shè)備進(jìn)行掃描、登錄和分配資源等初始化操作的同時(shí),會(huì)建立起系統(tǒng)中所有 PCI 設(shè)備的拓?fù)浣Y(jié)構(gòu),probe()函數(shù)將負(fù)責(zé)硬件的探測(cè)工作并保存配置信息。
pci_driver_id結(jié)構(gòu)體
??在 PCI 設(shè)備驅(qū)動(dòng)中,也需要定義一個(gè) pci_device_id 結(jié)構(gòu)體數(shù)組并導(dǎo)出到用戶空間,使熱插拔和模塊裝載系統(tǒng)知道驅(qū)動(dòng)模塊所針對(duì)的硬件設(shè)備。pci_device_id結(jié)構(gòu)體的定義:
struct pci_device_id { __u32 vendor, device; /* 廠商和設(shè)備 ID或 PCI_ANY_ID*/ __u32 subvendor, subdevice; /* 子系統(tǒng) ID 或 PCI_ANY_ID */ __u32 class, class_mask; /* (類、子類、prog-if) 三元組 */ kernel_ulong_t driver_data; /* 驅(qū)動(dòng)私有數(shù)據(jù) */ };??pci_device_id 結(jié)構(gòu)體數(shù)組使用宏 MODULE_DEVICE_TABLE 導(dǎo)出到用戶空間:
static struct pci_device_id netdrv_pci_tbl[] = { {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NETDRV_CB }, {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },{0,} } MODULE_DEVICE_TABLE (pci, netdrv_pci_tbl);PCI驅(qū)動(dòng)設(shè)備程序的實(shí)現(xiàn)
??在用模塊方式實(shí)現(xiàn)PCI設(shè)備驅(qū)動(dòng)程序時(shí),通常至少要實(shí)現(xiàn)以下幾個(gè)部分:初始化設(shè)備模塊、設(shè)備打開(kāi)模塊、數(shù)據(jù)讀寫和控制模塊、中斷處理模塊、設(shè)備釋放模塊、設(shè)備卸載模塊,下面是一個(gè)典型的PCI設(shè)備驅(qū)動(dòng)程序的基本框架:
/* 指明該驅(qū)動(dòng)程序適用于哪一些 PCI 設(shè)備 */ static struct pci_device_id xxx_pci_tbl [] __initdata = {{PCI_VENDOR_ID_DEMO, PCI_DEVICE_ID_DEMO,PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEMO},{0,} }; MODULE_DEVICE_TABLE(pci, xxx_pci_tbl); module_init(xxx_init_module); module_exit(xxx_cleanup_module); /* 中斷處理函數(shù) */static void xxx_interrupt(int irq, void * dev_id, struct pt_regs * regs){ /*PC的中斷資源比較有限,只有0~15的中斷號(hào),因此大部分外部設(shè)備都是以共享的形式申請(qǐng)中斷號(hào)的。當(dāng)中斷發(fā)生的時(shí)候,中斷處理程序首先負(fù)責(zé)對(duì)中斷進(jìn)行識(shí)別,然后再做進(jìn)一步的處理。*/}/* 字符設(shè)備 file_operations open 成員函數(shù) */static int xxx_open(struct inode * inode, struct file * file){/* 在這個(gè)模塊里主要實(shí)現(xiàn)申請(qǐng)中斷、檢查讀寫模式以及申請(qǐng)對(duì)設(shè)備的控制權(quán)等。在申請(qǐng)控制權(quán)的時(shí)候,非阻塞方式遇忙返回,否則進(jìn)程主動(dòng)接受調(diào)度,進(jìn)入睡眠狀態(tài),等待其它進(jìn)程釋放對(duì)設(shè)備的控制權(quán)。*/request_irq(xxx_irq, &xxx_interrupt, ...));...} /* 字符設(shè)備 file_operations ioctl 成員函數(shù) */static int xxx_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){...}/* 字符設(shè)備 file_operations read、write、mmap 等成員函數(shù) *//* 設(shè)備文件操作接口 ,PCI設(shè)備驅(qū)動(dòng)程序可以通過(guò)xxx_fops 結(jié)構(gòu)中的函數(shù)xxx_ioctl( ),向應(yīng)用程序提供對(duì)硬件進(jìn)行控制的接口。*/static struct file_operations xxx_fops = {owner:THIS_MODULE, /* xxx_fops 所屬的設(shè)備模塊 */read:xxx_read, /* 讀設(shè)備操作*/write:xxx_write, /* 寫設(shè)備操作*/ioctl:xxx_ioctl, /* 控制設(shè)備操作*/mmap:xxx_mmap, /* 內(nèi)存重映射操作*/open:xxx_open, /* 打開(kāi)設(shè)備操作*/release:xxx_release /* 釋放設(shè)備操作*/};/* pci_driver 的 probe 成員函數(shù)probe探測(cè)例程將負(fù)責(zé)完成對(duì)硬件的檢測(cè)工作*/static int _ _init xxx_probe(struct pci_dev * pci_dev, const struct pci_device_id * pci_id){pci_enable_device(pci_dev); //啟動(dòng) PCI 設(shè)備 /* 讀取 PCI 配置信息 */Iobase = pci_resource_start(pci_dev, 1);... pci_set_master(pci_dev); //設(shè)置成總線主 DMA 模式 pci_request_regions(pci_dev); //申請(qǐng) I/O 資源 /* 注冊(cè)字符設(shè)備 */cdev_init(xxx_cdev, &xxx_fops);register_chrdev_region(xxx_dev_no, 1, ...);cdev_add(xxx_cdev);return 0;}/* pci_driver 的 remove 成員函數(shù) */static int _ _init xxx_release(struct pci_dev * pdev){pci_release_regions(pdev); //釋放 I/O 資源pci_disable_device(pdev); //禁止 PCI 設(shè)備unregister_chrdev_region(xxx_dev_no, 1); //釋放占用的設(shè)備號(hào)cdev_del(&xxx_dev.cdev); //注銷字符設(shè)備... return 0;}/* 設(shè)備模塊信息 */static struct pci_driver xxx_pci_driver ={name:xxx_MODULE_NAME, /* 設(shè)備模塊名稱 */id_table:xxx_pci_tbl, /* 能夠驅(qū)動(dòng)的設(shè)備列表 */probe:xxx_probe, /* 查找并初始化設(shè)備 */remove:xxx_remove /* 卸載設(shè)備模塊 */};??在Linux系統(tǒng)下,想要完成對(duì)一個(gè)PCI設(shè)備的初始化,需要完成以下工作:
- 檢查PCI總線是否被Linux內(nèi)核支持;
- 檢查設(shè)備是否插在總線插槽上,如果在的話則保存它所占用的插槽的位置等信息。
- 讀出配置頭中的信息提供給驅(qū)動(dòng)程序使用。
??當(dāng)Linux內(nèi)核啟動(dòng)并完成對(duì)所有PCI設(shè)備進(jìn)行掃描、登錄和分配資源等初始化操作的同時(shí),會(huì)建立起系統(tǒng)中所有PCI設(shè)備的拓?fù)浣Y(jié)構(gòu):
??假設(shè)用樹來(lái)表示PCI總線,那么樹根就是主機(jī)/PCI橋,樹葉就是具體的PCI設(shè)備,樹葉與樹枝通過(guò)pci_driver連接,而樹葉本身的驅(qū)動(dòng),讀寫、控制樹葉則需要通過(guò)其樹葉設(shè)備本身所屬類設(shè)備驅(qū)動(dòng)來(lái)完成。
ISA
??ISA總線在設(shè)計(jì)上相當(dāng)陳舊而且其差勁的性能臭名昭著,但是在支持老主板而速度不是很重要的時(shí)候,ISA比PCI要更有優(yōu)勢(shì)。
??一個(gè)ISA設(shè)備可配備有I/O端口,內(nèi)存區(qū)域以及中斷線:
- 盡管 x86 處理器支持 64 KB I/O 端口內(nèi)存(即處理器有 16 條地址線), 一些老 PC 硬件僅解碼最低的 10 位地址線,這限制可用的地址空間為 1024 個(gè)端口。
- 如果 I/O 端口的可用性被限制, 內(nèi)存存取更加麻煩. 一個(gè) ISA 設(shè)備可只使用 640KB 到 1 MB 之間的內(nèi)存范圍和 15 MB 和 16MB 之間的范圍給 I/O 寄存器和設(shè)備控制。
- 對(duì) ISA 設(shè)備板第 3 個(gè)可用資源是中斷線. 一個(gè)有限數(shù)目的中斷線被連接到 ISA 總線, 并且它們由所有接口板共享. 結(jié)果是, 如果設(shè)備不被正確配置, 它們可能發(fā)現(xiàn)它們自己在使用同一個(gè)中斷線。
ISA編程
??對(duì)于編程, 內(nèi)核中沒(méi)有特別的幫助來(lái)易于存取 ISA 設(shè)備(像對(duì) PCI 那樣有). 你可使用的唯一工具是 I/O 端口和 IRQ 線的注冊(cè), 只能通過(guò)中斷處理來(lái)實(shí)現(xiàn), 驅(qū)動(dòng)可探測(cè) I/O 端口, 并且中斷線必須被自動(dòng)探測(cè), 這要通過(guò)"自動(dòng)探測(cè) IRQ 號(hào)"技術(shù)來(lái)實(shí)現(xiàn)。
其它PC總線
?? PCI 和 ISA 是在 PC 世界中最常用的外設(shè)接口, 但是它們不是唯一的. 這里簡(jiǎn)單介紹一下 PC 市場(chǎng)上的其他總線的特性:
MCA總線
??微通道結(jié)構(gòu)(MCA)是,用在 PS/2 計(jì)算機(jī)和一些筆記本電腦的IBM 標(biāo)準(zhǔn). 在硬件層次上, 微通道比 ISA 有更多特性. 它支持多主 DMA, 32-位地址和數(shù)據(jù)線, 共享中斷線, 和地理式尋址來(lái)存取每塊板的配置寄存器. 這樣的寄存器被稱為可編程選項(xiàng)選擇(POS), 但是它們沒(méi)有 PCI 寄存器的全部特點(diǎn). Linux 對(duì) 微通道的支持包括輸出給模塊的函數(shù)。
EISA總線
??擴(kuò)展 ISA (EISA) 總線是一個(gè)對(duì) ISA 的 32-位 擴(kuò)展, 帶有一個(gè)兼容的接口連接器; ISA 設(shè)備板可被插入一個(gè) EISA 連接器. 增加的線在 ISA 接觸之下被連接.
VLB總線
??另一個(gè)對(duì) ISA 的擴(kuò)展是 VESA Local Bus(VLB) 接口總線, 它擴(kuò)展了 ISA 連接器, 通過(guò)添加第 3 個(gè)知道長(zhǎng)度的槽位。一個(gè)設(shè)備可只插入這個(gè)額外的連接器(不用插入 2 個(gè)關(guān)聯(lián)的 ISA 連接器), 因?yàn)?VLB 槽位從 ISA 連接器復(fù)制了所有的重要信號(hào). 這樣"獨(dú)立"的 VLB 外設(shè)不使用 ISA 槽位是少見(jiàn)的, 因?yàn)榇蟛糠衷O(shè)備需要伸到后面板, 使它們的外部連接器是可用的。
??VESA 總線比 EISA , MCA, 和 PCI 總線在它的能力方面更加限制, 并且正在從市場(chǎng)上消失. 沒(méi)有特殊的內(nèi)核支持位 VLB 而存在。
總結(jié)
以上是生活随笔為你收集整理的Linux设备驱动程序学习(十)——PCI驱动程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 卫星传输链路需求分析和参数调整
- 下一篇: LINUX centos下查看CPU、主