Linux下對IO內存的訪問

1.引言

1.1文檔目的
本文檔描述IO內存的概念和訪問流程。

1.2背景

1.3參考資料
名稱 類型 作者 備註
Linux設備驅動開發詳解:基於最新的Linux4.0內核 書籍 宋寶華 第11章
國嵌內核驅動深入班5-1-2(硬件訪問) 視頻 謝老師

2.幾個概念

2.1 IO空間與內存空間
在X86處理器才存在IO空間,是相對於內存空間的概念。目前大多數嵌入式處理器(如ARM、PowerPC等)並不提供IO空間。所以內存空間是必須的,IO空間是可選的。嵌入式開發只關心內存空間即可。
IO空間和內存空間是彼此獨立的地址空間,在32位的X86處理器中,IO空間大小爲64K ,內存空間爲4G。

2.2 IO端口和IO內存
設備通常會提供一組寄存器開控制設備、讀寫設備和獲取設備狀態,既控制寄存器、數據寄存器和狀態寄存器。這些寄存器可能位於IO空間,也可能位於內存空間中。
當位於IO空間,稱爲IO端口;當位於內存空間時,對應的內存空間稱爲IO內存。

3. IO端口和IO內存的訪問

Linux是支持嵌入式處理器,也支持X86處理器,所以Linux支持IO空間(IO端口)和內存空間(IO內存)的訪問,只是API不同而已。

3.1 IO端口的訪問
前面說過了,嵌入式開發不關心IO空間,所以也不關心IO端口的訪問。這裏不詳述。

3.2 IO內存的訪問
IO內存的訪問,在設備驅動開發中,用的非常多的。比如我在ZYNQ平臺項目中,操作FPGA的寄存器。FPGA與ARM共享的內存區域,中間的一段用做寄存器的控制。FPGA看做是ZYNQ的一個外設,掛在內存空間。知道物理地址後,對地址進行映射操作即可。具體的IO空間操作流程如下圖3.2.1所示。
在這裏插入圖片描述
圖3.2.1 IO內存訪問步驟

項目中用到的例子如下。

static int __init fpga_init(void)
{
    int i = 0, ret;

    printk(KERN_DEBUG "fpga_init...\n");

    if (!request_mem_region(FPGA_CTRL_ADDR, FPGA_REG_SIZE, "fpga_comm")) {
        printk(KERN_ERR "Request mem region failed!\n");
        ret = -EBUSY;
        goto request_mem_region_fail;
    }

    g_fpga_reg_base = ioremap_nocache(FPGA_CTRL_ADDR, FPGA_REG_SIZE);
    if (unlikely(!g_fpga_reg_base)) {
        printk(KERN_ERR "Failed mapping fpga_ctrl phy address at %lu\n",
                (unsigned long)FPGA_CTRL_ADDR);
        ret = -ENOMEM;
        goto ioremap_nocache_fail;
    }

    printk(KERN_DEBUG "fpga_init ok...\n");
    return 0;
dma_alloc_coherent_fail:
    iounmap(g_fpga_reg_base);
ioremap_nocache_fail:
    release_mem_region(FPGA_CTRL_ADDR, FPGA_REG_SIZE);
    return ret;

3.2.1 mmap訪問
在驅動中訪問,可以按上面ioremap的方式。如果在應用層進行訪問。就可以mmap的方式實現啦。這種方式,在實際使用中,也比較常見,上面提到的ZYNQ的例子,同樣可以在用戶空間用mmap對物理地址進行映射。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章