GeekOS:Project1. Loading Executable Files
2009-06-14 14:14 无常 阅读(5935) 评论(0) 编辑 收藏 举报一、项目设计目的
熟悉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文件内容布局:
文件最开始是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;
}
此项目中执行的是 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
20090614
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架