GeekOS-Project1

GeekOS:Project1. Loading Executable Files

 转自 http://www.cnblogs.com/wuchang/archive/2009/06/14/geekos-project1.html

一、项目设计目的
       熟悉ELF文件格式,了解GeekOS系统如何将ELF格式的可执行程序装入到内存,建立内核进程并运行的实现技术。
二、项目设计要求
   1、修改/geekos/elf.c文件:在函数Parse_ELF_Executable( )中添加代码,分析ELF格式的可执行文件(包括分析得出ELF文件头、程序头,获取可执行文件长度,代码段、数据段等信息),并填充 Exe_Format数据结构中的域值。
  2、在Linux环境下编译系统得到GeekOS镜像文件。
  3、编写一个相应的bochs配置文件。
  4、在bochs中运行GeekOS系统显示结果。

 

 


在此项目中,GeekOS需要从磁盘加载一个可执行文件到内存中,并且在内核线程中执行此程序。我们需要做的就是完成/geekos/elf.c中Parse_ELF_Executable函数,把EXE文件的内容填充到指定的Exe_format格式的区域。

/geekos/elf.c中Parse_ELF_Executable函数的定义如下:

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


exeFileData为ELF(Executable and Linking Format)格式的可执行文件的内容,exeFileLength为文件的长度,函数就是需要把exeFileData中的数据填充到exeFormat中。


先来分析一下ELF文件内容布局:
image  
文件最开始是ELF文件头结构,跟着是ProgramesHeader表,接下来是各个区段,最后是可选的区段头表。详细的可以参看ELF Specification
在elf.h中可以找到 ELF Header和programHeader的定义:

typedef struct {
    unsigned  char    ident[16];
    unsigned  short   type;
    unsigned  short   machine;
    unsigned  int     version;
    unsigned  int     entry;
    unsigned  int     phoff;
    unsigned  int     sphoff;
    unsigned  int     flags;
    unsigned  short   ehsize;
    unsigned  short   phentsize;
    unsigned  short   phnum;
    unsigned  short   shentsize;
    unsigned  short   shnum;
    unsigned  short   shstrndx;
} ELFHeader;
ELFHEader各字段的含义参看这里ELF Header
typedef struct {
   unsigned  int   type;
   unsigned  int   offset;
   unsigned  int   vaddr;
   unsigned  int   paddr;
   unsigned  int   fileSize;
   unsigned  int   memSize;
   unsigned  int   flags;
   unsigned  int   alignment;
} programHeader;


Exe_Format结构的定义如下:

struct Exe_Format {
struct Exe_Segment segmentList[EXE_MAX_SEGMENTS]; /* Definition of segments */
int numSegments; /* Number of segments contained in the executable */
ulong_t entryAddr; /* Code entry point address */
};
struct Exe_Segment {
ulong_t offsetInFile; /* Offset of segment in executable file */
ulong_t lengthInFile; /* Length of segment data in executable file */
ulong_t startAddress; /* Start address of segment in user memory */
ulong_t sizeInMemory; /* Size of segment in memory */
int protFlags; /* VM protection flags; combination of VM_READ,VM_WRITE,VM_EXEC */
};

明白了这几个结构后,程序就很容易了:

int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength,
    struct Exe_Format *exeFormat)
{
     int i;
    elfHeader *hdr =(elfHeader*) exeFileData;
    programHeader *phdr=(programHeader *)(exeFileData + hdr->phoff);;
    struct Exe_Segment * segment= exeFormat->segmentList ;
    for( i=0; i< hdr->phnum; i++)
    {
        segment->offsetInFile = phdr->offset;
        segment->lengthInFile = phdr->fileSize;
        segment->startAddress = phdr->vaddr;
        segment->sizeInMemory = phdr->memSize;
        phdr++;
        segment++;
    }
    exeFormat->numSegments = hdr->phnum;
    exeFormat->entryAddr = hdr->entry;
    return 0;
}

编译成功后执行结果如下:
image

此项目中执行的是 src/user/a.c编译后的a.exe程序,如果想修改显示信息的可以打开此文件修改。

此项目执行的程序放在disk.img磁盘映像中,和project0稍有不同,所以要修改下.bochsrc文件,参考配置如下:

config_interface: textconfig
romimage: file=/usr/share/bochs/BIOS-bochs-latest
megs: 8
vgaromimage: file=/usr/share/vgabios/vgabios.bin
floppya: 1_44=./fd.img, status=inserted
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15
#ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
#ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
ata0-master: type=disk, path="diskc.img", mode=flat, cylinders=40, heads=8, spt=64
#ata0-slave: type=cdrom, path="/dev/cdrom", status=inserted
boot: a
ips: 1000000
log:./bochs.out
vga_update_interval: 300000
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
private_colormap: enabled=0

 

出处:http://wuchang.cnblos.com

### 关于 GeekOS 课程设计 Project 1 的资源与指南 GeekOS 是一个用于教学目的的操作系统项目,通常被用来帮助学生理解操作系统的核心概念以及其实现细节。对于 **Project 1**,其目标通常是围绕操作系统的初始化、内存管理或者基本进程控制展开[^2]。 以下是关于如何查找和利用相关资料的一些建议: #### 资源获取途径 可以参考一些公开的教学材料或类似的开源项目文档来辅助学习。例如: - 官方课程网站或讲义:许多大学会提供详细的项目说明和技术指导文件,这些文件可能包含了实现的具体要求和建议的技术路线。 - 开源社区贡献者分享的经验博客或教程文章:通过搜索引擎输入关键词如 `geekos project 1 tutorial` 或 `operating systems course projects examples` 可能找到其他学生的经验总结[^3]。 #### 技术要点解析 根据常见的操作系统课程设计需求,以下是一些技术方面的提示: - **启动过程分析**:了解引导加载程序的工作原理及其在操作系统中的角色是非常重要的。这涉及到硬件抽象层的知识点[^4]。 - **内存分配策略**:如果项目涉及到了简单的内存管理系统构建,则需要掌握静态/动态分区分配算法的基础理论[^5]。 - **中断处理机制**:熟悉处理器是如何响应外部事件并切换上下文环境的过程有助于完成某些特定功能模块的设计开发工作[^6]。 ```c // 示例代码片段展示了一个简化版的函数原型定义, // 这里假设我们要创建一个新的线程执行指定的任务。 int create_thread(void (*start_routine)(void *), void *arg); ``` 上述伪代码展示了创建新线程的一个接口声明形式,在实际编码过程中还需要考虑同步原语的应用等问题[^7]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值