linux0.11 高速缓冲区

本文介绍了Linux内核中的文件系统管理机制,包括进程最大打开文件数量限制及高速缓冲区的实现细节。详细解析了高速缓冲区的内存分配策略、缓冲区块的数据结构以及如何通过哈希表进行高效寻址。

在fs.h当中,定义了变量NR_OPEN

#define NR_OPEN20

在任务的task_struct(sched.h)结构体当中,有一项,如下:

struct file * filp[NR_OPEN];

即当前任务打开的文件列表,所以每个进程最多打开文件20个。

另外,0.11当中,最多打开文件数为64个:

#define NR_FILE64
extern struct file file_table[NR_FILE];

在0.11中,所有的对块设备的读写都是通过缓冲区进行的,当然,块设备驱动程序除外。在内存当中,高速缓冲区在内核模块后,主内存区域之前。

一般来说,1个块等于2个扇区,而扇区为512字节,现在随着大容量磁盘的应用,扇区逐渐的变大,现在有4k的扇区,磁盘的最小存储单位是扇区,数据存储的最小单位是块,块是对文件系统而言的。

高速缓冲区高位被划分为一个个缓冲区块,每个1024字节,在内核中,高速缓冲区通过hash_table寻块,在buffer.c当中定义:

struct buffer_head * hash_table[NR_HASH]= {0};

其中NR_HASH在fs.h当中定义:

#define NR_HASH 307

而在低位存放的是对应缓存区块的头结构这是一个双向链表,如下:

struct buffer_head
{
  char *b_data;            /* pointerto data block (1024 bytes) *///指针。
  unsigned long b_blocknr;   /* block number*/// 块号。
  unsigned short b_dev;       /* device (0 =free) */// 数据源的设备号。
  unsigned char b_uptodate; // 更新标志:表示数据是否已更新。
  unsigned char b_dirt;   /* 0-clean,1-dirty*///修改标志:0 未修改,1 已修改.
  unsigned char b_count;     /* users usingthis block */// 使用的用户数。
  unsigned char b_lock;       /* 0 - ok, 1-locked */// 缓冲区是否被锁定。
  struct task_struct*b_wait; // 指向等待该缓冲区解锁的任务。
  struct buffer_head*b_prev;     // hash 队列上前一块(这四个指针用于缓冲区的管理)。
  struct buffer_head*b_next;     // hash 队列上下一块。
  struct buffer_head*b_prev_free;   // 空闲表上前一块。
  struct buffer_head *b_next_free;    // 空闲表上下一块。
};

高速缓冲区位置,在main.c当中,根据内存大小的不同,高速缓冲区的大小也不同:

 // 内存大小=1Mb 字节+扩展内存(k)*1024 字节。
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;             // 忽略不到Kb(页)的内存数。
if (memory_end> 16*1024*1024)          // 如果内存超过Mb,则按Mb 计。
      memory_end= 16*1024*1024;
// 如果内存>12Mb,则设置缓冲区末端=4Mb
if (memory_end> 12*1024*1024)         
      buffer_memory_end= 4*1024*1024;
// 否则如果内存>6Mb,则设置缓冲区末端=2Mb
else if (memory_end > 6*1024*1024)
      buffer_memory_end= 2*1024*1024;
else
      buffer_memory_end= 1*1024*1024;// 否则则设置缓冲区末端=1Mb
      main_memory_start= buffer_memory_end;//主内存起始位置=缓冲区末端;

如果内存打印12M,则设置高速缓冲区末尾在4M的位置,如果<=12M 且>6M,高速缓冲区末尾为2M,如果<=6M,高速缓冲区为1M。

而640k-1M之间是显卡,BIOS缓存区域,所以如果内存<6M ,那么高速缓冲区的高端地址就是640K,那么缓冲区块从640k往下划分。如果高速缓冲区末尾不为1M,则从末尾开始分块,从开头开始写入buffer_head:

void buffer_init(long buffer_end)
{
       //start_buffer是内核模块的末端,是由ld链接产生的
      structbuffer_head * h = start_buffer;
      void* b;
      int i;
 
      if (buffer_end== 1<<20)
           b= (void *) (640*1024);
      else
           b= (void *) buffer_end;
      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;
           h->b_prev= NULL;
           h->b_data= (char *) b;
           h->b_prev_free= h-1;
           h->b_next_free= h+1;
           h++;
           NR_BUFFERS++;    //缓冲区块计数
           if(b == (void *) 0x100000)  //b分块到1M位置结束
                 b= (void *) 0xA0000;
      }
      h--;
      //设置空闲缓冲区列表
      free_list= start_buffer;
      free_list->b_prev_free= h;
      h->b_next_free= free_list;
      for (i=0;i<NR_HASH;i++)
           hash_table[i]=NULL;
}    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值