訪問記憶體過程小結

2022-04-16 11:32:52 字數 2547 閱讀 5821

本文總結一下,linux下面幾種訪問記憶體的方式方法。相關資料**自:linux 記憶體與i/o訪問

x86體系結構下,記憶體空間分為i/o空間和記憶體空間,i/o空間通過特定的指令in、out來訪問,記憶體空間採用mov等指令訪問。

arm體系結構下,記憶體空間和i/o空間統一劃分,他們在乙個位址空間內。

在處理器和真實的記憶體空間之間,還有mmu這一神奇的部件存在,它輔助作業系統進行記憶體管理,提供虛擬位址和實體地址的對映關係轉換、記憶體訪問許可權保護和cache快取控制等硬體功能,作業系統借助mmu,實現虛擬位址空間的管理,使得上層應用程式不必考慮真實實體地址大小,面對一片「虛擬」的邏輯位址空間。

在linux核心空間,kmalloc、__get_free_page,這兩個函式申請的記憶體空間在實體地址上都是連續的,vmalloc申請的記憶體空間在實體地址上不是連續的。

#define _ _pa(x)  ((unsigned long)(x)-page_offset)

extern inline unsigned long virt_to_phys(volatile void * address)

#define  _ _pa(x)      ((unsigned long)(x)+page_offset)

extern inline unsigned long virt_to_phys(volatile void * address)

return _ _pa (address);

通過ioremap函式將裝置所處的實體地址空間對映到虛擬位址空間

ioremap()原型:

void *ioremap(unsigned long offset, unsigned long size);

它返回乙個特殊的虛擬位址,用來訪問特定的實體地址頁面,我們可以通過c指標來訪問這些位址,

iounmap()原型:

void iounmap(void *addr);

它用來釋放通過ioremap對映的虛擬位址空間

通過mmap結合 /dev/mem 來直接對映物理記憶體空間,這種可以在應用程式態訪問核心態的東西

/dev/mem 是物理記憶體的全映象,可以用來訪問物理i/o裝置。通常只有root使用者對其有讀寫許可權

[note]:新核心版本限制了/dev/mem中的記憶體訪問介面,

/dev/kmem :kernel看到的虛擬記憶體全映象,可以用來訪問kernel的內容,檢視kernel變數,用作rootkit等

對於/dev/mem,我們可以把他當做乙個字元裝置,先open,再read或者write就行。 也可以直接通過命令來檢視和修改物理記憶體內容,這個命令就是hexedit

按tab鍵進入修改模式,修改內容以粗體顯示,按f2儲存內容,按ctrl+c退出。

下面的函式需要 sys/mman.h 標頭檔案支援。

1. void *mmap(void *stat,             //對映結果位址,通常設為null,表示系統自動選擇對映成功後的位址

size_t length,           //對映大小,以位元組為單位

int prot,                  // 對映區保護方式:可執行(prot_exec),可讀(prot_read),可寫(prot_write)

int flag,                  // 特性選項:map_shared(對對映區域的寫入寫回到fd中) map_private(對對映區域的寫入不寫回到fd)

int fd,                    // 指定對映的檔案描述符(本例中,為由open以可讀寫的方式開啟/dev/mem)

off_t offset             // 被對映的偏移量 ,表示從哪個檔案開始對映,一般設定為0,表示從頭開始對映。offset必須為頁大小的倍數(4k)

對映成功,返回對於的虛擬位址空間,對映失敗,返回map_failed,同時errno錯誤變數被設定。

2. void munmap(void *addr,size_t length )  // 釋放對映的虛擬記憶體空間 當呼叫程序終止時,該區域自動解除對映關係。關閉開啟的檔案描述符不會解除對映關係。

解除對映成功,munmap返回0,失敗返回-1,全域性errno被設定。

3. int  msync(void *addr,           //回寫對映開始位址

size_t  length,        // 回寫長度

int flags                // ms_async: 非同步呼叫,立即返回,回寫操作由系統管理

// ms_sync:同步呼叫,阻塞,直到回寫完成後才返回

msync將寫入共享對映區的資訊回寫到磁碟上,不使用它,在munmap呼叫之前,無法確保寫入對映區的內容真實寫入磁碟中。

回寫成功,返回0,失敗返回-1,同時設定全域性錯誤變數errno 。

technorati 標籤: 記憶體訪問

arm64記憶體訪問指令小結

如下指令,用在32bit arm處理器上面是沒有問題的,但是用在arm64時,就會出現下面這個data abort exception 對比手冊發現實際上64bit的str指令,當使用wt暫存器時,是按照64bit來訪問的,故將彙編 更改為如下,ok,成功點亮led led on mov x7,0x...

記憶體訪問衝突問題(非法記憶體訪問)

無獨有偶,我居然又碰上了同樣的問題。原因跟之前一樣,物件在記憶體中已經被銷毀,或者這個物件壓根就沒有被建立過。慢慢的查詢p screen在 被複製以及在 被銷毀,最有效的方法就是看函式呼叫棧。當我把斷點設定在p screen賦值語句的那一行時,發現還沒執行到斷點處就已經觸發異常了,當然還有一種可能就...

ios 記憶體小結

這是 看 書籍 objective c 高階程式設計 ios與os x多執行緒和記憶體管理 一書的隨記。除錯 1.檢視 autoreleasepool 池裡面的物件 extern void objc autoreleasepoolprint objc autoreleasepoolprint 上面的...