配置I/O埠

配置的意義是確保你有相關I/O埠的獨佔使用權。核心提供了一組註冊介面讓驅動程式用來存取所需要的I/O埠,其中最關鍵的是request_region():

#include <linux/ioport.h>

struct resource *request_region(unsigned long first,unsigned long n,const char *name);

此函式告訴核心,你想要使用的I/O埠範圍是從first開始的n個位址,name參數是裝置名稱。如果先前已有其他驅動程式搶先登記了該段範圍,則reguset_region()會傳回一個代表配置失敗的NULL,這表示你無權使用該範圍,這往往意味無法繼續工作,遇到這種現象,請查看/proc/ioports,這個紀錄了所有已經配置的I/O位址範圍的檔案。 將IO位址還給核心的函式:

void release_region(unsigned long start,unsigned long n);

檢查某段範圍內的IO位址是否被占用:

int check_region(unsigned long start,unsigned long n);

當被占用會傳回一個負值。

操作I/O埠

I/O位址資料傳輸位元有分8,16,32-bits三種寬度,因此對應不同的資料量,核心中<asm/io.h>定義了用來存取I/O埠的函式:

unsigned inb(unsigned port);
void outb(unsigned port);

讀寫1-byte(8-bits)埠,port可能是unsigned long或是unsigned short

unsigned inw(unsigned port);
void outw(unsigned port);

讀寫2-byte(16-bits)埠

unsigned inl(unsigned port);
void outl(unsigned port);

讀寫4-byte(32-bits)埠

字串操作

除了單次的I/O操作,有些處理器提供特殊指令,可以將一連串同等大小的bytes、words或是longs讀入、寫出到同一個I/O埠。這些就是所謂的字串指令,它們能以最快的速度來做到C語言迴圈的效果。以下列出各種字串操作模式:

void insb(unsigned port,void *addr,unsigned long count);
void outsb(unsigned port,void *addr,unsigned long count);

前者從port讀取count個位元組,並存放在addr位址上的記憶體,後者將addr位址上的count個位元組寫入port

void insw(unsigned port,void *addr,unsigned long count);
void outsw(unsigned port,void *addr,unsigned long count);

這為16-bits位元組操作

void insl(unsigned port,void *addr,unsigned long count);
void outsl(unsigned port,void *addr,unsigned long count);

此為32-bits位元組操作

results matching ""

    No results matching ""