小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

problems from dma_alloc_coherent - wilson的日志 - 網(wǎng)易博客

 jason zhai 2010-09-11
在項(xiàng)目驅(qū)動(dòng)過程中會經(jīng)常用到dma傳輸數(shù)據(jù),而dma需要的內(nèi)存有自己的特點(diǎn),一般認(rèn)為需要物理地址連續(xù),并且內(nèi)存是不可cache的,在linux內(nèi)核中提供一個(gè)供dma所需內(nèi)存的申請函數(shù)dma_alloc_coheren. 如下所述:
dma_alloc_coherent()

dma_alloc_coherent() -- 獲取物理頁,并將該物理頁的總線地址保存于dma_handle,返回該物理頁的虛擬地址

void *
dma_alloc_coherent(struct device *dev,        size_t size,
                   dma_addr_t    *dma_handle, gfp_t gfp)
{
    void *ret;
    if (!dev || *dev->dma_mask >= 0xffffffffUL)
        gfp &= ~GFP_DMA;
    ret = (void *)__get_free_pages(gfp, get_order(size)); //(1)
    if (ret) {
        memset(ret, 0, size);
        *dma_handle = virt_to_bus(ret);                   //(2)
    }
    return ret;
}

(1) 將size轉(zhuǎn)換成order, 即2^order
(2) 將虛擬地址ret轉(zhuǎn)換成總線地址

這個(gè)函數(shù)是一個(gè)平臺相關(guān)的函數(shù),以上是在x86平臺的實(shí)現(xiàn)細(xì)節(jié),從這里我們可以看到該函數(shù)返回值為linux 內(nèi)核線性地址,所以對于驅(qū)動(dòng)開發(fā)過程的mmap函數(shù)實(shí)現(xiàn)提供了便利。
但是在powerpc平臺卻不是這樣,筆者就曾經(jīng)遇到在將pci驅(qū)動(dòng)從x86平臺移植到powerpc平臺時(shí)出現(xiàn)問題。
首先我們來先看一下兩個(gè)平臺對于dma內(nèi)存的處理。
x86:
     linux內(nèi)存區(qū)域分為DMA區(qū)域,Normal內(nèi)存區(qū)域與高端內(nèi)存區(qū)域,高端內(nèi)存區(qū)域?yàn)楫?dāng)物理內(nèi)存高于768M時(shí)使用,一般DMA區(qū)域?yàn)?6M,這段空 間由操作系統(tǒng)預(yù)留。DMA區(qū)域與Normal區(qū)域全部使用線性映射,采用邏輯地址使用,高端內(nèi)存使用內(nèi)核虛擬地址。其中內(nèi)核空間的分部為:
物理區(qū)--8M隔離--vmalloc區(qū)--8k隔離--4M的高端映射區(qū)--固定映射區(qū)--128k

powerpc:
    本節(jié)采用freescale的mpc5121芯片為例,內(nèi)核沒有采用Normal內(nèi)存區(qū)域,只使用ZONE_DMA和ZONE_HIMEM兩種類型的空 間,其中ZONE_DMA存放低端內(nèi)存, ZONE_HIMEN存放高端內(nèi)存,整個(gè)內(nèi)存不在采用邏輯地址這一概念。所以基于邏輯地址的操作沒有可移植性。

下面看下具體的區(qū)別:
void *  __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
{
          //物理空間頁的申請
          page = alloc_pages(gfp, order);
        
         //對物理空間進(jìn)行清零cache
         {
                       unsigned long kaddr = (unsigned long)page_address(page);                
                       memset(page_address(page), 0, size);
                       flush_dcache_range(kaddr, kaddr + size);
          }

         //申請?zhí)摂M空間
         c = vm_region_alloc(&consistent_head, size,   gfp & 
                                     ~(__GFP_DMA | __GFP_HIGHMEM));

       //實(shí)現(xiàn)虛擬地址與物理地址映射
       if (c) {
                 unsigned long vaddr = c->vm_start;
                 pte_t *pte = consistent_pte + CONSISTENT_OFFSET(vaddr);
                 struct page *end = page + (1 << order);

                 split_page(page, order);

                 /*
                  * Set the "dma handle"
                  */
                 *handle = page_to_bus(page);

                do {
                         BUG_ON(!pte_none(*pte));

                         SetPageReserved(page);
                         set_pte_at(&init_mm, vaddr,
                                   pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL)));
                         page++;
                         pte++;
                         vaddr += PAGE_SIZE;
                 } while (size -= PAGE_SIZE);

     // 返回值為內(nèi)核虛擬地址。
      return (void *)c->vm_start

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多