步伐人生-Hello’s P2P

[复制链接]
发表于 2025-5-22 16:34:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
题     目  步伐人生-Hellos P2P 
专       业           将来技术学院             
学     号          2021113220              
班   级           21WL023             
学       生            崔传浩      
指 导 教 师             郑贵滨        
摘  要
本文主要阐述hello步伐在Linux系统的生命周期,探讨hello步伐从hello.c经过预处置处罚、编译、汇编、链接生成可执行文件的全过程。并结合课本的知识具体阐述我们的计算机系统是如何对hello进行进程管理、存储管理,通过对hello一生周期的探索,让我们对计算机系统有更深的了解。

关键词:Hello步伐;预处置处罚;编译;汇编;链接;进程;存储;虚拟内存        

目  录


第1章 概述

1.1 Hello简介

1.2 环境与工具

1.3 中心结果

1.4 本章小结

第2章 预处置处罚

2.1 预处置处罚的概念与作用

2.2在Ubuntu下预处置处罚的命令

2.3 Hello的预处置处罚结果解析

2.4 本章小结

第3章 编译

3.1 编译的概念与作用

3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果解析

3.4 本章小结

第4章 汇编

4.1 汇编的概念与作用

4.2 在Ubuntu下汇编的命令

4.3 可重定位目标elf格式

4.4 Hello.o的结果解析

4.5 本章小结

第5章 链接

5.1 链接的概念与作用

5.2 在Ubuntu下链接的命令

5.3 可执行目标文件hello的格式

5.4 hello的虚拟地址空间

5.5 链接的重定位过程分析

5.6 hello的执行流程

5.7 Hello的动态链接分析

5.8 本章小结

第6章 hello进程管理

6.1 进程的概念与作用

6.2 简述壳Shell-bash的作用与处置处罚流程

6.3 Hello的fork进程创建过程

6.4 Hello的execve过程

6.5 Hello的进程执行

6.6 hello的异常与信号处置处罚

6.7本章小结

第7章 hello的存储管理

7.1 hello的存储器地址空间

7.2 Intel逻辑地址到线性地址的变换-段式管理

7.3 Hello的线性地址到物理地址的变换-页式管理

7.4 TLB与四级页表支持下的VA到PA的变换

7.5 三级Cache支持下的物理内存访问

7.6 hello进程fork时的内存映射

7.7 hello进程execve时的内存映射

7.8 缺页故障与缺页中断处置处罚

7.9动态存储分配管理

7.10本章小结

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

8.2 简述Unix IO接口及其函数

8.3 printf的实现分析

8.4 getchar的实现分析

8.5本章小结

结论

附件

参考文献


第1章 概述


1.1 Hello简介

P2P:在Linux中,hello.c经过cpp的预处置处罚、ccl的编译、as的汇编、ld的链接最终成为可执行目标步伐hello,在shell中键入启动命令后,shell为其fork产生一个子进程,然后hello便从步伐变为了进程。

020: shell为此子进程execve,映射虚拟内存,进入步伐入口后步伐开始载入物理内存,然后进入 main函数执行目标代码,CPU为运行的hello分配时间片执行逻辑控制流。当步伐运行竣事后,shell父进程负责接纳hello进程,内核删除相干数据结构。
1.2 环境与工具

硬件环境:X64 CPU;2GHz;2G RAM;256GHD Disk

软件环境:Windows10;Vmware 12;Ubuntu 16.04 LTS 64位

开发与调试工具:gcc,vim,edb,readelf,HexEdit

1.3 中心结果

hello.i    hello.c预处置处罚之后文本文件

hello.s   hello.i编译后的汇编文件

hello.o  hello.s汇编之后的可重定位目标文件

Hello  链接之后的可执行目标文件

hello.out    hello反汇编之后的可重定位文件

1.4 本章小结

本章大致主要简单介绍了 hello 的 p2p,020 过程,列出了本次实验信息:环境、中心结果,而且大致简介了hello步伐从c步伐hello.c到可执行目标文件hello的大致经过的历程。
第2章 预处置处罚


2.1 预处置处罚的概念与作用

概念:预处置处罚器cpp根据以字符#开头的命令(宏定义、条件编译),修改原始的C步伐,将引用的全部库睁开合并成为一个完备的文本文件。
作用:
1.处置处罚宏定义指令
2. 处置处罚条件编译指令
3.处置处罚头文件
4.处置处罚特殊符号
2.2在Ubuntu下预处置处罚的命令

gcc hello.c -E -o hello.i

2.3 Hello的预处置处罚结果解析

经过预处置处罚之后,hello.c转化为hello.i文件,打开该文件可以发现,文件的内容增长,且仍为可以阅读的C语言步伐文本文件。而且源文件中的部分指令也得到了优化。
2.4 本章小结

本章介绍了预处置处罚的相干概念及其所进行的一些处置处罚,例如实现将定义的宏进行符号替换、引入头文件的内容、根据指令进行选择性编译等。
第3章 编译


3.1 编译的概念与作用

编译的概念:编译器将文本文件 hello.i 翻译成文本文件 hello.s,它包罗一个汇编语言步伐。其以源步伐作为输入,而以汇编语言或机器语言表现的目标步伐作为输出。。
编译步伐的基本功能是把源步伐(高级语言)翻译成目标步伐。

3.2 在Ubuntu下编译的命令

gcc -S hello.i -o hello.s    

3.3 Hello的编译结果解析

.file:声明源文件
.text:代码
.rodata:只读代码
.align:数据或者指令的地址对其方式
.string:声明一个字符串(.LC0,.LC1)
.global:声明全局变量(main)
.type:声明一个符号是数据类型还是函数类型
字符串:LC0、LC1

局部变量L2
数组

L4建立了一个数组

赋值:用mov指令进行赋值
movb:一个字节
movw:两个字节
movl:四个字节
movq:八个字节

逻辑判断
!=不等于
<小于
>大于

计算
Lea S,D 将S地址转移到D
Add S,D D=D+S
Sub S,D D=D-S
Sal S,D D=D<<S
Imul S,D D=D*S

跳跃指令
判断是否符合条件,符合条件则跳转到后面地址


类型转换
hello.c中涉及的类型转换是:atoi(argv[3]),将字符串类型转换为整数类型其他的类型转换另有int、float、double、short、char之间的转换

3.4 本章小结

本章主要陈诉了在编译阶段中编译器如那边置处罚各种数据和操作,以及c语言中各种类型和操作所对应的的汇编代码。在经过本章的学习过后我们对C语言和汇编代码之间的转换有了更好地理解

                                            第4章 汇编



4.1 汇编的概念与作用


汇编器(as)将汇编步伐翻译成机器语言指令,把这些指令打包成可重定位目标步伐的格式,并将结果保存在.o 目标文件中,.o 文件是一个二进制文件,它包罗步伐的指令编码。

4.2 在Ubuntu下汇编的命令

gcc hello.s -c -o hello.o
4.3 可重定位目标elf格式

ELF Header:Magic 描述了生成该文件的系统 的字的大小和字节次序,剩下的部分包罗链接器语法资助分析,讲授了 ELF 头的大小、目标文件的类型、机器类型、 以及节头部表中条目标大 小和数量等信息。
头部表:包罗了文件中出现的各个节的语义,包罗节 的类型、位置和大小等信息。在该位置的代码可运行,但不可编写,数据段不可运行
符号表:存放步伐中定义和引用的函数和全局变量的信息。
4.4 Hello.o的结果解析

与汇编语言的代码指令相比,反汇编代码无太大变化,只是反汇编代码所显示的不仅仅是汇编代码,另有机器代码。机器指令由操作码和操作数构成,而汇编语言是人们比较熟悉的词句直接表述CPU动作形成的语言。每一条汇编语言和机器语言是对应关系。

(1)分支转移:反汇编的跳转指令用的确定的地址。

(2)函数调用:在hello.s 文件中,函数调用之后直接跟着函数名称,而在反汇编程 序中,call的目标地址是当前下一条指令。

4.5 本章小结


本章对hello.s进行了汇编,生成了hello.o可重定位目标文件,而且分析了可重定位文件的ELF头、节头部表、符号表和可重定位节,比较了hello.s和hello.o反汇编代码的不同之处,分析了从汇编语言到机器语言的一一映射关系。
5链接


5.1 链接的概念与作用

链接是将各种代码和数据片段收集并组合成一个单一文件的过程,这个文件可被加载(复制)到内存并执行。链接可以执行于编译时,也就是在源代码被编译成机器代 码时;也可以执行于加载时,也就是在步伐被加载器加载到内存并执行时;乃至于运行时,也就是由应用步伐来执行。链接是由叫做链接器的步伐执行的。链接器使得分离编译成为大概。

5.3 可执行目标文件hello的格式

    

节头部表 对 hello中全部的节信息进行了声明,其 中包罗大小以及在步伐中的偏移量,因此根据节头部表中的信息我们就可以用 HexEdit 定位各个节所占的区间(起始位置,大小)。此中 Address 是步伐被载入到虚拟地址的起始地址。
5.4 hello的虚拟地址空间

ELF虚拟地址始于ox4011a0终止于ox401240
   
5.5 链接的重定位过程分析



(1)重定位节和符号定义链接器将全部类型相同的节合并在一起后,这个节就作为可执行目标文件的节。然后链接器把运行时的内存地址赋给新的聚合节,赋给输入模块定义的每个节,以及赋给输入模块定义的每个符号,当这一步完成时,步伐中每条指令和全局变量都有唯一运行时的地址。

(2)重定位节中的符号引用这一步中,毗连器修改代码节和数据节中对每个符号的引用,使他们指向准确的运行时地址。执行这一步,链接器依靠于可重定位目标模块中称为的重定位条目标数据结构。

(3)重定位条目当编译器遇到对最终位置未知的目标引用时,它就会生成一个重定位条目。
5.6 hello的执行流程


5.7 Hello的动态链接分析

  动态链接的基本头脑是把步伐按照模块拆分成各个相对独立部分,在步伐运行时才将它们链接在一起形成一个完备的步伐。固然动态链接把链接过程推迟
到了步伐运行时,但是在形成可执行文件时,还是需要用到动态链接库。
在调用共享库函数时,编译器没有办法预测这个函数的运行时地址,因为定义它的共享模块在运行时可以加载到任意位置。正常的方法是为该引用生成一条重定位记录,然后动态链接器在步伐加载的时候再解析它。GNU编译系统使用延长绑定,将过程地址的绑定推迟到第一次调用该过程时。
延长绑定是通过GOT和PLT实现的。GOT是数据段的一部分,而PLT是代码段的一部分。两表内容分别为:
PLT:PLT是一个数组,此中每个条目是16字节代码。PLT[0]是一个特殊条目,它跳转到动态链接器中。每个被可执行步伐调用的库函数都有它本身的PLT条目。每个条目都负责调用一个具体的函数。
GOT:GOT是一个数组,此中每个条目是8字节地址。和PLT连合使用时,GOT[O]和GOT[1]包罗动态链接器在解析函数地址时会使用的信息。GOT[2]是动态链接器在1d-linux.so模块中的入口点。其余的每个条目对应于一个被调用的函数,其地址需要在运行时被解析。每个条目都有一个相匹配的PLT条目。
如图所示,GOT起始地址在ox404000
5.8 本章小结

在本章中主要介绍了链接的概念与作用,而且具体阐述了hello.o是怎么链接成为一个可执行目标文件的过程,具体介绍了hello.o的ELF格式和各个节的含义,而且分析了hello的虚拟地址空间、重定位过程、执行流程、动态链接过程。


6hello进程管理


6.1 进程的概念与作用

进程是一个执行中的步伐的实例,每一个进程都有它本身的地址空间,一般情 况下,包罗文本区域、数据区域、和堆栈。文本区域存储处置处罚器执行的代码;数 据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储区着运动 过程调用的指令和当地变量。



作用:进程为用户提供了以下假象:

(1) 我们的步伐好像是系统中当前运行的唯一步伐一样,我们的步伐好像是独占的使用处置处罚器和内存。

(2) 处置处罚器好像是无间断的执行我们步伐中的指令,我们步伐中的代码和数据好像是系统内存中唯一的对象。


6.2 简述壳Shell-bash的作用与处置处罚流程

Linux系统中,Shell是一个交互型应用级步伐,代表用户运行其他步伐。

其基本功能是表明并运行用户的指令,重复如下处置处罚过程:

(1)终端进程读取用户由键盘输入的命令行。

(2)分析命令行字符串,获取命令行参数,并构造传递给execve的argv向量

(3)查抄第一个命令行参数是否是一个内置的shell命令

(4)如果不是内部命令,调用fork( )创建新进程/子进程

(5)在子进程中,用步骤2获取的参数,调用execve( )执行指定步伐。

(6)如果用户没要求后台运行否则shell使用waitpid等待作业终止后返回。

(7)如果用户要求后台运行,则shell返回;

6.3 Hello的fork进程创建过程

终端步伐通过调用fork()函数创建一个子进程,子进程得到与父进程完全相同但是独立的一个副本,两个进程的不同在于他们的PID是不同的。父进程与子进程是并发运行的独立进程,内核可以或许以任意方式交替执行它们的 逻辑控制流的指令。在子进程执行期间,父进程默认选项是显示等待子进程的完成。

以我们的hello为例,当我们输入 ./hello 1180800811 张瑞豪 1 的时候,首先shell对我们输入的命令进行解析,由于我们输入的命令不是一个内置的shell命令,因此shell会调用fork()创建一个子进程。

6.4 Hello的execve过程

当创建了一个子进程之后,子进程调用exceve函数在当前子进程的上下文加载并运行一个新的步伐即hello步伐,加载并运行需要以下几个步骤:

(1)删除已存在的用户区域。删除当前进程虚拟地址的用户部分中已存在的区域结构。

(2)映射私有区域。为新步伐的代码、数据、bss和栈区域创建新的区域结构。虚拟地址空间的代码和数据区域被映射为hello文件的.txt和.data区。bss区域是请求二进制零的,映射匿名文件,其大小包罗在hello文件中。栈和堆区域也是请求二进制零的,初始长度为零。

(3)映射共享区域。如果hello步伐与共享对象链接,好比尺度C库libc.so,那么这些对象都是动态链接到这个步伐的,然后再映射到用户虚拟地址空间中的共享区域。

(4)设置步伐计数器(PC)。exceve做的最后一件事就是设置当前进程的上下文中的步伐计数器,使之指向代码区域的入口点。下一次调用这个进程时,它将从这个入口点开始执行。

除了一些头部信息,在加载过程中没有任何从磁盘到内存的数据 复制。直到 CPU 引用一个被映射的虚拟页时才会进行复制,这时,操作系统利用 它的页面调理机制主动将页面从磁盘传送到内存。
6.5 Hello的进程执行

进程提供给应用步伐的抽象:
(1) 一个独立的逻辑控制流,它提供一个假象,好像我们的进程独占的使用处置处罚器
(2) 一个私有的地址空间,它提供一个假象,好像我们的步伐独占的使用CPU内存。
hello进程的执行是依靠于进程所提供的抽象的基础上,下面阐述操作系统所提供的的进程抽象:

①逻辑控制流::一系列步伐计数器 PC 的值的序列叫做逻辑控制流,进程是轮流 使用处置处罚器的,在同一个处置处罚器核心中,每个进程执行它的流的一部分后被抢占 (暂时挂起),然后轮到其他进程。

②并发流:一个逻辑流的执行时间与另一个流重叠,成为并发流。个流并发的执行的一般现象成为并发。

③时间片:一个进程执行它的控制流的一部分的每一时间段叫做时间片。

④私有地址空间:进程为每个流都提供一种假象,好像它是独占的使用系统地址空间。

⑤用户模式和内核模式::处置处罚器通常使用一个寄存器提供两种模式的区分,该寄 存器描述了进程当前享有的特权,当没有设置模式位时,进程就处于用户模式中, 用户模式的进程不允许执行特权指令,也不允许直接引用地址空间中内核区内的 代码和数据;设置模式位时,进程处于内核模式,该进程可以执行指令会集的任 何命令,而且可以访问系统中的任何内存位置。

⑥上下文信息:上下文就是内核重新启动一个被抢占的进程所需要的状态,它由 通用寄存器、浮点寄存器、步伐计数器、用户栈、状态寄存器、内核栈和各种内 核数据结构等对象的值构成。

⑦上下文切换:当内核选择一个新的进程运行时,则内核调理了这个进程。在内核调理了一个新的进程运行后,它就抢占当前进程,并使用一种称为上下文切换的机制来将控制转移到新的进程:
1) 保存从前进程的上下文
2)恢复新恢复进程被保存的上下文,
3)将控制传递给这 个新恢复的进程 ,来完成上下文切换。

而hello进程执行,在进程调用execve函数之后,进程已经为hello步伐分配了新的虚拟的地址空间,而且已经将hello的.txt和.data节分配虚拟地址空间的代码区和数据区。最初hello运行在用户模式下,输出hello步伐,然后hello调用sleep函数之后进程陷入内核模式,内核不会选择什么都不做等待sleep函数调用竣事,而是处置处罚休眠请求主动开释当前进程,并将hello进程从运行队列中移出参加等待队列,定时器开始计时,内核进行上下文切换将当前进程的控制权交给其他进程,当定时器到时发送一个中断信号,此时进入内核状态执行中断处置处罚,将hello进程从等待队列中移出重新参加到运行队列,成为停当状态,hello进程就可以继续进行本身的控制逻辑流了。
当hello调用getchar的时候,实际落脚到执行输入流是stdin的系统调用read,hello之前运行在用户模式,在进行read调用之后陷入内核,内核中的陷阱处置处罚步伐请求来自键盘缓冲区的DMA传输,而且安排在完成从键盘缓冲区到内存的数据传输后,中断处置处罚器。此时进入内核模式,内核执行上下文切换,切换到其他进程。当完成键盘缓冲区到内存的数据传输时,引发一个中断信号,此时内核从其他进程进行上下文切换回hello进程
6.6 hello的异常与信号处置处罚

中断:在hello步伐执行的过程中大概会出现外部I/O设备引起的异常。

陷阱:陷阱是故意的异常,是执行一条指令的结果,hello执行sleep函数的时候会出现这个异常。

故障:在执行hello步伐的时候,大概会发生缺页故障。

终止:终止时不可恢复的错误,在hello执行过程大概会出现DRAM或者SRAM位损坏的奇偶错误。

在发生异常时会发出信号,好比缺页故障会导致OS发生SIGSEGV信号给用户进程,而用户进程以段错误退出。

第一个按下ctrl-z的异常
图6.6.2按下 ctrl-z 的结果,输入ctrl-z默认结果是挂起前台的作业,hello进程并没有接纳,而是运行在后台下,用ps命令可以看到,hello进程并没有被接纳。,调用 fg 将其调到前台,此时 shell 步伐首先打印 hello 的命令行命令, hello 继续运行打印剩下的 6 条 info,之后输入字串,步伐竣事,同时进程被接纳。
第二个按下ctrl-c的异常

图6.6.5是按下Ctrl+c的结果,在键盘上输入Ctrl+c会导致内核发送一个SIGINT信号到前台进程组的每个进程,默认情况是终止前台作业,用ps检察前台进程组发现没有hello进程。


第三个异常乱按

步伐运行过程中按键盘,不绝乱按,可以发现,乱按只是将屏幕的输入缓存到 stdin,当 getchar 的时候读出一个’\n’结尾的字串(作为一次输入),其他字串会当做 shell 命令行输入。



6.7本章小结
在本章中,阐述进程的定义与作用,同时介绍了 Shell 的一般处置处罚流程和作用,而且偏重分析了调用 fork 创建新进程,调用 execve函数 执行 hello,hello的进程执行,以及hello 的异常与信号处置处罚。
                                                    第7章 hello的存储管理

7.1 hello的存储器地址空间

逻辑地址:步伐经过编译后出现在汇编代码中的地址。逻辑地址用来指定一个操作数或者是一条指令的地址。是由一个段标识符加上一个指定段内相对地址的偏移量,表现为 [段标识符:段内偏移量]。

线性地址:也叫虚拟地址,和逻辑地址类似,也是一个不真实的地址,如果逻辑地址是对应的硬件平台段式管理转换前地址的话,那么线性地址则对应了硬件也是内存的转换前地址。

虚拟地址:也就是线性地址。

物理地址:用于内存芯片级的单位寻址,与处置处罚器和CPU链接的地址总线相对应。可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是究竟上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。大概错误的理解更利于形而上的抽像。

7.2 Intel逻辑地址到线性地址的变换-段式管理

一个逻辑地址由两部份组成,段标识符: 段内偏移量。段标识符是由一个16位长的字段组成,称为段选择符。此中前13位是一个索引号。后面3位包罗一些硬件细节,表现具体的是代码段寄存器还是栈段寄存器抑或是数据段寄存器。

索引号就是“段描述符(segment descriptor)”的索引,段描述符具体地址描述了一个段。很多个段描述符,就组了一个数组,叫“段描述符表”,这样,可以通过段标识符的前13位,直接在段描述符表中找到一个具体的段描述符,这句话很关键,阐明段标识符的具体作用,每一个段描述符由8个字节组成。

Base字段,表现的是包罗段的首字节的线性地址,也就是一个段的开始位置的线性地址。一些全局的段描述符,就放在“全局段描述符表(GDT)”中,一些局部的,例如每个进程本身的,就放在所谓的“局部段描述符表(LDT)”中。那究竟什么时候该用GDT,什么时候该用LDT呢?这是由段选择符中的T1字段表现的,=0,表现用GDT,=1表现用LDT,GDT在内存中的地址和大小存放在CPU的gdtr控制寄存器中,而LDT则在ldtr寄存器中。
7.3 Hello的线性地址到物理地址的变换-页式管理

由课本知识点可知,线性地址到物理地址之间的转换通过分页机制完成。而分页机制是对虚拟地址内存空间进行分页。
使用虚拟寻址,CPU通过生成一个虚拟地址来访问主存,这个虚拟地址被送到内存之前首先转换为适当的物理地址。这一步叫做地址翻译,需要CPU硬件和操作系统之间的紧密互助。CPU芯片上叫做内存管理单位,利用主存中的查询表来动态翻译虚拟地址。
虚拟地址作为到磁盘上存放字节的数组的索引,磁盘上的数组内容被缓存在主存中。同时,磁盘上的数据被分割成块,这些块作为磁盘和主存之间的传送单位。虚拟内存分割被成为虚拟页。物理内存被分割为物理页,物理页和虚拟页的大小时相同的。
任意时候虚拟页都被分为三个不相交的子集:
未分配的:VM系统还未分配的页
缓存的:当前已经缓存在物理内存的已分配页
未缓存的:当前未缓存在物理内存的已分配页

每次将虚拟地址转换为物理地址,都会查询页表来判断一个虚拟页是否缓存在DRAM的某个地方,如果不在DRAM的某个地方,通过查询页表条目可以知道虚拟页在磁盘的位置。页表将虚拟页映射到物理页。页表就是一个页表条目标数组,每一个页表条目是由一个有用位和一个n为地址字段组成。有用位表明虚拟页是否缓存在DRAM中,n位地址字段是物理页的起始地址或者虚拟页在次胖的起始地址。
7.4 TLB与四级页表支持下的VA到PA的变换

虚拟地址空间 48 位,物理地址空间 52 位,页表大小 4KB,4 级页表。TLB 4 路 16 组相联。CR3 指向第一级页表的起始位置(上下文一部分)。 解析条件条件:由一个页表大小 4KB,一个 PTE 条目8B,共 512 个条目,使 用 9 位二进制索引,一共 4 个页表共使用 36 位二进制索引,所以 VPN 共 36 位, 因为 VA 48 位,所以 VPO 12 位;因为 TLB 共 16 组,所以 TLBI 需 4 位,因为 VPN 36 位,所以 TLBT 32 位。
n位的虚拟地址包罗两个部分:一个p位的虚拟页面偏移(VPO),一个n-p位的虚拟页号(VPN),MMU利用VPN选择适当的PTE,例如VPN 0选择PTE 0。根据PTE,我们知道虚拟页的信息,如果虚拟页是已缓存的,那直接将页表条目标物理页号和虚拟地址的VPO串联起来就得到一个相应的物理地址。这里的VPO和PPO是相同的。如果虚拟页是未缓存的,会触发一个缺页故障。调用一个缺页处置处罚子步伐将磁盘的虚拟页重新加载到内存中,然后再执行这个导致缺页的指令。

7.5 三级Cache支持下的物理内存访问

假设Cashe1的物理内存访问原理与Cashe2,Cashe3相同。

由于L1Cashe有64组,所以组索引位s为6,每组有8个高速缓存行,由于每个块的大小为64B,所以块偏移为为6,因此标记位为52-6-6=40位。

因此L1Cashe的物理访存大致过程如下:

(1) 组选择取出虚拟地址的组索引位,将二进制组索引转化为一个无符号整数,找到相应的组



(2) 行匹配把虚拟地址的标记为拿去和相应的组中全部行的标记位进行比较,当虚拟地址的标记位和高速缓存行的标记位匹配时,而且高速缓存行的有用位是1,则高速缓存命中。



(3) 字选择一旦高速缓存命中,我们就知道我们要找的字节在这个块的某个地方。因此块偏移位提供了第一个字节的偏移。把这个字节的内容取出返回给CPU即可



(4)不命中如果高速缓存不命中,那么需要从存储层次结构中的下一层取出被请求的块,然后将新的块存储在组索引位所指示的组中的一个高速缓存行中。一种简单的 放置策略如下:如果映射到的组内有空闲块,则直接放置,否则组内都是有用块, 产生辩论(evict),则采用近来最少使用策略 LFU 进行替换。如图7.5所示



7.6 hello进程fork时的内存映射

当 fork 函数被 shell 进程调用时,内核为新进程创建各种数据结构,并分配给 它一个唯一的 PID,为了给这个新进程创建虚拟内存,它创建了当前进程的 mm_struct、区域结构和页表的原样副本。它将这两个进程的每个页面都标记为只 读,并将两个进程中的每个区域结构都标记为私有的写时复制。



7.7 hello进程execve时的内存映射

execve 函数调用驻留在内核区域的启动加载器代码,在当前进程中加载并运 行包罗在可执行目标文件 hello 中的步伐,用 hello 步伐有用地替代了当前步伐。 加载并运行 hello 需要以下几个步骤:



1)删除已存在的用户区域,删除当前进程虚拟地址的用户部分中的已存 在的区域结构。

2)映射私有区域,为新步伐的代码、数据、bss 和栈区域创建新的区域结 构,全部这些新的区域都是私有的、写时复制的。代码和数据区域被映射为 hello 文件中的.text 和.data 区,bss 区域是请求二进制零的,映射到匿名 文件,其大小包罗在 hello 中,栈和堆地址也是请求二进制零的,初始长 度为零。

3)映射共享区域, hello 步伐与共享对象 libc.so 链接,libc.so 是动态链 接到这个步伐中的,然后再映射到用户虚拟地址空间中的共享区域内。

4)设置步伐计数器(PC),execve 做的最后一件事变就是设置当前进程 上下文的步伐计数器,使之指向代码区域的入口点。



7.8 缺页故障与缺页中断处置处罚

缺页故障:当指令引用一个相应的虚拟地址,而与改地址相应的物理页面不再内存中,会触发缺页故障。通过查询页表PTE可以知道虚拟页在磁盘的位置。缺页处置处罚步伐从指定的位置加载页面 到物理内存中,并更新PTE。然后控制返回给引起缺页故障的指令。当指令再次执行时,相应的物理页面已经驻留在内存中,因此指令可以没有故障的运行完成。

7.9本章小结

在这一章了解hello的存储器的地址空间,学习了四种地址空间的差别以及虚拟地址和物理地址的相互转换。同时介绍了hello的四级页表的虚拟地址空间到物理地址的转换。阐述了三级cashe的物理内存访问、进程 fork 时的内存映射、execve 时的内存映射、缺页故障与缺页中断处置处罚。
结论

hello.c:编写c步伐,hello.c诞生,它是一个二进制文本文件,hell中的每个字符都是用ascall编码表现。

hello.i:hello.c经过预处置处罚阶段变为hello.i。

hello.s:hello.i经过编译阶段变为hello.s。

hello.o:hello.s经过汇编阶段变为hello.o。

hello:hello.o与可重定位目标文件和动态链接库链接成为可执行文件hello。至此可执行hello步伐正式诞生。

创建子进程:由于终端输入的不是一个内置的shell命令,因此shell调用fork()函数创建一个子进程。

加载:shell 调用 execve,execve 调用启动加载器,加映射虚拟内 存,进入步伐入口后步伐开始载入物理内存,然后进入 main 函数。

上下文切换:hello调用sleep函数之后进程陷入内核模式,处置处罚休眠请求主动开释当前进程,内核进行上下文切换将当前进程的控制权交给其他进程,当sleep函数调用完成时,内核执行上下文切换将控制传递给当前进程。

信号管理:当步伐在运行的时候我们输入Ctrl+c,内核会发送SIGINT信号给进程并终止前台作业。当输入Ctrl+z时,内核会发送SIGTSTP信号给进程,并将前台作业制止挂起。

终止:当子进程执行完成时,内核安排父进程接纳子进程,将子进程的退出状态传递给父进程。内核删除为这个进程创建的全部 数据结构。

计算机系统的设计精巧:为了办理快的设备存储小、存储大的设备慢的不均衡,设计了高速缓存来作为更底层的存储设备的缓存,大大进步了CPU访问主存的速度!!!

计算机系统的设计考虑全面:计算机系统设计考虑统统大概的实际情况,设计出一系列的满足不同情况的策略。好比写回和直写,写分配和非写分配,直接映射高速缓存和组相连高速缓存等等。


附件


Hello.i   hello.c预处置处罚之后的文件

Hello.s   hello.i编译之后的文件

Hello.o   hello.s汇编之后的可重定位目标文件

Hello    链接之后的可执行目标文件

Hello.out  hello反汇编之后的可重定位的目标文件


参考文献

[1]  林来兴. 空间控制技术[M]. 北京:中国宇航出书社,1992:25-42.
[2]  辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出书社,1999.
[3]  赵耀东. 新期间的工业工程师[M/OL]. 台北:天下文化出书社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
[4]  谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5]  KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
[6]  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表