一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Linux內(nèi)核開(kāi)發(fā)之內(nèi)存與I/O訪問(wèn)(二)

 看風(fēng)景D人 2014-07-19

“小濤哥,咱們說(shuō)Linux設(shè)備驅(qū)動(dòng)程序說(shuō)了那么久,怎么從來(lái)不說(shuō)實(shí)際設(shè)備呢,頂多就說(shuō)了下內(nèi)存,總感覺(jué)驅(qū)動(dòng)程序是和設(shè)備分離的,怎么關(guān)聯(lián)起來(lái)..”小王思索著。

“不錯(cuò),這也正是這次講課的內(nèi)容,設(shè)備I/O端口與I/O內(nèi)存的訪問(wèn)”我啊,禁不住拍拍她的頭。

  對(duì)于一塊實(shí)際的設(shè)備而言,通常會(huì)提供一組寄存器來(lái)用于控制設(shè)備,讀寫(xiě)設(shè)備和獲取設(shè)備狀態(tài),也就是我們常說(shuō)的控制寄存器,數(shù)據(jù)寄存器和狀態(tài)寄存器。這些寄存器可能位于I/O空間(這時(shí)叫做I/O端口),也可能位于內(nèi)存空間(對(duì)應(yīng)的內(nèi)存空間被成為I/O內(nèi)存)。在Linux中提供了一系列的I/O端口和I/O內(nèi)存操作的接口如下:

  1)I/O端口操作:在Linux設(shè)備驅(qū)動(dòng)中,應(yīng)使用Linux內(nèi)核提供的函數(shù)來(lái)訪問(wèn)定位于I/O空間的端口,包括一下幾種:

   *讀寫(xiě)字節(jié)端口(8位寬)

     unsigned inb(unsigned port);【讀】          voi outb(unsigned char byte, unsigned port);【寫(xiě)】

   *讀寫(xiě)字端口(16位寬)

     unsigned inw(unsigned port);【讀】          voi outw(unsigned short word, unsigned port);【寫(xiě)】

   *讀寫(xiě)長(zhǎng)字端口(32位寬)

     unsigned inl(unsigned port);【讀】          voi outl(unsigned longword, unsigned port);【寫(xiě)】

   *讀寫(xiě)一串字節(jié)

     unsigned insb(unsigned port, void *addr, unsigned long count);【讀】      voi outsb(unsigned port, void *addr, unsigned long count);【寫(xiě)】

   *讀寫(xiě)一串字 

     unsigned insw(unsigned port, void *addr,unsigned long count);【讀】      voi outsb(unsigned port, void *addr, unsigned long count);【寫(xiě)】

   *讀寫(xiě)一串長(zhǎng)字

     unsigned insl(unsigned port, void * addr, unsigned long count);【讀】      voi outsb(unsigned port, void *addr, unsigned long count);【寫(xiě)】

    說(shuō)明:上述各函數(shù)中I/O端口port的類型長(zhǎng)度依賴與具體的硬件平臺(tái),所以只是寫(xiě)出了unsigned

  2)I/O內(nèi)存:在內(nèi)核中訪問(wèn)I/O內(nèi)存之前,需首先使用ioremap()函數(shù)將設(shè)備所處的物理地址映射到虛擬地址。

   *ioremap()原型:void *ioremap(unsigned long offset, unsigned long size);

     它返回一個(gè)特殊的虛擬地址,該地址可用來(lái)存取特定的物理地址范圍。用它返回的虛擬地址應(yīng)該使用iounmap()函數(shù)釋放。

   *iounmap()原型:void iounmap(void *addr);

   現(xiàn)在,有了物理地址鎖映射出來(lái)的虛擬地址后,我們就可以通過(guò)c指針來(lái)直接訪問(wèn)這些地址,但Linux內(nèi)核也提供了一組函數(shù)來(lái)完成這中虛擬地址的讀寫(xiě)。如下

   *讀IO內(nèi)存

     unsigned int ioread8(void *addr);      unsigned int ioread16(void *addr);     unsigned int ioread32(void *addr);  與之對(duì)應(yīng)的較早版本是:

     unsigned readb(address);                unsigned readw(address);                 unsigned readl(address);  這些在2.6的內(nèi)核中依然可以使用。

   *寫(xiě)IO內(nèi)存

     void iowrite8(u8 value,void *addr);  void iowrite16(u16 value, void *addr);   void iowrite32(u32 value, void *addr);  與之對(duì)應(yīng)的較早版本是:

     void writeb(unsigned value, address); void writew(unsigned value,address);  void writel(unsigned value,address);  2.6的內(nèi)核中依然可以使用。

   *讀一串IO內(nèi)存                                                                          *寫(xiě)一串IO內(nèi)存

     void ioread8_rep(void *addr, void *buf, unsigned long count);       void iowrite8_rep(void *addr, void *buf, unsigned long count);

     void ioread16_rep(void *addr, void *buf, unsigned long count);     void iowrite8_rep(void *addr, void *buf, unsigned long count);

     void ioread32_rep(void *addr, void *buf, unsigned long count);     void iowrite8_rep(void *addr, void *buf, unsigned long count);

   *復(fù)制IO內(nèi)存

     void memcpy_fromio(void *dest, void *source, unsigned int count);

     void memcpy_toio(void *dest, void *source, unsigned int count);

   *設(shè)置IO內(nèi)存

     void *ioport_map(unsigned long port, unsigned int count);

  3)把IO端口映射到內(nèi)存空間

     void *ioport_map(unsigned long port, unsigned int count);   通過(guò)這個(gè)函數(shù),可以把port開(kāi)始的count個(gè)連續(xù)的IO端口重映射為一段“內(nèi)存空間”。然后

                                                                                     就可以在其返回的地址上向訪問(wèn)IO內(nèi)存一樣訪問(wèn)這些端口,當(dāng)不再需要這種映射時(shí),調(diào)用:

     void ioport_unmap(void *addr);                                      來(lái)撤銷這種映射

  4)IO端口申請(qǐng)

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

     這個(gè)函數(shù)向內(nèi)核申請(qǐng)n個(gè)端口,這些端口從first開(kāi)始,name參數(shù)為設(shè)備的名稱,成功返回非NULL.一旦申請(qǐng)端口使用完成后,應(yīng)當(dāng)使用:

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

  5)IO內(nèi)存申請(qǐng)

    struct resource *request_mem_region(unsigned long start, unsigned long len, char *name);

    這個(gè)函數(shù)向內(nèi)核申請(qǐng)n個(gè)內(nèi)存,這些地址從first開(kāi)始,name為設(shè)備的名稱,成功返回非NULL,一旦申請(qǐng)的內(nèi)存使用完成后,應(yīng)當(dāng)使用:

    void release_mem_region() ;          來(lái)釋放歸回給系統(tǒng)。需要說(shuō)明的是這兩個(gè)函數(shù)也不是必須的,但建議使用。  

6)通過(guò)以上的基礎(chǔ),我們就可以歸納出設(shè)備驅(qū)動(dòng)訪問(wèn)IO端口和IO內(nèi)存的步驟。

   一種方法是:直接使用IO端口操作函數(shù):在設(shè)備打開(kāi)或驅(qū)動(dòng)模塊被加載時(shí)申請(qǐng)IO端口區(qū)域,之后使用inb(),outb()等進(jìn)行端口訪問(wèn),最后在設(shè)備關(guān)閉或驅(qū)動(dòng)被卸載時(shí)釋放IO端口范圍。流程如下:

   123

   另外一種途徑是:將IO端口映射為內(nèi)存進(jìn)行訪問(wèn),在設(shè)備打開(kāi)或驅(qū)動(dòng)模塊被加載時(shí),申請(qǐng)IO端口區(qū)域并使用ioport_map()映射到內(nèi)存,之后使用IO內(nèi)存的函數(shù)進(jìn)行端口訪問(wèn),最后,在設(shè)備關(guān)閉或驅(qū)動(dòng)模塊被卸載時(shí)釋放IO端口并釋放映射,流程如下:

   456

  上邊是IO端口的訪問(wèn)方法,至于IO內(nèi)存的訪問(wèn)方法是:首先調(diào)用request_mem_region()申請(qǐng)資源,接著將寄存器地址通過(guò)ioremap()映射到內(nèi)核空間的虛擬地址,之后就可以Linux設(shè)備訪問(wèn)編程接口訪問(wèn)這些寄存器了,訪問(wèn)完成后,使用ioremap()對(duì)申請(qǐng)的虛擬地址進(jìn)行釋放,并釋放release_mem_region()申請(qǐng)的IO內(nèi)存資源。

流程如下:

   789

 

“小王,感覺(jué)怎么樣呢, 我是盡最大努力了哈”我說(shuō)。

“可以,可以,感覺(jué)挺好,我覺(jué)得哈,你要是多畫(huà)圖,我就沒(méi)問(wèn)題,就像上邊三個(gè)圖一樣”小王調(diào)皮的說(shuō)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日本东京热视频一区二区三区| 亚洲国产av在线视频| 欧美色婷婷综合狠狠爱| 国产熟女一区二区三区四区| 欧美一区二区三区高潮菊竹| 黄色美女日本的美女日人| 中文字幕乱码一区二区三区四区| 日本一本不卡免费视频| 99少妇偷拍视频在线| 又色又爽又无遮挡的视频| 久久热九九这里只有精品| av在线免费观看一区二区三区| 在线观看欧美视频一区| 麻豆在线观看一区二区| 日韩国产亚洲一区二区三区| 午夜激情视频一区二区| 国产在线一区中文字幕| 亚洲国产精品久久琪琪| 日韩高清中文字幕亚洲| 国产精品欧美一区二区三区不卡 | 欧洲一区二区三区蜜桃| 国产在线一区二区免费| 国产一区二区三区免费福利| 色哟哟在线免费一区二区三区| 色狠狠一区二区三区香蕉蜜桃| 国产农村妇女成人精品| 国产内射在线激情一区| 福利新区一区二区人口| 亚洲一区在线观看蜜桃| 欧美人妻盗摄日韩偷拍| 国产日产欧美精品大秀| 空之色水之色在线播放| 中文字幕一区二区久久综合| 午夜精品在线观看视频午夜| 丁香六月婷婷基地伊人| 国产一区二区不卡在线播放| 亚洲欧美日韩在线中文字幕| 亚洲熟女诱惑一区二区| 午夜国产精品福利在线观看| 人妻乱近亲奸中文字幕| 欧美日韩亚洲国产综合网|