Advertisement

北航操作系统实验lab

阅读量:

本次实验主要完成了内核生成相关的工作,包括修改编译器路径配置、编写Makefile以实现交叉编译,并通过实验博客为学弟学妹提供帮助。此外还学习了如何使用链接脚本进行内核加载配置,并尝试完成了一系列与汇编和内核开发相关的练习。最终在gxemul目录下成功生成了vmlinux内核文件,并通过实践加深了对操作系统的底层原理的理解。

lab1

图挂了以后补

实验内容

我已下定决心投入全部精力去完成这些实验。尽管该指导书不够明确,在一定程度上偏离了我的预期目标——即建立一个完整自己的操作系统环境。然而这些实验的内容与我的最初目标并不完全一致。其中包含了许多值得深入学习的内容,在完成这个实验的同时我也计划撰写一篇博客文章以期为即将开始探索计算机领域的新手学者提供一些建议和参考。

Exercise 1.1

请编辑include.mk文件以确保交叉编译器路径正确。完成后进行make指令。若所有配置无误,则在gxemul目录中生成vmlinux内核文件。

vim一下include.mk

修改路径为 /OSLAB/compiler/usr/bin/mips_4KC-

这里的代码需要学习makefile有一篇极好的教程

(十七条消息)跟我一起编写Makefile(一)haoel的博客-:makefile

前4篇重点看,其它挑重点

这里:=其实是阻塞赋值

1、“=”

在处理整个makefile时, 它会依次执行各个目标, 并最终确定各个变量的值. 换句话说, 在处理过程中, 默认情况下各个变量将被赋予最后一次出现时的值. 看例子:

x = foo ​ y = $(x) bar ​ x = xyz

在上例中,y的值将会是 xyz bar ,而不是 foo bar 。

2、“:=”

在makefile中位置所决定的变量值,并非其整体展开后的最终结果。

x := foo ​ y := $(x) bar ​ x := xyz

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

位于**/usr/bin**处的是你后期安装的一些软件的运行脚本集合。这些脚本主要用于存放软体工具的必备执行文件如c++编译器(c++)、g++编译器(g++)、gcc编译器(gcc)、chdrv设备管理器(chdrv)、diff比较工具(diff)、dig目录浏览器(dig)、du文件属性查看器(du)、eject删除旧文件(eject)、elm配置管理工具(elm)、free内存管理函数(free)、gnome工具箱(gnome )等;此外还包括gzip压缩工具(gzip)、htpasswd密码生成器(htpasswd)、kfm网络配置管理器(kfm)、ktop图形终端 emulator (ktop)、last命令历史记录器 (last)等常用软件包;还有一些实用命令如less文本编辑器 (less)、locale语言环境支持 (locale)以及m4宏处理语言 (m4)等基础组件;还有make程序流程控制器 (make)、man手册页浏览器 (man)以及文件复制移动命令 (mcopy)等 utilities;还有远程连接工具如ncftp网络传输层协议客户端 (ncftp),新快捷方式设置 (newaliases),网络资源查找服务 nslookup+passwd (nslookup passwd),文件存储限制 quota 等;最后还有smb 网络文件服务 (smb_) 和 wget统一资源定位访问客户端 (wget) 等相关组件。

可以看到生成了内核文件

Exercise1.2

请仔细阅读.readelf文件夹中的kerelf.h、readelf.c以及main.c三个文件中的代码内容,并修复readelf.c中缺失的代码部分。其中readelf函数应记录Elf文件中所有section header的信息,并以指定格式输出:每个section header按如下格式输出:"序号:地址"(其中序号和地址均以十进制形式表示)。

首先进入文件夹

在main.c中调用了

还需要在kerelf.h中查看elf(32位)格式

完成readelf.c文件

编译并且执行

Exercise 1.3 填写 tools/scse0_3.lds 中空缺的部分,将内核调整到正确的位置上。

在实际应用中相对较少使用LDS相关知识库模块(LDSS),因此推荐您参考该教程详细的LDS语法与规则解析教程(来自官方文档) - BSP-路人甲博客

比较精华的是这段

在此示例案例中,在内存地址 24位十六进制数值表示法_处运行程序;在内存起始位置 24位十六进制数值表示法_处进行数据存储;该链接脚本将执行以下具体操作步骤包括:

复制代码

建议您采用 ' SECTIONS ' 作为关键字 ' SECTIONS ' 进行定义,并在花括号内详细说明赋值操作以及输出展示的内容。

在’ SECTIONS ’命令的第一行中,“ . ” 占位符符被指定为用于标记当前段落的位置计数值。若无特别说明,则该段落的默认地址会被设置为位置计数值;否则,在后续处理中会进行相应修改。随后将位置计数值递增以反映当前段落的长度。值得注意的是,在‘ SECTIONS ’命令的第一行执行时,默认起始值设为0。

具体修改说明

在定义输出段'.text'时,位置计数器设定了该段的偏移量为'_ 〉 〉 〉 〉 〉 〉
示例:
原句:这个方法很有效。
改写:该种方式具有显著的效果。

剩余的行指定了输出文件中两个特定的区域:'. data.'以及'. bss.'这两个区域由编译程序进行区分并分别处理。 '. data.'区的内容会被定位到内存地址'. heap_base + image_base + program counter + stack base + etc.'的位置上。当编译程序处理完'. data.'区的内容后,在计算下一个块的位置时会将其起始地址设为当前堆栈基址(即堆栈起始点)加上'. data.'区的实际大小。这样做的好处是可以确保所有操作都能正常运行而不影响其他模块的功能。因此, '. bss.'区的内容会被精确地安置在'. data.'区域紧接着后面,并且由于其特殊的用途, 它不需要被修改或保护, 因此可以安全地被覆盖或重置以释放更多的内存空间用于其他操作.

链接器将通过配置位置计数器(如有必要)来保证每个输出部分都能满足所需的对齐要求。在此示例中, .text 和_.data_ 段的特定内存区域能够满足各种对齐约束条件,但需要注意的是,链接器必须在_.data_ 和_.bss_ 段之间留出足够的空隙以避免潜在的冲突或性能问题。

如上,这就是一个简单完整的链接脚本。

进入文件夹并且开始编辑

make

查看section地址

Exercise 1.4

填入 boot/start.S 段落中的空白处。配置栈寄存器,并转移至主函数。通过 OSLAB/gxemul 执行以下指令:-E testmips(测试指令集)、-C R3000(选择处理器)、-M64(64位模式),并指定 elf-file 作为输入文件。其中 elf-file 是你编译生成的 vmlinux 文件路径。

关于学习汇编编程,在上个学期时达到了一个黄金时代阶段。然而现在已经基本忘记了这些知识;后来我又补充了我以前收集的各种编程教程资料

进入编辑

Exercise 1.5

请仔细阅读相关代码文档,并结合下面对函数规格的说明内容,在 lib/print.c 中完成 lp_Print() 函数的修复工作以支持字符输出功能。

编写

最后得了60

改正

在求助了助教之后我终于发现了问题所在

我的scse0_3.1ds被我不小心新建了一个

我一直没察觉,改的是我自己创建的那个

改正后终于得到了100

思考

我有很多思考,但是这里写不下,我写在我博客里吧,之后还会继续更新。

全部评论 (0)

还没有任何评论哟~