Lab1实验报告

一、实验思考题

Thinking 1.1

也许你会发现我们的readelf程序是不能解析之前生成的内核文件(内核文件是可执行文件)的,而我们之后将要介绍的工具readelf则可以解析,这是为什么呢?(提示:尝试使用readelf -h,观察不同)

答:通过readelf -h读取vmlinuxtestELF的结果如下图所示:

  • vmlinux:
OS-lab1实验报告_linux
  • testELF:
OS-lab1实验报告_c语言_02

Data属性一栏中可以看到vmlinux为大端存储而testELF为小端存储,我们的readelf程序只能对小端存储进行解析,所以无法解析内核文件。

Thinking 1.2

内核入口在什么地方?main 函数在什么地方?我们是怎么让内核进入到想要的 main 函数的呢?又是怎么进行跨文件调用函数的呢?

答:内核入口在0x8000_0000main函数在0x8001_0000。通过执行跳转指令jal跳转到main函数。跨文件调用函数时,会先将需要的参数保存在寄存器a0-a3中,然后执行跳转指令跳转至函数执行,将返回值保存在寄存器v0-v1中。

二、实验难点图示

本次实验中比较难的地方,我认为是如何读懂已有的代码。

比如对于Exercise 1.2,如果不提前仔细了解ELF的文件大体结构。乍一看kerelf.h的代码是很迷茫的。

OS-lab1实验报告_linux_03

这样“冗长”的一个结构体到底是什么意思,结构体中的各个变量代表着什么属性,只有结合注释和理论的知识才能理解,从而加以运用。

对于Exercise 1.5,这一点就更加明显了。想要完成Exercise 1.5,需要阅读三个代码文件,了解printf函数的具体实现过程,需要了解这三个文件之中与printf实现相关的函数功能以及具体实现方法,比如printf.c中的myoutput函数和printf函数,这两个函数与我们需要补写的内容密切相关。

OS-lab1实验报告_linux_04

了解了这两个函数之后再去读print.c的函数内容,才能比较好的理解lp_Print函数的具体实现过程。

三、体会与感想

对于本次实验,给出你自己的难度评价,并如实记录你在这次实验上花费的时间,写出完成此次实验的体会和感想。

本次实验难度相对于lab0来说还是高了很多,主要的难点就是在于如何读懂已有的代码并且运用。虽然难度比较高但是花费的时间好像和lab0差不多(还是因为lab0做的太久了),在lab1上花费的时间前前后后加起来应该是10个小时左右。

体会与感想:

  • C语言yyds!

    C语言几乎贯穿整个lab1实验,但是实验过程中有些好奇为什么要用C语言来写操作系统,就去查了一下资料,了解到写操作系统的语言需要具有:能够跨平台、有方便的操作硬件的功能、兼容性要好、可以很方便的拓展改造、开发者众多等特点。而C语言恰好满足了这些,确实是最适合进行操作系统开发的语言。

  • 面对复杂的代码结构要耐心,仔细分析

    在实际工程开发的过程中,我们可能遇到的代码复杂程度要比实验中的高得多。在面对复杂的代码结构,要耐心读,仔细分析,理清各个部分的功能,才能从容不迫的继续进行开发。

  • 注重理论与实践的结合

    在lab0的时候因为没有预习盲目去做实验浪费了大量的时间,因此这次我先进行了充分预习,再开始写,但是又发现了新的问题。比如ELF文件,读ELF手册实在令人痛苦,毫无头绪,最后还是结合实验给出的代码一起看才能够大概理解。在后面的lab要吸取lab0和lab1的经验教训,理论和实际应用都要重视,尽量找到一个平衡更好的进行学习。

四、【可选】指导书反馈

指导书中对于SectionSegment的翻译(可能)存在问题,容易引起误解。

指导书:

OS-lab1实验报告_c语言_05
OS-lab1实验报告_BUAA_OS_06

ELF手册:

OS-lab1实验报告_c语言_07

指导书似乎把SegmentSection都译为段。