Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Linux0.11內核--緩沖區機制大致分析,linux0.11緩沖區

Linux0.11內核--緩沖區機制大致分析,linux0.11緩沖區

編輯:關於android開發

Linux0.11內核--緩沖區機制大致分析,linux0.11緩沖區


文件系統的文件太多,而且是照搬的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;
}

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

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved