首页 > 其他分享 >NEMU PA 2-2 实验报告

NEMU PA 2-2 实验报告

时间:2023-02-24 22:47:46浏览次数:42  
标签:文件 kernel ELF 装载 NEMU 地址 PA 指令 实验报告

课程地址:https://www.bilibili.com/video/BV1f7411D7P6

一、实验目的

在PA2-1中,我们实现了了解了程序的装载和对指令的解码和执行,在这一章节我们将继续深入了解程序的装载,以不同于原本直接copy的方式实现对程序的装载。

二、实验步骤

首先我们熟悉ELF可执行目标文件的结构,即认识ELF文件和ELF Header:

其中比较重要的有:

  • 节头表,这个表记录了文件分为多少个节,每个节(如.symtab节)在文件中的什么地方;
  • 程序头表,这个表记录了文件的哪一部分应该被搬到内存的哪个位置,我们在后面装载的实现中需要用到程序头表给出的信息。
  • 符号表和字符串表,PA2-3符号解析中需要用到,它们记录了某全局变量或函数对应内存的哪个地址。

我们在这一章需要做的,就是改变原本程序的装载方式,通过对ELF文件中程序头表的解析来装载程序。

  • 原本的装载方式:把ELF文件和镜像文件分别copy到DAMdisk区和物理内存区;

  • 新的装载方式:通过NEMU的操作系统,来将(已经copy到)DAMdisk区的ELF文件装载到物理内存区。这意味着我们不仅要装载样例文件,还要先把操作系统(kernel文件)先装载到内存中。(kernel的装载就直接copy,同原本的样例镜像文件的装载方式)

装载的步骤为:

  1. 由kernel解析测试用例的ELF文件并装载,装载起始位置为0X100000;
  2. 由kernel调整CPU的EIP到装载的起始位置0X100000;

现在,我们可以进行一下要点的梳理

  • 现阶段哪些文件是待装载的ELF文件?样例ELF文件。
  • ELF文件是由谁装载的?Kernel负责。
  • 现阶段在NEMU启动后待装载的ELF文件位于何处?Kernel的后面,0X100000处。
  • NEMU开机后执行的第一条指令是哪个地址?是哪个软件的指令?Kernel的起始地址,0X30000。
  • ELF文件被装载到哪个地址?0X100000。
  • 为了保证上述装载和执行地址的正确,需要修改Makefile。

接下来是重头戏,我们要实现对程序头表的解析:

  • 首先,我们可以通过readelf命令来观察需要装载的ELF文件的程序头表;

  • 上文我们提到,程序头表记录了文件的哪一部分应该被搬到内存的哪个位置,我们观察readelf给出的信息:

    可以发现Type为LOAD的节是需要装载的——ELF文件中从文件Offset开始位置,连续FileSiz个字节的内容需要被装载,装载到内存VirtAddr开始,连续MemSiz个字节的区域中,其中MemSiz可能大于FileSiz(.bss节的原因,这时候需要把内存中 VirtAddr + [FileSiz, MemSiz] 的区域清零)。

  • 好,我们现在进行装载。装载由kernel的loader程序来完成。其装载逻辑如下:

  • 通过阅读kernel/src/elf/elf.c处的代码(主要是loader()函数),我们可以再进行一次要点的梳理

    • Kernel中访问变量语句编译后对应什么指令?mov指令或者lea指令。

    • 这条指令由谁执行?访问的地址是多少?由cpu执行,访问地址需要看变量类型,但都在hw_mem[]数组地址的范围内。

    • 指令中的地址如何转换成对hw_mem[]的访问的?

      首先kernel里面的代码会编译成一条条指令(如memcpy会被编译成一条条mov指令),而这些指令操作的执行不是通过现实的机器来执行,而是像PA2-1一样,是依靠你自己实现的虚拟CPU来执行的,由你手搓的CPU进行指令的解码和执行。然后解码执行过程中,对地址的操作是由自己实现的operand_read/write来读/写的,operand_read/write调用了memory.c中封装好的读写函数进行转换(看最底层的hw_mem_read/write,这个时候的读写操作的解码执行才是现实CPU做的,要分清实机和虚拟机),避免了直接访问当前地址而造成的访问到了实际机器上的内存的问题。

      在这里我还要提醒自己:ELF文件放在实际机器可以靠实际机器的CPU运行,放在手搓虚拟机上就需要靠手搓的CPU运行。kernel也一样,这里的kernel也是一个img文件,它的执行环境决定了它需要靠你自己手搓的对ISA的实现上运行。一定要注意运行环境的不同!不然容易混糊,就像这一问。

  • 我们需要实现的代码部分位于该loader()函数中:

都到这一步了,我们来看看Kernel是如何执行loader()的:

kernel/start/start.S开始 --> 跳转到kernel/src/main.c中的init() --> 跳转到kernel/src/main.c中的init_cond()

--> 执行loader()函数,并由其返回可执行文件的EIP(通过ELF头得到) --> 得到EIP后我们就可以直接将它包装成函数指针,去跑装载好的测试用例。

整体的PA2-2代码要求如下:

  1. 修改testcase/MakefileLDFLAGS并make clean

  2. 实现Kernel中的loader();该代码位于kernel/src/elf/elf.c

  3. 使用make test_pa-2-2执行测试用例并通过。

三、思考题

这章节没有明确需要回答的思考题,以下是理解PA2-2过程中一些给出的要点的解答:

  • 现阶段哪些文件是待装载的ELF文件?样例ELF文件。

  • ELF文件是由谁装载的?Kernel负责。

  • 现阶段在NEMU启动后待装载的ELF文件位于何处?Kernel的后面,0X100000处。

  • NEMU开机后执行的第一条指令是哪个地址?是哪个软件的指令?Kernel的起始地址,0X30000。

  • ELF文件被装载到哪个地址?0X100000。

  • Kernel中访问变量语句编译后对应什么指令?mov指令或者lea指令。

  • 这条指令由谁执行?访问的地址是多少?由cpu执行,访问地址需要看变量类型,但都在hw_mem[]数组地址的范围内。

  • 指令中的地址如何转换成对hw_mem[]的访问的?

    首先kernel里面的代码会编译成一条条指令(如memcpy会被编译成一条条mov指令),而这些指令操作的执行不是通过现实的机器来执行,而是像PA2-1一样,是依靠你自己实现的虚拟CPU来执行的,由你手搓的CPU进行指令的解码和执行。然后解码执行过程中,对地址的操作是由自己实现的operand_read/write来读/写的,operand_read/write调用了memory.c中封装好的读写函数进行转换(看最底层的hw_mem_read/write,这个时候的读写操作的解码执行才是现实CPU做的,要分清实机和虚拟机),避免了直接访问当前地址而造成的访问到了实际机器上的内存的问题。

标签:文件,kernel,ELF,装载,NEMU,地址,PA,指令,实验报告
From: https://www.cnblogs.com/grapefruit-cat/p/17153409.html

相关文章

  • NEMU PA 2-1 实验报告
    课程地址:https://www.bilibili.com/video/BV1TE411P7tq一、实验目的通过PA2-0了解了汇编基础知识和如何去阅读i386手册后,在这个阶段我们就需要:了解程序执行的宏观过......
  • NEMU PA 2-3 实验报告
    课程地址:https://www.bilibili.com/video/BV1yC4y1s74C一、实验目的了解ELF符号表的解析进一步完善调试器的功能,理解编译器的设计原理二、实验步骤在PA2-1中实现......
  • jQuery插件-fullpage全屏幻灯片展示效果
    fullpage全屏插件全屏滚动效果,原生js也很好实现,主要是用mousewheel鼠标滚轮滚动事件,来判断上滚动还是下滚动,之后设置每次滚动的高度为屏幕的高度即可。但是,虽然效果简......
  • k8s-部署Nginx+Keepalived高可用负载均衡器
    本文章是 k8s二进制高可用集群部署 的分支。详细步骤请参考目录。Kubernetes集群高可用性包含以下两个层面的考虑:Etcd数据库的高可用性KubernetesMaster组件......
  • PAT Basic 1004. 成绩排名
    PATBasic1004.成绩排名1.题目描述:读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。2.输入格式:每个测试输入包含1个测试用例,格......
  • PAT Basic 1003. 我要通过!
    PATBasic1003.我要通过!1.题目描述:“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送——只要读入的字符串满足下列条件,系统......
  • pandas 常用方法使用示例
    #生成DataFrame,保存至文件frompandasimportDataFrameimportnumpyasnpimportpandasaspdt={"称呼":["爸爸","妈妈","宝宝"],"年龄":[18,30,np.......
  • 417. Pacific Atlantic Water Flow[Medium]
    417.PacificAtlanticWaterFlowThereisanmxnrectangularislandthatbordersboththePacificOceanandAtlanticOcean.ThePacificOceantouchestheisl......
  • java代码上传文件,接口consumes = "multipart/*",headers = "content-type=multipart/f
    publicstaticStringdoPost(Stringurl,StringfileName,Filefile){CloseableHttpClienthttpClient=null;CloseableHttpResponseresponse=null;Str......
  • 【笔记】springboot使用Spring-data-jpa
    Spring-data-jpaSpring-data-jpa依赖于Hibernate。通过整合Hibernate之后,我们以操作Java实体的⽅式最终将数据改变映射到数据库表中。添加依赖:<dependency<groupId......