关于 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; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
bin文件和elf文件都是可执行文件的一种格式,它们的主要区别在于: 1. 内容格式不同:bin文件是二进制文件,内容是直接可执行的机器指令;而elf文件是一种带有头部信息的二进制文件,内容包括机器指令、符号表、重定位信息等,可以被系统动态加载并执行。 2. 用途不同:bin文件主要用于直接烧录到硬件设备中执行,如单片机、DSP等;而elf文件主要用于编译链接后生成可执行文件,可以在操作系统上运行。 编写elf文件的一般步骤如下: 1. 编写源代码:使用C/C++等编程语言编写源代码文件,如hello.c。 2. 编译源代码:使用gcc等编译器将源代码编译成目标文件,如hello.o。命令如下: ``` gcc -c hello.c -o hello.o ``` 这个命令会生成一个名为hello.o的目标文件,其中包含了编译后的机器指令。 3. 链接目标文件:使用ld等链接器将目标文件链接成可执行文件,如hello。命令如下: ``` ld hello.o -o hello ``` 这个命令会生成一个名为hello的可执行文件,其中包含了机器指令、符号表、重定位信息等。 4. 运行可执行文件:使用./hello命令运行可执行文件。命令如下: ``` ./hello ``` 这个命令会启动操作系统上的elf文件执行器,读取并执行hello文件中的机器指令,输出hello world字符串。 需要注意的是,在编写elf文件时需要注意机器指令的平台相关性,不同的操作系统和处理器架构可能需要不同的编译和链接选项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值