一文带你慢且不通SEOSLab2
主要是针对OS Lab2的一些记录,自己看看的
makefile解读
一共三条,make onlyCpp
主要是一开始没写汇编的打印函数,全用的cout,先编译出来看看效果
同时也是为了便于调试,打断点(./main的过程可能也是可以调的,没试
实验开始前
装库
gcc-multilib 和 g+±multilib
不然后面会报错
制作软盘并建立结构
1 | mkfs.fat -C a.img 1440 |
补充:
-
创建层及目录mkdir可加-p参数
mkdir -p a/b/c
-
进入挂载好的目录之后,切换成root创建各种东西会方便点
如果是普通用户vim文件时可能显示文件read only
-
在盘的根路径下使用tree命令查看结构
代码部分
直接从主代码开始看
整个结构,很重要:
1. 初始化BPB信息
打开文件,用自建的BPB类读取相关信息
BPB类如下:
init函数读取
bpb->init(fat12)进行读取
先读到bpb类的成员函数里面(两行就行
1 | // BPB从第11个字节处开始,0-2为短跳转指令,3-10为厂商名 |
再初始化一些后面可能用到的全局变量
要计算的是四个
BytesPerClus = 1 * 512
FATBase = 1 * 512
RootDirBase = (1 + 2 * 9) * 512
DataBase = ((224 * 32 + 32 - 1) / 512 + 1 + 2 * 9) * 512
2. 创建root根节点(所要建立的那个树
Node类如下:
以及还有一部分get set方法
设置一些root的成员变量
3. 开始创建树,利用根目录区开始
根目录区其实就是很多目录项(这里的目录包含文件,比如我使用的img文件中根目录下就应该有三项
0x2600根目录区开始
后面不用管,注意文件名是8+3
由此开始读文件(并且建立树结构)之旅
RootDirEntry结构如下:
RootDirEntry纯粹就是个读东西存放用的工具
一共32字节,也就是两行
这样就是一个目录项
RootDirEntry里有readFile方法,从这个开始递归读取
注1:讲道理这个readFile方法其实就调用了一次,不该作为RootDirEntry的成员方法,而应该是全局的一个函数
注2:RootDirEntry类的DIR_Name就是那个占11字节的名字
注3:就是在这里获取了DIR_FstClus,后面读取内容会用到
主体结构如下
注1:根目录项的文件属性
1 | void RootDirEntry::readFile(FILE *fat12) { |
bool RootDirEntry::isInvalidName():
读取根目录项时判断哪些是需要的文件或目录
以’\0’开头(就是空的目录项)或者出现11个字节内出现任何不合法字符就是invalid
可如下验证:
RootDirEntry::readFile内的四个函数
string name = dealFileName(entry->getDirName());
readFileContent(fat12, fileChild);
string name = dealDirName(entry->getDirName());
readDirContent(fat12, dirChild);
递归就是靠这两个readContent函数实现的
个人感觉递归的关键在于
如果根目录下是一个目录,那么在数据区对应的地方也是会有一个32字节的目录项,就跟根目录区是一样的构成
数据区并不全是数据,非根目录的目录也是会在这的
复看代码的时候发现一处问题
linux并不是文件都有扩展名,所以在dealFileName的时候,文件名是不一定包含’.'的
但好像这次实验又说了文件会有扩展名,所以就不修这个地方了,要修的话无非就是判断下后面有没有扩展名,没有的话就把’.'去掉而已
getFatValue()
实现两个readContent函数还有一个关键的地方在于获取fat表项的值
小端存储:低地址向高地址生长
数据的高字节在高位就是小端存储
图中的例子,读到HOUSE的FstClus=3然后
0x200 + 3 * 3 / 2 = 0x204
把204(f0) 205(ff)的字节读出来是fff0,奇数,取高12位fff
说明结束了,HOUSE的内容只在簇3
然后簇3-2=簇1
数据区起始在0x4200一个簇512字节就是0x200所以0x4400的数据就是它的内容
至此,文件终于读完了!树也构建好了
4. 汇编实现的打印函数
1 | global myAsmPrint |
关于参数压栈顺序
(2条消息) C语言 | 函数参数压栈的顺序是?_函数参数压栈顺序_嵌入式大杂烩的博客-CSDN博客
栈应该是高地址往地址生长
C/C++ 参数从右往左压栈,而之前要先压入一个IP,所以栈从高到低是
长度、首地址、IP
5. 实现cat命令
cat和ls都用到了一个关键的函数
findFileNodeByName
找到的话就返回节点,没找到或者找的过程中有不存在的,也会返回空
6. 实现ls和ls -l
注意
ls -
是要报错的
ls 和 ls -l差不太多
递归实现下listAllContentWithoutL和listAllContentWithL就行
1 | // ls指令,要处理的东西还是很多的 |
- 标题: 一文带你慢且不通SEOSLab2
- 作者: SYuan03
- 创建于 : 2023-04-14 23:45:07
- 更新于 : 2024-09-30 20:52:08
- 链接: https://bblog.031105.xyz/posts/2023-Spring-Courses-操作系统/一文带你慢且不通seoslab2.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。