這一周主要看了陳老師的記憶體管理例項,感覺理解的很有限,例項**的**如下:http://home.lupaworld.com/home-space-uid-26540-do-blog-id-230202.html
師姐把這個例項拆分成了四個部分, 第一部分比較簡單,根據
vm_area_struct
結構體中的
vma_next
指標來完成當前程序虛存區的遍歷,列印當前程序的
vma ,並且列印
vma 的標誌,標誌對應可讀、可寫、可執行,我們還可以通過當前程序的
task_struct
結構中的
comm
和pid
成員來列印出它的名稱和
pid 號。第二部分的主要功能是通過呼叫
find_vma()
函式來查詢隨意乙個虛位址對應的
vma ,這個函式主要是將虛位址與
vma 的起始與結束位址相比較,如果正好在起止位址之間的話就正好找到了對應的
vma ,函式執行過程中用到了
vm_area_struct
結構體中的
rb_node
結點,這是採用了紅黑樹演算法,這是一種自平衡二叉查詢樹,看了一些介紹但不太懂,如果查詢到了對應的
vma 則列印它的起止位址和標誌。第三部分的第乙個函式主要是根據
vma 和其中的虛位址來查詢它對應的物理頁,**採用了四級目錄的表示方法,分別對應
pgd_t
頁全域性目錄項、
pud_t
頁上級目錄項、
pmd_t
頁中間目錄項、
pte_t
頁表項,採用四級目錄主要是為了在
64 位系統中使用,
64 位系統中只用了
48 位
(9 +9 +
9 +9 +
12) 來表示,函式中順序的呼叫了相應的
offset
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
,其中(mm)->pgd
是獲得頁目錄的基位址,
pgd_index(address)
#define pgd_index(address) (((address) >> pgdir_shift) & (ptrs_per_pgd - 1))
, pgdir_shift
為39,就是將
address
左移39
位獲得高
9 位。又如:
#define pud_offset(pgd, start) (pgd)
,這個產生頁上級目錄對應的線性位址,
#define pmd_offset(dir,addr) ((pmd_t *) pud_page_vaddr(*(dir)) + (((addr) >> pmd_shift) & (ptrs_per_pmd - 1)))
,這個就看不懂了,到頁表時呼叫了
pfn_to_page
巨集,這個巨集也看不懂。下面乙個函式是根據頁表,求出某個虛位址所在的頁,並可以轉換成對應的實體地址,其中主要的兩句是
kernel_addr = page_address(page)
,kernel_addr += addr & ~page_mask;
第一句先求得虛位址對應物理頁面的起始位址,第二句將起始位址加上頁內偏移量,其中
page_mask
為4k,這樣就將虛位址轉換成實體地址了。第四部分的功能主要是向
vma 中寫入資料,先找到虛位址對應的
vma ,並判斷它的標誌是否可寫,然後便可寫入相應的資料了。
這四個部分如果要整合成乙個完整的模組**還要加上一些其他的部分,並且對
vma 的操作要加上互斥訊號量,這個訊號量在
mm_struct
中定義為
mmap_sem
,再加上實現各種功能的操作函式後這個例項的架構基本上就定下來了,主要使用了
memcmp(buf, "", n),
函式來控制對於於哪種功能,用於列出
vma 只要使用
memcmp(buf, "listvma", 7)
,查詢vma 除了使用
memcmp(buf, "findvma", 7)
外還要用使用
sscanf()
函式來輸入虛位址,後面的幾個功能也要進行相應的處理,再加上模組的註冊和許可證後這個模組便基本上完成了。
記憶體管理幾個程式例項
void getmemory char p,int num void test void 解析 getmemory str,100 傳的是str的值 null 所以分配記憶體的時候是對str值操作,不是對它的位址的操作。所以strcpy呼叫時,str值仍為null,並未malloc到記憶體。mall...
學習EtherCAT的感想
個人覺得 把ethercat的相關資料粗略的看一遍。然後找個寫得比較詳細的伺服驅動器手冊研究,最好結合相應的伺服驅動器 我看的是松下的手冊和山洋的 在學習ethercat的時候,twincat是必須要學習的。twincat軟體其功能強大,可以寫plc程式,可以寫圖形化介面,可以觀察波形等等。初次學習...
C 的boost學習 記憶體管理
boost庫的記憶體處理 智慧型指標 1,scoped ptr 不允許拷貝,賦值,只能在被宣告的作用域中使用,不需要使用delete釋放資源,自動釋放資源,可以獲得與原始指標同樣的速度。include include using namespace std void usagescopedptr c...