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

原创 2006年06月01日 17:42:00

关于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和链表结合使用功能不错的技术。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

linux块设备基础知识(来源于国嵌)

1、块设备 块设备将数据存储在固定大小的块中,每块的大小通常在521字节到32768字节之间。磁盘、SD卡都是常见的块设备。 2、块设备与字符设备的区别 (1)读写数据的单元不同:块设备以块为读...

linux块设备基础知识(来源于国嵌)

1、块设备 块设备将数据存储在固定大小的块中,每块的大小通常在521字节到32768字节之间。磁盘、SD卡都是常见的块设备。 2、块设备与字符设备的区别 (1)读写数据的单元不同:块设备以块为读...

Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)

一.什么是DTS?为什么要引入DTS?   DTS即Device Tree Source 设备树源码, Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。 ...

linux驱动学习--第一天:设备驱动概述(一)之基础知识

前言: 工作有5年了,但是依然没有自己的特色。 废话不多说,从今天开始,坚持学习完《linux设备驱动开发详解》这本书。 根据自己的浅薄的C语言的基础,实现自己有一技之长的梦想。 当中肯定会遇...

Linux 驱动开发 基础知识及编译过程

buzzer_driver.ko的驱动编译过程说明 在下列目录下执行"make"命令编译buzzer_driver.c 得到下列文件,其中有buzzer_driver.ko, 并装载此驱动模块 ...

字符设备驱动之笔记-中断处理过程情景分析

中断系统的运行过程分析: --------------------------------------------------------------------------------------...

MFC基础知识(四)——双缓冲解决刷屏时闪烁

本文主要介绍:在利用MFC画图或图像显示时,有时候需要调用OnDraw()函数刷新屏幕,而屏幕往往会发生闪烁,本文主要介绍利用双缓冲解决闪屏问题。 关于闪屏方面的介绍分析见博文: http://b...

Linux内核读文件处理过程浅析

作者:YouChuang 本文主要介绍学习Linux内核中读文件操作的源码实现过程
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)