linux0.11缓冲处理过程及一点块设备的基础知识

关于linux缓冲处理过程及一点块设备的基础知识

 

: 块设备硬盘的基础知识:

硬盘存储信息的格式是按柱面、磁头号和扇区来存储的,硬磁盘每个存储表面被划分成若干个磁道,每道划分成若干个扇区。

存储容量=磁头数×柱面数×扇区数×每扇区字节数

磁头数: 磁头是硬盘读取数据的关键部件,,在工作状态时,磁头悬浮在盘片上方,而不与盘片直接接触,电源关闭之后,磁头会自动回到在盘片上的起始位置。硬盘的磁头数取决于硬盘中的碟片数,盘片正反两面都存储着数据,所以一个盘片对应两个磁头才能正常工作。比如总容量80GB的硬盘,采用单碟容量80GB的盘片,那只有一张盘片,该盘片正反面都有数据,则对应两个磁头;而同样总容量120GB的硬盘,采用二张盘片,则只有三个磁头,其中一张盘片的一面没有磁头。

扇区: 硬盘内部是金属盘片,将圆形的盘片划分成若干个扇形区域,这就是扇区.

磁道: 以盘片中心为圆心,把盘片分成若干个同心圆,那每一个划分圆的线条,就称为磁道。

柱面: N张盘片中相同位置的磁道组成一个柱面,磁道 v==柱面数

:高速缓冲工作过程及相关基本算法:

缓冲的结构

struct buffer_head {

       char * b_data;                    //每个都指向一个1024字节地址

       unsigned long b_blocknr;  //挂钩的设备的块号

       unsigned short b_dev;              // 数据源的设备号

       unsigned char b_uptodate; //更新标志表示数据已经更新

       unsigned char b_dirt;         //干净或者脏页标志0干净1

       unsigned char b_count;     //经常被用到的引用记数设计模式的计数器

       unsigned char b_lock;              //锁定标志1锁定

       struct task_struct * b_wait; //所有访问此设备此块的任务等待队列

       struct buffer_head * b_prev;

       struct buffer_head * b_next;

       struct buffer_head * b_prev_free;

       struct buffer_head * b_next_free;

};

 

A:初始化过程

    0.11基本思想我们要将内存划分为1024字节一块的N块缓冲数据区,并且以上面的数据结构来管理这部分缓冲。我们下面看下基本划分内存的过程:

    0.11中内存主要划分成内核0~640KB(内核代码不到640KB),显存和BOIS信息(640KB~1MB),高速缓冲区( 1M ~XM),部分虚拟盘,然后是主存储区。(X的值可以参考设计获取 16M 内存则X=4, 8M 内存则X=2…) .

    管理通过hash表和空闲联表共同管理。通过设备号和逻辑块号作为主键进行hash,我们所有操作设备的数据都是通过这段缓冲进行管理。

B:处理过程

    请求数据:我们先根据读的位置在hash表中映射位置查看对应位置中是否存在已经被请求的缓冲块,比如是否已经有其他的进程请求过此块内容,如果匹配到那么直接返回hash中的节点位置,执行对应操作就可以了。如果没有hash表中存在,那么就要到空闲块中申请一个块作为此设备的缓冲,并链入hash,并将此块从空闲队列中移除放到空闲的最后。找此块的条件首先需要引用记数为0标志其没有被任何进程占用,然后需要不脏并且未被锁定。B_dirty, b_lock可以不为0(最好都为0,其次不为脏)。然后依次等待解锁,等待同步直到找到一个完全干净的块。当然其间一旦此块又被占用又会去扫描hash然后扫描空闲队列重复开头操作。

    其中可以看到有个比较特殊的bread_page,其实就是一次操作4个块,目的为适应内存管理时的页面交换等操作。因为一个页面是4kb等于4个块大小。

   

另外有点关于linux使用的LRU算法, 普通直观的LRU算法,要在块表中为每一块设置一个计数器。被装入或被替换的块,其对应的计数器清为"0",同组中其它所有块所属的计数器都加"1"。命中的块,其对应的计数器清为"0"。同组中其它所有计数器中,凡是计数器的值小于命中块所属计数器原来值的,都加"1",其它计数器不变。需要替换时,在同组的所有计数器中选择计数值最大(一般为全1)的计数器,它所对应的块就是要被替换的块。

linux采用的是双向空闲联表和hash辅助实现了这个算法。值得借鉴。其实看了也只是形式变换了,本质也没有变只是多组变成了一组,最新被使用的联表将被链入空闲最后的地方表示最不空闲的。其中的引用记数和简单的hash和链表结合使用功能不错的技术。

你可能感兴趣的:(linux0.11缓冲处理过程及一点块设备的基础知识)