天天看点

浅谈Nachos之COFF

课程设计中接触到了Nachos系统,在完成Project2的过程中碰到了“COFF”这个概念。一开始对它不甚了解,系统中自带的注释也仅仅写着:进程执行的程序。

百度百科中对它的定义如下:COFF –通用对象文件格式(Common Object File Format),是一种很流行的对象文件格式(注意:这里不说它是“目标”文件,是为了和编译器产生的目标文件(*.o/*.obj)相区别,因为这种格式不只用于目标文件,库文件、可执行文件也经常是这种格式)。大家可能会经常使用VC吧?它所产生的目标文件(*.obj)就是这种格式。其它的编译器,如GCC(GNU Compiler Collection)、ICL(Intel C/C++ Compiler)、VectorC,也使用这种格式的目标文件。不仅仅是C/C++,很多其它语言也使用这种格式的对象文件。

COFF文件一共有8种数据,自上而下分别为: 1. 文件头(File Header) 2. 可选头(Optional Header) 3. 段落头(Section Header) 4. 段落数据(Section Data) 5. 重定位表(Relocation Directives) 6. 行号表(Line Numbers) 7. 符号表(Symbol Table) 8. 字符串表(String Table)

这样看来,“进程执行的程序”与“通用对象文件格式”是不同的解释,那么是否可以理解为Nachos中的COFF类并不是普通意义下的COFF类呢?其实不然。我们可以看一下Nachos中对COFF的定义。

    private OpenFile file;

    protected int entryPoint;

    protected CoffSection sections[];

    private static final int headerLength = 20;

    private static final int aoutHeaderLength = 28;

    private static final char dbgCoff = 'c';

由上面的变量声明可以发现,其实Nachos中的COFF类就是一个通用对象文件格式装载器。Nachos中定义的文件头长度20,可选头长度28,文件头用来保存COFF文件的基本信息,如文件标识,各个表的位置等等。那么file又是什么呢?我们首先需要了解的是,每一个要执行的程序都保存在文件中,当这个程序需要执行时,系统就把它加载到内存中。COFF类中的实例变量file就是用来指包含着即将要执行的程序的文件。entryPoint则代表程序的入口地址(这是一个虚拟地址),被存放在文件头里面,由autograder(Nachos中的默认自动分级器)给出。而sections数组则保存着COFF文件中的段落(我们要知道每个程序是由多个段组成的)。

总的来说,每一个要执行的程序都对应一个coff,每个coff有一个sections数组,数组里面存放多个段(coffsection),每个段管理好几个虚拟页,换句话说,也就是由多个虚拟页组成。而每个coff记录一个开始的虚拟地址,从这个地址开始存放文件头以及每个段的段落头。

以上就是我对Nachos中的COFF的理解,希望大家一起来纠正讨论!

继续阅读