关于 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 entryextern 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_headerramdisk_read(&program_header, elfheader.e_phoff, sizeof(Elf_Phdr));// 进入循环,这个循环会遍历所有的 program_headerfor(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_headerramdisk_read(&program_header, elfheader.e_phoff + i * elfheader.e_phentsize, sizeof(Elf_Phdr));}// 返回程序入点return elfheader.e_entry; 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/596048.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文阅读】CompletionFormer:深度完成与卷积和视觉变压器

【论文阅读】CompletionFormer:深度完成与卷积和视觉变压器 文章目录 【论文阅读】CompletionFormer:深度完成与卷积和视觉变压器一、介绍二、联系工作深度完成Vision Transformer 三、方法四、实验结果 CompletionFormer: Depth Completion with Convolutions and Vision Tran…

S7-200 SMART 应用第003期-数字量输入模块接线

概述 S7-200 SMART作为西门子的一款高性价比PLC产品,很多工控电气工程师在选型和电路图设计时,对模块接线并不是非常清楚,为了使大家更好的了解和掌握该部分,本文从CPU本体、数字量输入(DI)、数字量输出(DQ)向大家详细介绍S7-200 SMART 详细的接线和注意事项。 不同型号C…

Linux学习之路 -- 进程篇 -- PCB介绍2 -- 标识符和进程创建

前面我们介绍了的进程的标识符&#xff0c;下面继续介绍进程标识符和进程创建的知识。 目录 一、进程创建 <1>fork函数的返回值 <2>创建子进程的目的 <3>代码共享 二、fork函数的相关问题 <1>为什么给父进程返回子进程的pid&#xff0c;给子进程…

OpenHarmony开发-系统烧录

本文详细介绍了烧录OpenHarmony系统到开发板的操作流程。从基础的硬件准备和软件环境设置入手&#xff0c;详细说明了如何配置开发环境、构建系统镜像等过程&#xff0c;详细描述了烧录过程中的关键步骤&#xff0c;以及如何使用专用工具将OpenHarmony系统镜像传输到开发板。同…

CSS层叠样式表学习(引入方式)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS引入方式的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 五、CSS的三种样式表 5.1 CSS的三种样式表 按照CSS样式书写的位置(或者引入方式)&#xff0c;CSS样式表可…

11-pyspark的RDD的变换与动作算子总结

目录 前言 变换算子动作算子 前言 一般来说&#xff0c;RDD包括两个操作算子&#xff1a; 变换&#xff08;Transformations&#xff09;&#xff1a;变换算子的特点是懒执行&#xff0c;变换操作并不会立刻执行&#xff0c;而是需要等到有动作&#xff08;Actions&#xff09;…

蓝桥杯每日一题:公约数(gcd)

题目描述&#xff1a; 给定两个正整数 a 和 b。 你需要回答 q 个询问。 每个询问给定两个整数 l,r&#xff0c;你需要找到最大的整数 x&#xff0c;满足&#xff1a; x 是 a和 b 的公约数。l≤x≤r。 输入格式 第一行包含两个整数 a,b。 第二行包含一个整数 q。 接下来…

并发包中的CompletableFuture介绍及使用示例

一、抛砖引玉——优化一个计数任务 1.1、需求&#xff1a;计算从1加累加到100的结果 1.1.1、普通的实现代码示例 package com.example.mavendemo.completablefuture;public class NormalTest {public static void main(String[] args) {long startTime System.currentTimeM…

C#开发中一些常用的工具类分享

一、配置文件读写类 用于在开发时候C#操作配置文件读写信息 1、工具类 ReadIni 代码 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;namesp…

LeetCode 1017. 负二进制转换

解题思路 相关代码 class Solution {public String baseNeg2(int n) {if(n0) return "0";String s"";while(n!0)if(Math.abs(n)%20){nn/(-2);ss0;}else{ss1; n (n-1)/(-2);}String t reverse(s);return t;}public String reverse(String s){Str…

ZYNQ学习Linux 基础外设的使用

基本都是摘抄正点原子的文章&#xff1a;《领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf》&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 工程的创建参考&#xff1a;《ZYNQ学习之Petalinux 设计流程实战》 一、GPIO 之 LED 的使…

自定义实现shell/bash

文章目录 函数和进程之间的相似性shell打印提示符&#xff0c;以及获取用户输入分割用户的输入判断是否是内建命令执行相关的命令 全部代码 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#…