操作系统——文件系统(2)生磁盘的使用

1.第一层抽象:从扇区到磁盘块请求

    从用户的角度来看,每次使用磁盘都需要去操纵对应的柱面C、柱头H、扇区S,这显得过于烦琐。如果能直接省略这些细节,将磁盘变成从0开始到10000、10001…这样的扇区,更符合用户的操作习惯。那么,对于第一层抽象而言,建立从基于C、H、S的扇区地址到扇区号的映射,是最重要的任务。
    0号扇区可以规定在0柱面(最外围的柱面)、0磁头(最上面的磁头)、0扇区位置。但问题在于1号扇区选取在什么位置:(1)和0号扇区相邻的同一磁道上的下一个扇区;(2)和0扇区相邻的下一个磁道上的扇区;(3)和0号扇区相邻的下一个柱面上的扇区。示意图如意。
在这里插入图片描述
    1号位置的选取,要出于提高磁盘工作效率的考虑。磁盘读写分成三步:移动磁臂(寻道)、旋转磁盘、数据传输。寻道通常要花费10ms的时间,磁盘转速7200r/min,转动半圈需要4ms,而数据传输的速度通常为每秒几十兆节,1个扇区512个字节的传输时间只需要0.01ms。因此,在磁盘读写时,占用时间最多的是寻道和磁盘转动的时间。
    而当我们将所有扇区按照扇区号编号以后,根据局部性原理,我们往往在读完第一个扇区的内容后,要紧接着去读相邻的下一个扇区的内容。比如读完0号扇区,要紧接着去读1号扇区,那么选择1号扇区处在与0号扇区同一磁道的相邻位置是最合适的,在这种情况下不需要移动磁臂和旋转磁盘,可以最大程度的提高效率。在这里插入图片描述
    按照这种编号方式,可以给出C、H、S扇区地址对应的扇区号为:

sector = C*(Heads*Sectors)+H*Sectors+S

    sector是扇区号,Sectors所示每个磁道的扇区数,Heads是磁盘的数量,变形后得到如下:

sector=(C*Heads+H)*Sectors+S

    这时根据扇区号sector来算出C、H、S:

S=sector%Sectors
H=sector/Sectors%Heads
C=sector/Sectors/Heads

    现在已经完成了扇区的编号,我们不需要去关注扇区所在的C、H、S了,而是用一个扇区号直接代替了,当操作系统接收到扇区号,就会计算出对应的C、H、S,用out指令将这些信息写到磁盘控制器。但如果每次只操作一个扇区号,效率也是不够高的,一次读取一个扇区的话,其速度是0.5KB/14.01ms,但如果一次读取十个扇区,速度是5KB/14.1ms,速度相当于提高到十倍。
    正是因为读写数据的时间相较于磁盘旋转和寻道时间来说是很小的,所以我们倾向于一次性读取更多的扇区,而这些扇区的组合称之为磁盘块。当然磁盘块会造成磁盘空间的浪费,如果一个磁盘块的大小为1MB,那么一个文件平均会造成最后一个磁盘块0.5MB空间的浪费。然而在磁盘成本越来越小的今天,这种牺牲空间换取效率的方法是很可取的。
    有了磁盘块以后,用户发出的读写请求就从扇区号变成盘块号blocknr了,那么扇区号就等于blocknr*blocksize。
    得到盘块号就可以算出扇区号,根据扇区号求出C、H、S,CPU就可以发出out指令。具体实现如下:

//创建和处理磁盘读写请求的代码
static void make_request()
{
	struct request *req;//数据结构中的核心信息就是sector
	req = request + NR_REQUEST;
	req -> sector = bh -> b_blocknr<<1;
	add_request(major + blk_dev, req);
}
void do_hd_request(void)//实现从sector到C、H、S的计算
{
	unsigned int block = CURRENT->sector;
	__asm__("divl % 4":  "=a" (block), "=d" (sec): "0"
	(block), "1" (0), "r" (hd_info[dev].sect));
	__asm__("divl % 4":  "=a" (cyl), "=d" (head): "0"
	(block), "1" (0), "r" (hd_info[dev].head));
	hd_out(dev, nsect, sec, head, cyl, WRITE);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值