GeekOS操作系统课程设计 项目1
环境配置可以见文章 :
1. 前置知识
ELF文件格式:一种在linux中应用广泛的可执行文件、对象、共享库的标准文件格式。其中的数据按照Segment和Section两个概念进行划分。
Segment:告诉内核执行ELF文件时如何映射内存。
Section:告诉链接器ELF文件中的各个部分分别是什么。
具体内容见ELF文件格式
2. 项目设计目的
熟悉ELF文件格式,了解GeekOS系统如何将ELF格式的可执行程序装入到内存,建立内核进程并运行的实现技术。
3. 项目设计要求及实现
- 修改project1/src/geekos/elf.c文件:在函数Parse_ELF_Executable( )中添加代码,分析ELF格式的可执行文件(包括分析得出ELF文件头、程序头,获取可执行文件长度,代码段、数据段等信息),并填充Exe_Format数据结构中的域值。
// 分析ELF格式文件
int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength,struct Exe_Format *exeFormat)
{
//利用ELF头部结构体指向可执行文件头部,便于获取相关信息
elfHeader *ehdr = (elfHeader*)exeFileData;
//段的个数
exeFormat->numSegments = ehdr->phnum;
//代码入口地址
exeFormat->entryAddr = ehdr->entry;
//获取头部表在文件中的位置,便于读取信息
programHeader *phdr = (programHeader*)(exeFileData + ehdr->phoff);
//填充Exe_Segment
unsigned int i;
for(i = 0; i < exeFormat->numSegments; i++, phdr++)
{
struct Exe_Segment *segment = &exeFormat->segmentList[i];
//获取该段在文件中的偏移量*
segment->offsetInFile = phdr->offset;
//获取该段的数据在文件中的长度
segment->lengthInFile = phdr->fileSize;
//获取该段在用户内存中的起始地址
segment->startAddress = phdr->vaddr;
//获取该段在内存中的大小
segment->sizeInMemory = phdr->memSize;
//获取该段的保护标志位
segment->protFlags = phdr->flags;
}
return 0;
}
-
修改/project1/src/geekos/lprog.c 文件中的 Spawn_Program()函数,将其中的 virtSize 局部变量修改为静态全局变量,即在文件头部添加"static unsigned long virtSize;“一行代码,同时注释"unsigned long virtSize;”。
-
修改 lprog.c 文件中的 Printrap_Handler()函数
static void Printrap_Handler( struct Interrupt_State* state )
{
char *msg;
/* 此处修改以下内容以正确显示 a.c 中的局部变量 */
if (state->eax <= virtSize)
msg = (char *)virtSpace + state->eax;
else
msg = (char *)state->eax;
Print(msg);
g_needReschedule = true;
return;
}
- 在Linux环境下编译系统得到GeekOS镜像文件。终端进入project1的build目录下make depend、make。
- 编写一个相应的bochs配置文件。进入project1的 Build目录下输入gedit .bochsrc编写bochs配置文件。
megs: 32
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest
boot: a
floppya: 1_44=fd.img, status=inserted
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path=diskc.img, mode=flat, cylinders=40, heads=8, spt=63, translation=none
log: bochs.out
mouse: enabled=0
private_colormap: enabled=0
display_library: x
clock: sync=realtime, time0=local
cpu: count=1, ips=1000000
magic_break: enabled=1
- 在bochs中运行GeekOS系统显示结果。进入project1的 Build目录下输入bochs运行Bochs模拟器,执行GeekOS内核。