Linux0.11內核--緩衝區機制大致分析

来源:http://www.cnblogs.com/joey-hua/archive/2016/07/11/5662070.html
-Advertisement-
Play Games

文件系統的文件太多,而且是照搬的MINIX的文件系統,不想繼續分析下去了。緩衝區機制和文件系統密切相關,所以這裡就簡單分析一下緩衝區機制。 buffer.c 程式用於對高速緩衝區(池)進行操作和管理。高速緩衝區位於內核代碼塊和主記憶體區之間,見圖9-9 中所示。高速緩衝區在塊設備與內核其它程式之間起著 ...


文件系統的文件太多,而且是照搬的MINIX的文件系統,不想繼續分析下去了。緩衝區機制和文件系統密切相關,所以這裡就簡單分析一下緩衝區機制。

buffer.c 程式用於對高速緩衝區(池)進行操作和管理。高速緩衝區位於內核代碼塊和主記憶體區之間,見圖9-9 中所示。高速緩衝區在塊設備與內核其它程式之間起著一個橋梁作用。除了塊設備驅動程式以外,內核程式如果需要訪問塊設備中的數據,就都需要經過高速緩衝區來間接地操作。

因為讀取磁碟數據很耗費時間,所以緩衝區的作用就是存儲讀過的磁碟數據,下次有需求直接從緩衝區讀取,緩衝區是記憶體區域,讀取非常快速。

圖中高速緩衝區的起始位置從內核模塊末段end 標號開始,end 是內核模塊鏈接期間由鏈接程式(ld)設置的一個值,內核代碼中沒有定義這個符號。當在連接生成system 模塊時,ld 程式的digest_symbols()函數會產生此符號。該函數主要用於對全局變數進行引用賦值,並且計算每個被連接文件的其始和大小,其中也設置了end 的值,它等於data_start + datasize + bss_size,也即內核模塊的末段。

整個高速緩衝區被劃分成1024 位元組大小的緩衝塊,正好與塊設備上的磁碟邏輯塊大小相同。高速緩衝採用hash 表和空閑緩衝塊隊列進行操作管理。在緩衝區初始化過程中,從緩衝區的兩端開始,同時分別設置緩衝塊頭結構和劃分出對應的緩衝塊。緩衝區的高端被劃分成一個個1024 位元組的緩衝塊,低端則分別建立起對應各緩衝塊的緩衝頭結構buffer_head(include/linux/fs.h,68 行),用於描述對應緩衝塊的屬性和把所有緩衝頭連接成鏈表。直到它們之間已經不能再劃分出緩衝塊為止,見圖9-10 所示。而各個buffer_head 被鏈接成一個空閑緩衝塊雙向鏈表結構。詳細結構見圖9-11 所示。

緩衝區的大致結構可參照buffer.c的buffer_init函數:

extern int end;			// 由連接程式ld 生成的表明程式末端的變數。[??]
struct buffer_head *start_buffer = (struct buffer_head *) &end;
struct buffer_head *hash_table[NR_HASH];	// NR_HASH = 307 項。
static struct buffer_head *free_list;


//// 緩衝區初始化函數。
// 參數buffer_end 是指定的緩衝區記憶體的末端。對於系統有16MB 記憶體,則緩衝區末端設置為4MB。
// 對於系統有8MB 記憶體,緩衝區末端設置為2MB。
void
buffer_init (long buffer_end)
{
  struct buffer_head *h = start_buffer;
  void *b;
  int i;

// 如果緩衝區高端等於1Mb,則由於從640KB-1MB 被顯示記憶體和BIOS 占用,因此實際可用緩衝區記憶體
// 高端應該是640KB。否則記憶體高端一定大於1MB。
  if (buffer_end == 1 << 20)
    b = (void *) (640 * 1024);
  else
    b = (void *) buffer_end;
// 這段代碼用於初始化緩衝區,建立空閑緩衝區環鏈表,並獲取系統中緩衝塊的數目。
// 操作的過程是從緩衝區高端開始劃分1K 大小的緩衝塊,與此同時在緩衝區低端建立描述該緩衝塊
// 的結構buffer_head,並將這些buffer_head 組成雙向鏈表。
// h 是指向緩衝頭結構的指針,而h+1 是指向記憶體地址連續的下一個緩衝頭地址,也可以說是指向h
// 緩衝頭的末端外。為了保證有足夠長度的記憶體來存儲一個緩衝頭結構,需要b 所指向的記憶體塊
// 地址 >= h 緩衝頭的末端,也即要>=h+1。
  while ((b -= BLOCK_SIZE) >= ((void *) (h + 1)))
    {
      h->b_dev = 0;		// 使用該緩衝區的設備號。
      h->b_dirt = 0;		// 臟標誌,也即緩衝區修改標誌。
      h->b_count = 0;		// 該緩衝區引用計數。
      h->b_lock = 0;		// 緩衝區鎖定標誌。
      h->b_uptodate = 0;	// 緩衝區更新標誌(或稱數據有效標誌)。
      h->b_wait = NULL;		// 指向等待該緩衝區解鎖的進程。
      h->b_next = NULL;		// 指向具有相同hash 值的下一個緩衝頭。
      h->b_prev = NULL;		// 指向具有相同hash 值的前一個緩衝頭。
      h->b_data = (char *) b;	// 指向對應緩衝區數據塊(1024 位元組)。
      h->b_prev_free = h - 1;	// 指向鏈表中前一項。
      h->b_next_free = h + 1;	// 指向鏈表中下一項。
      h++;			// h 指向下一新緩衝頭位置。
      NR_BUFFERS++;		// 緩衝區塊數累加。
      if (b == (void *) 0x100000)	// 如果地址b 遞減到等於1MB,則跳過384KB,
	b = (void *) 0xA0000;	// 讓b 指向地址0xA0000(640KB)處。
    }
  h--;				// 讓h 指向最後一個有效緩衝頭。
  free_list = start_buffer;	// 讓空閑鏈表頭指向頭一個緩衝區頭。
  free_list->b_prev_free = h;	// 鏈表頭的b_prev_free 指向前一項(即最後一項)。
  h->b_next_free = free_list;	// h 的下一項指針指向第一項,形成一個環鏈。
// 初始化hash 表(哈希表、散列表),置表中所有的指針為NULL。
  for (i = 0; i < NR_HASH; i++)
    hash_table[i] = NULL;
}

根據上面的理論知識,這段代碼很好分析,就不多做解釋了。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本人目前還不是游戲行業的圈內人士,並不懂得,游戲行業的生態圈,也不懂得,所謂的什麼“中國市場環境”。所以不敢發表關於這方面的見解,不過我在這裡想要插一句話,就是我認為啊,行業內,人與人之間還是有分層次的,什麼層次的人,看到什麼層次的東西,不同層次的人對“市場”的理解肯定不一樣,我覺得吧,不要一概而論... ...
  • 本文主要對android6.0源碼中的Camera API2.0下的內置應用Camera2的caputre流程進行分析 ...
  • 實現圖片拉伸有三種方式. 1.直接修改圖片資源 2.通過圖片框可直接修改stretching 3.就是通過代碼的實現 // 可以把NSString 的參數 改成NSArray 數組存放參數 (就是可以修改多個) + (UIImage *)stretchImageWith:(NSString *)im ...
  • 設置一個按鈕的方法就不再贅述了 法一: UIBarButtonItem *oneButton = [[UIBarButtonItemalloc]initWithTitle:@"設置" style:UIBarButtonItemStylePlain target:selfaction:@selecto ...
  • 代碼: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.title=@"頁面調的時候隱藏工具條"; //當跳轉的時候,隱藏工具條 [self.tabB ...
  • 打開終端: 查看Git的版本的終端命令:git —version 輸入:ssh 查看是否已經存在ssh. 如果存在,先將已有的ssh備份,或者將新建的ssh生成到另外的目錄下 如果不存在,通過預設的參數直接生成ssh 生成過程如下: ssh-keygen -t rsa -C [email protected] ...
  • 當我們自定義View的時候,在給View賦值一些長度寬度的時候,一般都是在layout佈局文件中進行的。,比如android:layout_height="wrap_content",除此之外,我們也可以自己定義屬性,這樣在使用的時候我們就可以使用形如 myapp:myTextSize="20sp" ...
  • 你好, 世界 <!--EndFragment--> <!--EndFragment--> <!--EndFragment--> <!--EndFragment--> <!--EndFragment--> <!--EndFragment--> <!--EndFragment--> 【寫在開頭:】 『關 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...