MIT6.S081 make qemu运行出错,常见问题及解决方法
- 问题一:make: *** No rule to make target 'user/_ps',needed by 'fs.img'. Stop.
- 问题二:error: variable ‘XXXX’ set but not used [-Werror=unused-but-set-variable]
- 问题三:Is another process using the image [fs.img]?
- 问题四:mkfs:mkfs/mkfs.c:85: main:Assertion '(BSIZE % sizeof(struct dinode)) == 0 'failed.
- 问题五:error:implicit declaration of function 'filewalk' ; did you men 'sys_filewalk'?
- 问题六:其他的一些错误
- 问题七:未完待续(●'◡'●)
问题一:make: *** No rule to make target ‘user/_ps’,needed by ‘fs.img’. Stop.
可能出错的原因及解决方法:
- 在修改Makefile文件时,没有严格按照Makefile的格式去编写。
检查:$u/_ps\ 该语句后有没有多余的空格
上图就是错误的示例,$u/_wc\该语句后有多余的空格,并且根据shell语句可以看出,该语句的格式与其他语句不同。 - 编写的相关配置文件不全。在编写xv6系统下的系统调用时,可以从如下几个相关文件入手编写:
Step 1
:修改用户代码:包括user/user.h user/usys.pl
Step 2
:修改内核代码:包括kernel/syscall.h kernel/syscall.c 【kernel/syspro.c】 【kernel/sysfile.c】【kernel/proc.c】
注意:后面【】中的文件是否修改根据具体的要求。
Step 3
:编写应用工具,即编写user/ps.c
文件(以ps为例)
Step 4
:修改Makefile
文件,将$U/_ps\
添加到Makefile的UPROGS中
Step 5
:make qemu,进行测试 - 大家可以多去了解一些关于
Makefile
内部更深层的一些代码,有助于我们进行错误调试。另外,过段时间我也会写1篇关于Makefile文件的深层解读。Makefile文件深入解读
问题二:error: variable ‘XXXX’ set but not used [-Werror=unused-but-set-variable]
解决方法:
- 找到Makefile文件
- Linux环境下,若当前模式为:NORMAL,直接输入:
/FLAGS
,查找如下的语句。
删除掉该行语句中的 -Werror
即可。
问题三:Is another process using the image [fs.img]?
原因:
make qemu执行之后,没有等到相关调用执行完成,强制退出
。一般情况下,若执行没有结束,可以通过Ctrl+A 松开再按X
组合键正常退出。
正常退出情形下,执行结果如下图所示:QEMU:Terminated
解决方法:
- 若该系统调用未执行完,可以通过
Ctrl+A松开再按X
组合键正常退出,再去调试相关的问题找出问题所在。 - 若是在服务器环境下运行,出现上述错误,建议重新导入一下镜像,同时将原来的代码
git
保存。
导入镜像代码:git clone git://g.csail.mit.edu/xv6-labs-2020
- 可以参考一下网上的做法:链接
问题四:mkfs:mkfs/mkfs.c:85: main:Assertion '(BSIZE % sizeof(struct dinode)) == 0 'failed.
原因:
对于文件内部的结构,需要满足大小约束,因此若在添加dinode
成员变量时,会出现以上的错误。
解决方法:
方案一: 找到mkfs.c
文件中的该行语句,进行注释,如下图所示。
方案二: 上面的这种方法不太建议,因为一个文件对应一个 inode,文件的访问控制信息可以存储在 inode 中。而在 linux 中,一个 inode 的大小通常是定死的 256 或者 512 字节,不能够轻易改动,因此我们想到可以将dinode
结构体中的一个成员变量进程拆解。
我们将 type
的 short 类型的 16 bit
拆成两个 8bit
的 char
类型,其中 mod
用来存储文件的访问控制权限,而 type
则做原来的用途,表示文件的类型,如下图所示:
问题五:error:implicit declaration of function ‘filewalk’ ; did you men ‘sys_filewalk’?
原因: 在当前文件下没有声明该函数直接进行调用
解决方法: 在该文件中对函数进行定义,例如int filewalk(void);
问题六:其他的一些错误
大家在实验过程中,会遇到各种各样类似的问题。可以根据错误提示,去找相关的文件进行修改。另外,进行带参数的系统调用设计的过程中,可以添加一些printf
语句进行调试。
大家遇到其他的问题,也可以在评论区进行留言,我们一块讨论去解决。