Linux 驅動程式的 I/O, #2: I/O 存取相關函數

jollen 發表於 December 20, 2006 10:57 PM

I/O 存取相關函數

要提到「I/O 處理」當然要整理 Linux 提供的相關函數,以下分 3 大類來整理:

1. I/O port
2. I/O memory
3. PCI configuration space
4. ioremap

I/O Port

以下是 Linux 提供最原始的 I/O port 存取函數:

˙ unsigned inb(unsigned port);
˙ unsigned inw(unsigned port);
˙ unsigned inl(unsigned port);
˙ void outb(unsigned char byte, unsigned port);
˙ void outw(unsigned short word, unsigned port);
˙ void outl(unsigned long word, unsigned port);

I/O Memory

以下是 Linux 提供最原始的 I/O memory 存取函數:

˙ unsigned readb(unsigned port);
˙ unsigned readw(unsigned port);
˙ unsigned readl(unsigned port);
˙ void writeb(unsigned char byte, unsigned port);
˙ void writew(unsigned short word, unsigned port);
˙ void writel(unsigned long word, unsigned port);

對於 I/O memory 的操作,Linux 也提供 memory copy 系列函數如下:

˙ memset_io(address, value, count);
˙ memcpy_fromio(dest, source, num);
˙ memcpy_toio(dest, source, num);

以上在「Linux 驅動程式觀念解析, #6: 依流程來實作 -- Physical Device Driver」介紹過一次,並且也搭配了一個簡單範例做說明,您可參考該文。

PCI Configuration Space

Linux 也提供讀寫 PCI configuration space(PCI BIOS)的函數:

˙ int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val);
˙ int pci_read_config_word(struct pci_dev *dev, int where, u16 *val);
˙ int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val);
˙ int pci_write_config_byte(struct pci_dev *dev, int where, u8 val);
˙ int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
˙ int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);

有些朋友可能看過開頭是 pcibios_* 的函數版本,「不過這是舊的函數,請勿再使用」。

ioremap()

這個 API 就重要到不行了,任何時候,Linux device driver 都「不能直接存取 physical address」。所以,「使用以上的 I/O 相關函數時,只能傳 virtual address,不能傳入 physical address」,ioremap() 就是用來將 physical address 對應到 virtual address 的 API。

小結

對於 I/O 函數的使用,應該在「深諳」Linux驅動程式架構與Linux作業系統原理的情況下使用,「單純的 kernel module + IO APIs」並不叫做 Linux 驅動程式,再更進一步的「kernel module + read/write/ioctl + IO APIs」也只是小聰明(編註),還是稱不上 Linux「驅動程式」。建構在作業系統裡的驅動程式,90% 都是在實作良好的機制與行為,因此「OS 原理與機制的研究」,才是正確的思考方向。與大家分享自己的心得,希望對您的學習有幫助。

編註:這是 Linux device driver 的「開始」但不是全部,也只是冰山一角。但是許多教育訓練機構的課程卻是以此為做為規劃方向,並不是很妥當。

Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw