关于 elf loader 的编写

可以使用如下命令观看 elf 文件的信息

readelf -a build/ramdisk.img | vim -

在编写 elf loader 的时候,实际上只有下图这一部分 “Program Headers” 是有用的
在这里插入图片描述
凡是类型为 “LOAD” 的就是需要加载进内存的部分

所以,只要把这些部分加载进内存里,再跳转到 entrypoint 就完事了,是不是很容易啊?

如下,使用 PA3 中的 elf loader 代码:

static uintptr_t loader(PCB *pcb, const char *filename) {
//	1. read program from ramdisk to mem -- invoke ramdisk_read()
//	2. execute the program -- return the entry

	extern size_t ramdisk_read(void *buf, size_t offset, size_t len);

	Elf_Ehdr elfheader;
	
	// 从磁盘/elf文件中读取 elf 头,这部分元数据放在 elf 文件的头部
	ramdisk_read(&elfheader, 0, sizeof(Elf_Ehdr));

	// 检查这个 elf 文件针对的机器架构是否是我们这种架构
	assert(elfheader.e_machine == EXPECT_TYPE);
	// 检查 elf 魔数
	assert(*(uint64_t *)(elfheader.e_ident) == 0x00010102464c457f);

	// Elf_Phdr 的格式和大小刚好是 ELF Program Headers 中的一节 
	Elf_Phdr program_header;

	// 从磁盘/elf文件中 读取第一个 program_header
	ramdisk_read(&program_header, elfheader.e_phoff, sizeof(Elf_Phdr));

	// 进入循环,这个循环会遍历所有的 program_header
	for(int i = 1; i < elfheader.e_phnum; i++) {
		// 如果当前这节 program_header 的类型是 LOAD,那么把它装载进内存
		// 然后再把 program_header.memsize - program_header.filesize 这部分清零
    	if(program_header.p_type == PT_LOAD) {
			ramdisk_read((void *)(program_header.p_vaddr), program_header.p_offset, program_header.p_filesz);
			memset((uint8_t *)(program_header.p_vaddr) +  program_header.p_filesz, 0, program_header.p_memsz - program_header.p_filesz);
		}
		
		// 从磁盘/elf文件中 读取下一个 program_header
		ramdisk_read(&program_header, elfheader.e_phoff + i * elfheader.e_phentsize, sizeof(Elf_Phdr));
	}

	// 返回程序入点
	return elfheader.e_entry; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值