20
GeekOS 操操操 操操 操操操操 1 北北北北北 北北北北北 西 北北 北北北 北北 操操操操http://hi.baidu.com/ geekos/

GeekOS 操作系统实验 设计项目 1

  • Upload
    aletha

  • View
    214

  • Download
    8

Embed Size (px)

DESCRIPTION

GeekOS 操作系统实验 设计项目 1. 西北工业大学 计算机学院 刘尊 史豪斌 潘炜. 课程博客: http://hi.baidu.com/geekos/. 设计目的. 熟悉 ELF 文件格式,了解 GeekOS 系统如何将 ELF 格式的用户可执行程序装入到内存,建立内核进程并运行的实现技术。. 设计要求. - PowerPoint PPT Presentation

Citation preview

Page 1: GeekOS 操作系统实验 设计项目 1

GeekOS操作系统实验设计项目 1

西北工业大学 计算机学院 刘尊 史豪斌 潘炜

课程博客: http://hi.baidu.com/geekos/

Page 2: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

设计目的

熟悉 ELF文件格式,了解 GeekOS系统如何将ELF格式的用户可执行程序装入到内存,建立内核进程并运行的实现技术。

Page 3: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

设计要求

修改 /geekos/elf.c文件:在函数Parse_ELF_Executable()中添加代码,分析ELF格式的可执行文件 ( 包括分析得出 ELF文件头、程序头,获得可执行文件长度,代码段、数据段等信息 ),并填充 Exe_Format数据结构中的域值。

掌握 GeekOS在核心态运行用户程序的原理,为项目 2 的实现做准备。

Page 4: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

ELF文件格式

可执行文件 对于可执行文件有三个重要的概念:编译、连接、加载。源程序文件首先被编译成目标文件,多个目标文件被连接成一个可执行文件,最后可执行文件被加载到内存运行。

Page 5: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

ELF头

ELF头也叫 ELF文件头,它位于文件中最开始的地方。#define EI_NIDENT 16typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; /* Entry point */ Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx;} Elf32_Ehdr;

Page 6: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

Elf32_Ehdr->e_ident[] (Magic)

这个字段是 ELF头结构中的第一个字段,在 elf.h中EI_NIDENT被定义为 16,因此它占用 16个字节。 e_ident的前四个字节顺次应该是 0x7f、 0x45、 0x4c、 0x46,也就是 "\177ELF"。这是 ELF文件的标志,任何一个 ELF文件这四个字节都完全相同。

16进制 8 进制 字母 0x7f 0177 0x45 E 0x4c L 0x46 F 第 5 个字节标志了 ELF格式是 32位还是 64位, 32位

是 1 , 64位是 2 。 第 6 个字节,在 0x86系统上是 1 ,表明数据存储方式为

低字节优先。 第 7 个字节, ELF文件头的版本信息

Page 7: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

Elf32_Ehdr->e_type (Type) ELF文件的类型, 1 表示此文件是重定位文件, 2 表示可执

行文件, 3 表示此文件是一个动态连接库。 Elf32_Ehdr->e_machine (Machine) CPU类型,它指出了此文件使用何种指令集。如果是Intel 0x386 CPU此值为 3 ,如果是 AMD 64 CPU此值为 62也就是 16进制的 0x3E。

Elf32_Ehdr->e_version (Version) ELF文件版本,为 1 。 Elf32_Ehdr->e_entry (Entry point address)

可执行文件的入口虚拟地址。此字段指出了该文件中第一条可执行机器指令在进程被正确加载后的内存地址 ! Elf32_Ehdr->e_phoff (Start of program headers)

程序头在 ELF文件中的偏移量。如果程序头不存在此值为 0 。

ELF头部分析

Page 8: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

ELF头部分析

Elf32_Ehdr->e_shoff (Start of section headers)

节头在 ELF文件中的偏移量。如果节头不存在此值为0 。 Elf32_Ehdr->e_ehsize (Size of -ELF header)它描述了“ ELF头”自身占用的字节数。 Elf32_Ehdr->e_phentsize (Size of program headers)

程序头中的每一个结构占用的字节数。程序头也叫程序头表,可以被看做一个在文件中连续存储的结构数组,数组中每一项是一个结构,此字段给出了这个结构占用的字节大小。 e_phoff指出程序头在 ELF文件中的起始偏移。

Elf32_Ehdr->e_phnum (Number of program headers)

此字段给出了程序头中保存了多少个结构。如果程序头中有3个结构则程序头( 程序头表) 在文件中占用了(3×e_phentsize)个字节的大小。

Page 9: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

ELF头部分析

Elf32_Ehdr->e_shentsize (Size of section headers)

节头中每个结构占用的字节大小。节头与程序头类似也是一个结构数组,关于这两个结构的定义将分别在讲述程序头和节头的时候给出。

Elf32_Ehdr->e_shnum (Number of section headers)

节头中保存了多少个结构。 Elf32_Ehdr->e_shstrndx (Section header string table index)

这是一个整数索引值。节头可以看作是一个结构数组,用这个索引值做为此数组的下标,它在节头中指定的一个结构进一步给出了一个“字符串表”的信息,而这个字符串表保存着节头中描述的每一个节的名称,包括字符串表自己也是其中的一个节。

Page 10: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

程序头 ( 程序头表 ) -- Program Header

程序头有时也叫程序头表,它保存了一个结构数组 ( 结构 Elf32_Phdr的数组 ) 。程序头是从加载执行的角度看待 ELF文件的结果,从它的角度ELF文件被分成许多个段。每个段保存着用于不同目的的数据,有的段保存着机器指令,有的段保存着已经初始化的变量 ; 有的段会做为进程映像的一部分被操作系统读入内存,有的段则只存在于文件中。

Page 11: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

typedef struct elf32_phdr{ Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align;} Elf32_Phdr;

Page 12: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

段结构分析

Elf32_Phdr->p_type段的类型,它能告诉我们这个段里存放着什么用途的数据。

此字段的值是在 elf.h中定义了一些常量。例如1(PT_LOAD)表示是可加载的段,这样的段将被读入程序的进程空间成为内存映像的一部分。段的种类再不断增加,例如 7(PT_TLS)在以前就没有定义,它表示用于线程局部存储。

Elf32_Phdr->p_flags段的属性。它用每一个二进制位表示一种属,相应位为 1 表

示含有相应的属性,为 0 表示不含那种属性。其中最低位是可执行位,次低位是可写位,第三低位是可读位。如果这个字段的最低三位同时为 1 那就表示这个段中的数据加载以后既可读也可写而且可执行的。同样在 elf.h文件中也定义了一此常量 (PF_X、 PF_W、 PF_R)来测试这个字段的属性,做为一个好习惯应该尽量使用这此常量。

Elf32_Phdr->p_offset该段在文件中的偏移。这个偏移是相对于整个文件的。

Page 13: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

段结构分析 Elf32_Phdr->p_vaddr该段加载后在进程空间中占用的内存起始地址。 Elf32_Phdr->p_paddr该段的物理地地址。这个字段被忽略,因为在多数现代操

作系统下物理地址是进程无法触及的。 Elf32_Phdr->p_filesz该段在文件中占用的字节大小。有些段可能在文件中不存

在但却占用一定的内存空间,此时这个字段为 0 。 Elf32_Phdr->p_memsz该段在内存中占用的字节大小。有些段可能仅存在于文件

中而不被加载到内存,此时这个字段为 0 。 Elf32_Phdr->p_align对齐。现代操作系统都使用虚拟内存为进程序提供更大的空间,分页技术功不可没,页就成了最小的内存分配单位,不足一页的按一页算。所以加载程序数据一般也从一页的起始地址开始,这就属于对齐。

Page 14: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

节头 ( 节头表 ) -- Section Header

节头也叫节头表。 ELF头的 e_shoff字段给出了节头在整个文件中的偏移 ( 如果节头存在的话 ) ,节头可看做一个在文件中连续存储的结构数组 (Elf32_Shdr结构的数组 ) ,数组的长度由 ELF头的 e_shnum字段给出,数组中每个结构的字节大小由 ELF头的 e_shentsize字段给出。把文件指针移到在 ELF头中 e_shoff给出的位置,然后读出的内容就是节头了。节头表是从连接角度看待 ELF文件的结果,所以从节头的角度 ELF文件分成了许多的节,每个节保存着用于不同目的的数据,这些数据可能被前面提到的程序头重复引用。

Page 15: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize;} Elf32_Shdr;

Page 16: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

ELF文件和内存中的可执行文件镜像

Page 17: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

设计提示

在 /src/geekos/main.c文件中,用户可以看到函数调用 Spawn_Init_Process,该函数的功能是调用Start_Kernel_Thread(),它以 Spawner函数为进程体建立一个核心级进程,并使之准备就绪。函数Spawner主要功能是从 PFAT文件系统读入一个用户执行程序,为之建立相应的进程影像,然后调用Spawn_Program函数建立相应的进程。 Spawner函数代码在目录: /src/geekos/lprog.c。

函数 Spawn_Program在 /src/geekos/lprog.c文件中已经实现,参数的数据结构 Exe_Format和Exe_Segment的定义在 elf.h文件中。

Page 18: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

设计提示

Spawn_Program函数完成如下的工作。 (1)根据 Exe_Format中的 Exe_Segment结构提供的用户程序段信息,及用户进程堆栈大小计算用户进程所需的最大内存空间,即要分配给用户进程的内存空间。

(2)为用户程序分配内存空间,并全部初始化为零,否则系统后面运行可能出错。

(3)根据段信息将用户程序中的各段内容复制到分配的用户内存空间。

(4)根据 Exe_Segment提供的用户段信息初始化代码段、数据段、以及堆栈段的段描述符和段选择子。

Page 19: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

设计提示

由于系统已经完成了内核的所有函数,用户在完成本项目设计时要完成的任务比较简单,只需要完成函数 Parse_ELF_Executable即可。函数Parse_ELF_Executable声明为:

int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength,Struct Exe_Format *exeFormat)

参数: exeFileData-已装入内存的可执行文件所占用空间的起始地址; exeFileLength-可执行文件长度; exeFormat-保存分析得到的 ELF文件信息的结构体指针。

Page 20: GeekOS 操作系统实验 设计项目 1

西北工业大学计算机学院

程序运行结果

Hi ! This is the first stringHi ! This is the second stringHi ! This is the last stringIf you see this you're happy