文件系统
硬盘操作的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