Orange'S:一个操作系统的实现

文件系统

Posted by BINBIN Blog on November 9, 2019

文件系统

硬盘操作的IO端口

硬盘驱动程序

要先创建硬盘,按照书上所提供的方法,使用bximage创建!

做好了80MB的硬盘,512字节的扇区!

给出了bochsrc配置信息的提示:

The following line should appear in your bochsrc: ata0-master: type=disk, path=”80m.img”, mode=flat

修改bochsrc

注意书上的源代码是这样的:

ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
# !! Remember to change these if the hd img is changed:
#    1. include/sys/config.h::MINOR_BOOT
#    2. boot/include/load.inc::ROOT_BASE
#    3. Makefile::HD
#    4. commands/Makefile::HD
ata0-master: type=disk, path="80m.img", mode=flat, cylinders=162, heads=16, spt=63

经实践,不需要 cylinders=162, heads=16, spt=63 这些信息!

chapter9 a节的代码

文件系统基本要素

  • 有要地方存放metadata
  • 要有地方记录扇区的使用情况
  • 要有地方记录任一文件的信息,比如占用了哪些扇区等等
  • 要有地方存放文件的索引

参照minix的文件系统设计

  • 有要地方存放metadata – 占用整整一个扇区的superblock
  • 要有地方记录扇区的使用情况 – sector map
  • 要有地方记录任一文件的信息,比如占用了哪些扇区等等 – inode map以及被称作inode_array的i-node真正存放地
  • 要有地方存放文件的索引 – root数据区

superblock也叫超级块,关于文件系统的Metadata,统统记载这里。 secort map 是一个位图,用来映射扇区的使用情况,1表示扇区已经被使用,0表示未使用,i-node是UNIX世界各种文件系统的核心数据结构之一,借用过来! 每一个i-node对应一个文件,用于存放文件名,文件属性等内容,inode_array就是把所有i-node都放在这里,形成一个较大的数组。而inode map就是用来映射inode_array这个数组使用情况的一个位图,用法跟sector map 类似。

root数据区类似于FAT12的根目录,但是本质上他也是个普通文件,由于它是所有文件的索引,所以我们把它单独看到。

为了简单起见,我们的文件系统暂时不支持文件夹。 听说以前也有个不支持文件夹的东西,叫做扁平文件系统flat file system

引导扇区就用做引导! 就不学习fat12把一些额外的数据结构塞进去,现在硬盘很大够用了

硬盘分区表

设置一下grub实现多引导!

硬盘分区表其实是一个结构体数组,数组的每个成员是一个16字节的结构体,他的构成如表所示;

把刚生成的硬盘分成几个区

这样第一个主分区10m就完成了!

剩下的作为逻辑分区

在这里,我们分成了一个主分区和一个扩展分区,扩展分区又分成了逻辑分区,我们把系统装在80m.img的分区。

我们先把分区类型更改为99h,又设定了“可启动”标志!

可以看到硬盘钱1BEh个字节都是0,后面就是分区表的内容了!

完善硬盘驱动程序,目前只处理DEV_OPEN消息!增加DEV_READ和 DEV_WRITE! 制作一个文件系统

  • 用于存储和组织计算机文件数据的一套方法
  • 存在于某介质的具备某种格式的数据

mkfs() 分几个部分:

  • 向硬盘驱动程序索取ROOT_DEV的起始扇区和大小;
  • 建立超级块(Super Block)
  • 建立inode-map
  • 建立sector-map
  • 写入inode_array
  • 建立根目录文件

文件操作

源代码缺少了proc.h 中的

stuct file_desc * filp[NR_FILES];

书上源代码缺少项目太多了,从网上下载的代码缺少很多,主要缺少了sys文件下的代码!导致代码编译错误太多了,我只好根据书上提供的网址去找书上的代码,发现作者把代码已上传github,github真是好东西!

网址 https://github.com/yyu/osfs00

makefile 也做相应的修改! CFLAGS = -I include/ -I include/sys/ -m32 -c -fno-builtin -Wall -fno-stack-protector

f章节

可以看到abc被读出来了!

h章节

运行可以看出,创建了foo bar baz 三个文件, 然后有删除了三个文件夹。 代码可以用log记录来作为调试辅助!

有个调试异常,作者分享了一个经验!

异常: 完成unlink()系统调用的过程中,一个意外发生了,就在我们添加几行很简单的代码,突然发现系统无法启动了:每次启动都很快奔溃。 调试之后,错误终于发现,使用ls -1F 可以看到内核文件 kernel.bin 已经超过64kb了,回忆第5章,我们目前loader所支持的内核大小的上限为64kb。

正如书上直接修改loader代码!

万一内核有太大盛不下怎么办? 作者支招就是写个脚本并修改makefile,让脚本在每次make之后执行一下。 脚本的任务有两个! 一是比较kernel.bin的大小和我们预留出来的空间,代码设置的是20000h; 二是用readelf之类的工具获取内核在内存中的最终布局,并判断他是否越过了1000h ~ 6FFFFh这个界限。

为文件系统添加系统调用的步骤 ,参考书上所说!

i章节就是将tty纳入文件系统

j章节就是修改printf