2013-03-21 159 views

回答

0

你能告訴我們你正在使用的內核版本和CPU架構/類型嗎?一般來說,如果要映射到的特定虛擬地址與內核虛擬地址(例如0xC0000000)不重疊,並且您的設備正在使用的物理地址與系統內存物理地址範圍不重疊,則可以使用低級函數(如果沒有,則可以使用匯編語言在內核啓動期間直接設置MMU TLB條目)設置MMU TLB條目,以便在內核啓動期間將特定地址映射到特定虛擬地址。我可以提供一個基於2.6.10內核版本和Freescale PowerPC CPU的例子,有一個函數io_block_mapping來完成你想要的任務。

+0

我使用內核3.0與ARM/omap拱。 我掛鉤了內核啓動時間(使用「pure_initcall」宏)以使用memblock_remove函數保留這個物理地址,所以我知道它是免費的。 – yygg 2013-03-21 11:51:33

0

好的,這是我目前的解決方案。要映射phys_addrvirt_addr我使用此代碼:

page = pfn_to_page(virt_addr >> PAGE_SHIFT); 
pte = get_locked_pte(&init_mm, phys_addr, &ptl); 
set_pte_at(&init_mm, phys_addr, pte, mk_pte(page, VM_READ | VM_WRITE | VM_EXEC)); 
spin_unlock(ptl); 
flush_tlb_all(); 

一些explenations:我用的是pfn_to_page FUNC得到對應我virt_addr的頁面結構。我得到頁表項(pte)與get_locked_pte函數,它需要與想要的pte相對應的物理地址和一個未經初始化的自旋鎖(ptl)。然後,我實際使用set_pte_at func和mk_pte宏映射頁面,解鎖自旋鎖並刷新tlb緩存。

這種解決方案似乎工作得很好,雖然它不能在上下文切換中倖存下來。

相關問題