歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 內核中的物理內存分配函數kernel api解析

內核中的物理內存分配函數kernel api解析

日期:2017/2/28 17:48:53   编辑:Linux教程

在網上查資料時看到幾篇介紹 linux driver 編寫的文章,其中提到 kmalloc()與 __get_free_page()返回地址的問題,我們都知道 kmalloc() 與 __get_free_page() 分配的是物理內存,但它返回的到底是什麼?那幾篇關於驅動編寫的文章中提到申請的是物理地址,返回的依然是物理地址。但有一篇文章中,作者

對此提出了質疑,但沒有給出答案。這也就是我寫這篇筆記的原因。在找答案的同時也將 linux kernel 分配物理內存的流程做了下分析。這僅是篇筆記,寫的比較亂。自己能看懂就行了。

這裡只分析分配連續物理地址的函數。對於 vmalloc() 這種分配非連續物理地址的函數不在本記錄范圍之內。

1、kmalloc() 分配連續的物理地址,用於小內存分配。

2、__get_free_page() 分配連續的物理地址,用於整頁分配。

至於為什麼說以上函數分配的是連續的物理地址和返回的到底是物理地址還是虛擬地址,下面的記錄會做出解釋。

kmalloc() 函數本身是基於 slab 實現的。slab 是為分配小內存提供的一種高效機制。但 slab 這種分配機制又不是獨立的,它本身也是在頁分配器的基礎上來劃分更細粒度的內存供調用者使用。也就是說系統先用頁分配器分配以頁為最小單位的連續物理地址,然後 kmalloc() 再在這上面根據調用者的需要進行切分。

關於以上論述,我們可以查看 kmalloc() 的實現,kmalloc()函數的實現是在 __do_kmalloc() 中,可以看到在 __do_kmalloc()代碼裡最終調用了 __cache_alloc() 來分配一個 slab,其實

kmem_cache_alloc() 等函數的實現也是調用了這個函數來分配新的 slab。我們按照 __cache_alloc()函數的調用路徑一直跟蹤下去會發現在 cache_grow() 函數中使用了 kmem_getpages()函數來分配一個物理頁面,kmem_getpages() 函數中調用的alloc_pages_node() 最終是使用 __alloc_pages() 來返回一個struct page 結構,而這個結構正是系統用來描述物理頁面的。這樣也就證實了上面所說的,slab 是在物理頁面基礎上實現的。kmalloc() 分配的是物理地址。

Copyright © Linux教程網 All Rights Reserved