W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
我們我們已經在前面章節(jié)中注意到的, 大量連續(xù)內存緩沖的分配是容易失敗的. 系統(tǒng)內存長時間會碎片化, 并且常常出現一個真正的大內存區(qū)會完全不可得. 因為常常有辦法不使用大緩沖來完成工作, 內核開發(fā)者沒有優(yōu)先考慮使大分配能工作. 在你試圖獲得一個大內存區(qū)之前, 你應當真正考慮一下其他的選擇. 到目前止最好的進行大 I/O 操作的方法是通過發(fā)散/匯聚操作, 我們在第 1 章的"發(fā)散-匯聚 映射"一節(jié)中討論了.
如果你真的需要一個大的物理上連續(xù)的緩沖, 最好的方法是在啟動時請求內存來分配它. 在啟動時分配是獲得連續(xù)內存頁而避開 __get_free_pages 施加的對緩沖大小限制的唯一方法, 不但最大允許大小還有限制的大小選擇. 在啟動時分配內存是一個"臟"技術, 因為它繞開了所有的內存管理策略通過保留一個私有的內存池. 這個技術是不優(yōu)雅和不靈活的, 但是它也是最不易失敗的. 不必說, 一個模塊無法在啟動時分配內存; 只有直接連接到內核的驅動可以這樣做.
啟動時分配的一個明顯問題是對通常的用戶它不是一個靈活的選擇, 因為這個機制只對連接到內核映象中的代碼可用. 一個設備驅動使用這種分配方法可以被安裝或者替換只能通過重新建立內核并且重啟計算機.
當內核被啟動, 它贏得對系統(tǒng)種所有可用物理內存的存取. 它接著初始化每個子系統(tǒng)通過調用子系統(tǒng)的初始化函數, 允許初始化代碼通過減少留給正常系統(tǒng)操作使用的 RAM 數量, 來分配一個內存緩沖給自己用.
啟動時內存分配通過調用下面一個函數進行:
#include <linux/bootmem.h>
void *alloc_bootmem(unsigned long size);
void *alloc_bootmem_low(unsigned long size);
void *alloc_bootmem_pages(unsigned long size);
void *alloc_bootmem_low_pages(unsigned long size);
這些函數分配或者整個頁(如果它們以 _pages 結尾)或者非頁對齊的內存區(qū). 分配的內存可能是高端內存除非使用一個 _low 版本. 如果你在為一個設備驅動分配這個緩沖, 你可能想用它做 DMA 操作, 并且這對于高端內存不是一直可能的; 因此, 你可能想使用一個 _low 變體.
很少在啟動時釋放分配的內存; 你會幾乎肯定不能之后取回它, 如果你需要它. 但是, 有一個接口釋放這個內存:
void free_bootmem(unsigned long addr, unsigned long size);
注意以這個方式釋放的部分頁不返回給系統(tǒng) -- 但是, 如果你在使用這個技術, 你已可能分配了不少數量的整頁來用.
如果你必須使用啟動時分配, 你需要直接連接你的驅動到內核. 應當如何完成的更多信息看在內核源碼中 Documentation/kbuild 下的文件.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: