雁过留声 发表于 昨天 07:39

hitics 计算机系统 大作业 步伐人生 Hello‘s P2P


摘  要
本文借由hello从预处理到IO管理的整个过程,简单分析了其中涉及的计算机系统的知识与内容,包罗:编译与链接、进程管理、存储管理、系统级I/O等,简述了hello的一生是怎样度过的。
关键词:计算机系统;编译;进程;存储;I/O                        









目  录

第1章 概述............................................................................................................. - 4 -
1.1 Hello简介...................................................................................................... - 4 -
1.2 环境与工具..................................................................................................... - 4 -
1.3 中心结果......................................................................................................... - 4 -
1.4 本章小结......................................................................................................... - 4 -
第2章 预处理......................................................................................................... - 5 -
2.1 预处理的概念与作用..................................................................................... - 5 -
2.2在Ubuntu下预处理的下令.......................................................................... - 5 -
2.3 Hello的预处理结果解析.............................................................................. - 5 -
2.4 本章小结......................................................................................................... - 5 -
第3章 编译............................................................................................................. - 6 -
3.1 编译的概念与作用......................................................................................... - 6 -
3.2 在Ubuntu下编译的下令............................................................................. - 6 -
3.3 Hello的编译结果解析.................................................................................. - 6 -
3.4 本章小结......................................................................................................... - 6 -
第4章 汇编............................................................................................................. - 7 -
4.1 汇编的概念与作用......................................................................................... - 7 -
4.2 在Ubuntu下汇编的下令............................................................................. - 7 -
4.3 可重定位目标elf格式................................................................................. - 7 -
4.4 Hello.o的结果解析...................................................................................... - 7 -
4.5 本章小结......................................................................................................... - 7 -
第5章 链接............................................................................................................. - 8 -
5.1 链接的概念与作用......................................................................................... - 8 -
5.2 在Ubuntu下链接的下令............................................................................. - 8 -
5.3 可实行目标文件hello的格式.................................................................... - 8 -
5.4 hello的假造地址空间.................................................................................. - 8 -
5.5 链接的重定位过程分析................................................................................. - 8 -
5.6 hello的实行流程.......................................................................................... - 8 -
5.7 Hello的动态链接分析.................................................................................. - 8 -
5.8 本章小结......................................................................................................... - 9 -
第6章 hello进程管理................................................................................... - 10 -
6.1 进程的概念与作用....................................................................................... - 10 -
6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -
6.3 Hello的fork进程创建过程..................................................................... - 10 -
6.4 Hello的execve过程................................................................................. - 10 -
6.5 Hello的进程实行........................................................................................ - 10 -
6.6 hello的非常与信号处理............................................................................ - 10 -
6.7本章小结....................................................................................................... - 10 -
第7章 hello的存储管理................................................................................ - 11 -
7.1 hello的存储器地址空间............................................................................ - 11 -
7.2 Intel逻辑地址到线性地址的变换-段式管理............................................ - 11 -
7.3 Hello的线性地址到物理地址的变换-页式管理....................................... - 11 -
7.4 TLB与四级页表支持下的VA到PA的变换............................................. - 11 -
7.5 三级Cache支持下的物理内存访问.......................................................... - 11 -
7.6 hello进程fork时的内存映射.................................................................. - 11 -
7.7 hello进程execve时的内存映射.............................................................. - 11 -
7.8 缺页故障与缺页中断处理........................................................................... - 11 -
7.9动态存储分配管理....................................................................................... - 11 -
7.10本章小结..................................................................................................... - 12 -
第8章 hello的IO管理................................................................................. - 13 -
8.1 Linux的IO装备管理方法.......................................................................... - 13 -
8.2 简述Unix IO接口及其函数....................................................................... - 13 -
8.3 printf的实现分析........................................................................................ - 13 -
8.4 getchar的实现分析.................................................................................... - 13 -
8.5本章小结....................................................................................................... - 13 -
结论......................................................................................................................... - 14 -
附件......................................................................................................................... - 15 -
参考文献................................................................................................................. - 16 -



第1章 概述

1.1 Hello简介

首先,步伐员敲代码敲出一个hello.c源文件,然后进行预处理、编译、汇编、链接等步骤天生可实行文件hello。
在shell里输入./hello以运行这个步伐。Shell先给它fork一个进程,然后通过execve将hello步伐加载到内存中。假造内存机制通过mmap为hello进程分配了假造空间,调度器为它分配时间片。(P2P)
CPU逐条从.text段取指令,syscall让进程陷入内核,实行write。
末了通过waitpid,内核回收该进程,所占用的处理器及内存资源被开释。(020)。
1.2 环境与工具

硬件环境:处理器11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
软件环境:Windows、Linux Ubuntu
1.3 中心结果

hello.c:源文件。
hello.i:预处理文件。(ASCII码)
hello.s:汇编语言文件。
hello.o:可冲定位目标文件。
1.4 本章小结

       hello.c先通过编译天生可实行文件,然后操作系统来实行可实行文件,包罗为步伐创建进程、分配内存、分配CPU占用、I/O流、回收等,表现了hello的P2P和020。
(第1章0.5分)



第2章 预处理

2.1 预处理的概念与作用

概念:预处理是指在系统对源步伐(.c文件)进行编译之前,对步伐中某些特殊的下令行进行处理的过程。预处理步伐会根据这些预处理指令对源代码进行修改或调整,然后天生一个预处理后的文件(以.i为扩展名),供后续的编译阶段使用。
作用:移除表明、文件包含(如处理#include)、宏界说更换(处理#define)、优化代码格式等。
2.2在Ubuntu下预处理的下令

https://i-blog.csdnimg.cn/direct/6ad01bbdb0d6492bb49b3cc54ffe5e00.png
2.3 Hello的预处理结果解析

天生了hello.i文件,发现#include<stdio.h>等被更换成了stdio.h等的代码。
2.4 本章小结

预处理主要进行宏更换,hello.c文件经过预处理天生了hello.i文件。

(第2章0.5分)

第3章 编译

3.1 编译的概念与作用

概念:编译是指利用编译器将与处理后的代码转换为汇编代码的过程。
作用:词法分析、语义检查、中心代码天生、优化(删除冗余代码、公共子表达式消除等)等。
3.2 在Ubuntu下编译的下令​​​​​​​

https://i-blog.csdnimg.cn/direct/89a560327b8a49f9b7ce4d96264fd999.png
3.3 Hello的编译结果解析

3.3.1 数据
3.3.1.1.整型常量被编译为立即数。如argc!=5中的5以及exit(1)中的1。如下图:https://i-blog.csdnimg.cn/direct/4496f3b31a37429bbf3130469625ade1.png

https://i-blog.csdnimg.cn/direct/61eb3977d8d94ababb1a47af434bacd8.png

3.3.1.2.字符型常量被生存在只读代码段.rodata,在使用的时候取其地址传参。
https://i-blog.csdnimg.cn/direct/d956731f5d364abb8f0f2fb032a4fb18.png

https://i-blog.csdnimg.cn/direct/e4e5256b9b0f42319795ba7c1cde79d7.png

https://i-blog.csdnimg.cn/direct/3e44248c35de45d085149c55d81373bc.png

3.3.1.3.局部变量i在界说的时候没赋初值,编译器没管它。

3.3.2 赋值
在for循环中,先对i赋初值0,如下图:
https://i-blog.csdnimg.cn/direct/3df3590d9a4c4765a0240739e9ce7fd8.png

3.3.3 类型转换
atoi(argv)返回的类型是int,而sleep()要求参数为unsigned int,发生隐式类型转换。但在汇编语言中没有表现。atoi的返回值在rax,rax把值给edi作为sleep的参数。如下图:
https://i-blog.csdnimg.cn/direct/757ab985783a41ae92791808769e504c.png

3.3.4 算术操作
for循环中的i++,编译器在栈中给i加1,如下图:
https://i-blog.csdnimg.cn/direct/dfd01074fcec46959e4de1a0d8c6d402.png

3.3.5关系操作
编译器通常通过cmp + jum 语句组合进行比力、转移。如下图:
argc!=5:
https://i-blog.csdnimg.cn/direct/1f650fe901a240878d36530702f9363a.png
;i<9:
https://i-blog.csdnimg.cn/direct/3586e160668d455389d2f92645f14e25.png

3.3.6 数组操作
hello中数组为参数,在栈中。取值时使用mov,取地址时使用lea。
printf("Hello %s %s %s\n",argv,argv,argv);语句对应的汇编代码表现了取数组元素的过程。如下图:
https://i-blog.csdnimg.cn/direct/4527504114f64971957d20b33ba81db1.png
每次取-32(%rbp)以后加24/16/8对应的是argv的地址。

3.3.7 控制转移
       控制转移通常和关系比力一同出现,hello中有:if(argc!=5)和for(i=0;i<9;i++)两种跳转。如下图:
argc!=5:
https://i-blog.csdnimg.cn/direct/5a078a61d783447b88306f3ae6e4a489.png
;i<9:
https://i-blog.csdnimg.cn/direct/c62f49d93a96485f96fc5f83973e56a4.png

3.3.8 函数操作
hello中的函数操作有:printf 、exit 、sleep 、atoi 、getchar。编译器先向rdi,rsi,rdx,rcx等寄存器通报参数,然后call。如下图:
https://i-blog.csdnimg.cn/direct/751580acb2ec4d1d9d6183114f156e97.png

https://i-blog.csdnimg.cn/direct/ec7b23ad85e54d9996fffaea95621e87.png


https://i-blog.csdnimg.cn/direct/da0445980e384d158925f17fdc0037e9.png

https://i-blog.csdnimg.cn/direct/2c48b127032743cbbf6c33c5557f298b.png


https://i-blog.csdnimg.cn/direct/8e0ce03d452d40cd805ba42848de61cb.png

https://i-blog.csdnimg.cn/direct/cfbbe9c1a86745adb18ae418e853766f.png
3.4 本章小结

编译器高级步伐语言编译为汇编语言,并进行优化。本章分析了编译器对各种操作的实现,包罗数据界说、赋值、类型转换、算术操作、关系操作、数组操作、控制转移、函数操作等。
(第3章2分)

第4章 汇编

4.1 汇编的概念与作用


汇编器将汇编语言步伐转换为二进制机器码步伐,把指令打包成可重定位目标步伐的格式,天生.o文件。

4.2 在Ubuntu下汇编的下令

https://i-blog.csdnimg.cn/direct/e19beabf2cc346d58914d8c3f577eeb9.png
4.3 可重定位目标elf格式

ELF头:包含了magic(确认这是一个ELF文件)、class(这是一个64位的ELF文件)、data(说明小端序)、type(可重定位文件)等。如下图:
https://i-blog.csdnimg.cn/direct/bf31c8660a974a638502928057592127.png
节头:展现所有节的名称、大小、文件内的位置、类型等信息。如下图:
https://i-blog.csdnimg.cn/direct/c9d3ef53a6964b309b87d03fe9f49061.png

重定位节(.rela.text 和 .rela.eh_frame):Offset指出.text节中必要重定位的地址偏移;Info包含符号表索引和重定位类型;Type中R_X86_64_PC32和R_X86_64_PLT32,分别表现32位基于PC的相对重定位和过程链接表(PLT)的重定位;Sym. Value和Sym. Name:指出哪个符号必要重定位以及它的当前值;Addend用于调整重定位值的额外偏移。
从.rela.text中,可以看到有多个外部函数(如puts、exit、printf等)必要重定位。这意味着在链接阶段,链接器必要找到这些函数的实际地址,并将它们插入到.text节的相应位置。如下图:
https://i-blog.csdnimg.cn/direct/220f711c1d124a55b1992e1933b9b501.png

符号表:列出文件中所有的符号,包罗函数、变量和外部引用。如下图:
https://i-blog.csdnimg.cn/direct/560ec2debd00403e81c15d6bc82b67d1.png
4.4 Hello.o的结果解析

差异:
1).cfi等指令在.s文件中存在,而在反汇编中消散。
2).s文件中操作数是10进制,反汇编中是16进制。如下图:
     
https://i-blog.csdnimg.cn/direct/9d5e0caa35c24e96b532f8d67bea1daf.png
—>
https://i-blog.csdnimg.cn/direct/f1df3e2a6cb44e6998f5a571f0d157bf.png
3).s文件在分支跳转的时候以标签的形式,而反汇编以地址的形式。如下图:
     
https://i-blog.csdnimg.cn/direct/cfe28ba0317649f8829d4c8356903d61.png
 —>
https://i-blog.csdnimg.cn/direct/f43897bc99264f02bd4cba84077a0752.png
4).s文件在函数调用时以函数名形式,而反汇编以地址形式。如下图:
     
https://i-blog.csdnimg.cn/direct/7ba7592b8b1743e4be7495d44f2aab5f.png
—>
https://i-blog.csdnimg.cn/direct/7c6f8782bbf34edca6350725298a59ac.png
4.5 本章小结

分析了汇编后可重定位文件的ELF格式及内容,并观察了同样是汇编语言的.s文件与反汇编的差异。
(第4章1分)

第5章 链接

5.1 链接的概念与作用

链接将多个编译后的目标文件或库文件组合成一个可实行文件或库文件。主要有符号解析和重定位两个任务。
5.2 在Ubuntu下链接的下令

https://i-blog.csdnimg.cn/direct/b491ac8744bb4812a6d72147735de831.png
5.3 可实行目标文件hello的格式

hello.o的ELF头:
https://i-blog.csdnimg.cn/direct/a6831ccb73de4456947fc519403ed1dc.png

hello的ELF头:
https://i-blog.csdnimg.cn/direct/bd6e4095554049478266e559b1d2608e.png

发现program headers和section headers的内容增多了。

各段信息:
https://i-blog.csdnimg.cn/direct/bb40dff9e9e941d2b3066ed9db650978.png
https://i-blog.csdnimg.cn/direct/24d26f8e421249ff9119c3cabe09c4e2.png
5.4 hello的假造地址空间

通过5.3中各段的假造空间中位置信息,可以用edb中data dump查看相应内容。如:
https://i-blog.csdnimg.cn/direct/065e899cb04e4da5a5a1e2acb06f5821.png

https://i-blog.csdnimg.cn/direct/4f327232d9544bc9aad404166e426424.png
5.5 链接的重定位过程分析

5.5.1地址序号差异
objdump -d -r hello 序号为假造地址从0x400000开始,而objdump -d -r hello.o序号是从0开始的。如下图:
https://i-blog.csdnimg.cn/direct/437ba6a516494751ba5e668d36b69074.png

https://i-blog.csdnimg.cn/direct/147bb5b6028d46578bcbf7138bcfd2bb.png

5.5.2 字符串常量地址差异
在objdump -d -r hello.o中是可重定位条目,地址用0替代;在objdump -d -r hello中假造地址被添补上(重定位了)。如下图:
https://i-blog.csdnimg.cn/direct/c9832d51601c40c987abf4e5fb232783.png
https://i-blog.csdnimg.cn/direct/2ee8337723e24ef89d3ceaad8fe2e347.png

5.5.3函数调用地址差异
与字符串常量同理,被重定位了。如下图:
https://i-blog.csdnimg.cn/direct/8b95afae730a4cda9f325dc47f93f892.png
https://i-blog.csdnimg.cn/direct/dbaba6dd80924b07a518f31b9908a005.png

5.5.4 链接过程
链接包罗符号解析和重定位这两个焦点步骤。
符号解析的目的是将每个符号引用与其对应的符号界说关联起来。对于局部符号,链接器通常不必要进行特殊处理,由于这些符号的作用域仅限于其所在的目标文件。对于全局符号,规定:不允许由同名强符号;强弱同名取强;弱弱同名任取一个。
重定位的目的是确定每个符号界说的运行时内存地址,并修改对这些符号的引用,使之指向正确的内存地址。链接器首先将所有雷同类型的节合并成一个新的节,然后为每个合并后的节确定运行时内存地址,并为其中的符号界说分配内存地址。然后链接器修改所有对这些符号的引用(依赖于目标文件中的重定位信息)。以R_X86_64_PC32为例:
主函数开始地址:
https://i-blog.csdnimg.cn/direct/d6107df7949745908229809da2f82825.png

未定位:
https://i-blog.csdnimg.cn/direct/9b10657339c742ebb74a22d28a850296.png

重定位:
https://i-blog.csdnimg.cn/direct/a75ae2211e374e1ca3fedc62b9d1c4e5.png

查看节头表知.rodata在402000 :
https://i-blog.csdnimg.cn/direct/72002bbf53e84437a9845c7456c7ac9c.png

查看重定位条目:
https://i-blog.csdnimg.cn/direct/394d88f525924441be912abf27794c38.png

0x4010f0+0x00001c=0x40110c(运行时地址)
0x402000+(-4)-0x40110c=0xef0
写成小端模式:f0 0e 00 00,即重定位后的偏移地址(相对于PC)。
5.6 hello的实行流程

。。。。。。。这我写得不好。。。。。。。qwq
5.7 Hello的动态链接分析

在动态链接过程中,会天生一个共享库(动态库),该库能够在步伐运行时被加载到任意的内存地址,并与主步伐进行链接。这一过程主要由动态链接器负责完成,它在步伐启动并准备实行main函数之进步行必要的符号解析和重定位工作。
通过观察.got.plt节的变化,观察动态链接的过程。
https://i-blog.csdnimg.cn/direct/8528d3de07fb4f8ebef1475a6467a2f0.png
通过readelf找到.got.plt节在地址为0x404000的地方开始,大小为0x48。
https://i-blog.csdnimg.cn/direct/d504ea070a33445ab3eb8e95a0093058.png

https://i-blog.csdnimg.cn/direct/ab42be6aecfc470f9a81995b0e3b3642.png
5.8 本章小结

分析了实行链接操作的结构底子:ELF格式。
分析了毗连过程符号解析及重定位的过程以及动态链接的过程。
(第5章1分)


第6章 hello进程管理

6.1 进程的概念与作用

进程是操作系统中用于管理和实行步伐的根本单元,它是一个正在运行的步伐实例。进程为步伐提供两个假象:独占处理器(逻辑控制流)、独占内存系统(私有地址空间)。
6.2 简述壳Shell-bash的作用与处理流程

Shell是一个下令表明器,它为用户提供了一个向Linux内核发送哀求以便运行步伐的界面系统级步伐。
其根本功能是表明并运行用户的指令,重复处理如下过程:

[*]终端进程读取用户由键盘输入的下令行。
[*]分析下令行字符串,获取参数,并构造通报给execve的argv向量。
[*]如果是内置下令,立即实行;如果不是,调用Fork()创建子进程。
[*]在子进程中,用2)的参数,调用execve实行指定步伐。
[*]若用户没要求后台运行(没&)则waitpid等待作业终止后返回。
[*]若要求后台运行,则返回。
6.3 Hello的fork进程创建过程

Shell实行fork函数,创建一个与当进步程几乎完全雷同的子进程。这个子进程会得到父进程当前实行到的位置、打开的文件形貌符、当前的工作目录等环境的副本。
fork进程创建过程:系统为新进程分配一个唯一的进程标识符(PID),为新进程分配所需的内存空间,包罗步伐、数据和用户栈。
6.4 Hello的execve过程

execve函数用于加载并实行一个新的可实行文件,将当进步程更换为新的步伐。操作系统将hello加载到当进步程的内存空间中,更换掉当进步程的代码段、数据段、堆栈等,将argv和envp参数指定的下令行参数和环境变量设置为新进程的相应内容,从新步伐的入口点(main)开始实行代码。
6.5 Hello的进程实行

当hello进程创建时,操作系统会为hello进程分配时间片,hello与其他进程轮流使用处理器,并发实行,实行各自的逻辑控制流。
当实行系统调用(如hello中的sleep,printf)或者当操作系统认为hello进程运行得充足久时,会发生上下文切换,步伐将由用户态转换至焦点态。内核中的调度器决定进程如何调度并进行上下文切换,将当前的上下文信息生存到内核中,规复某个先前被抢占的进程的上下文,然后再由焦点态转换至用户态,将控制通报给这个新规复的进程。
6.6 hello的非常与信号处理

6.6.1 正常运行后随便按一个键
打印结束后getchar()等待用户输入一个键,之后步伐结束运行,Shell回收hello进程。如下图:
https://i-blog.csdnimg.cn/direct/116fa059e23e42a2bf1aa46ca7684596.png

6.6.2 ctrl +c
内核发送SIGINT信号给Shell前台的所有进程,所有进程吸收信号并终止运行。如下图:
https://i-blog.csdnimg.cn/direct/4950a29e14284eb0b7ccfe39f6ecacf5.png

6.6.3 crtl+z
内核发送SIGTSTP信号给Shell前台的所有进程,所有进程吸收信号并挂起。如下图:
https://i-blog.csdnimg.cn/direct/6c04258975b84868a63f1ba5c4970603.png

ps可以查看到当前hello被挂起:
https://i-blog.csdnimg.cn/direct/e55392739ad141e18ab514cfafad3256.png

jobs查看被挂起的hello进程的jid及状态标识:
https://i-blog.csdnimg.cn/direct/a3acac134ff74eaab5ed9c708f1961a8.png

pstree查看hello进程的继承关系:
systemd──systemd──gnome-terminal-──bash──hello

fg让hello回到前台继续运行:
​​​​​​​https://i-blog.csdnimg.cn/direct/123d5ba8f62645fe9db48c6b9de1f7c1.png

Kill发送信号给进程,这里发送SIGKILL信号(序号9)终止步伐:
https://i-blog.csdnimg.cn/direct/af037ea5d17742748e1ee8f79612dad9.png

6.6.4 乱按
      不按到上述几个就没影响。
https://i-blog.csdnimg.cn/direct/5a45595aba20411b8e3be966fb1aa1ea.png
6.7本章小结

在shell中运行hello可实行步伐,shell先为它fork,再为它execve,分配时间片和内存,同时内核检测键盘给出的信息(硬件非常),为进程发送相应的信号,hello在收到信号由信号处理步伐实行相应操作。
(第6章1分)

第7章 hello的存储管理

7.1 hello的存储器地址空间

逻辑地址是指从应用步伐角度看到的内存单元或存储单元的地址,它通常是由步伐产生的段内偏移地址。
线性地址是逻辑地址到物理地址变换之间的中心层。在分段部件中,逻辑地址加上基地址(段基址)就构成了线性地址。
假造地址是步伐运行在假造地址空间中的地址,它与实地址模式下的分段地址类似,也可以写为“段:偏移量”的形式。
物理地址是内存中各存储单元的编号,即存储单元的真实地址。它是可识别、可寻址并实际存在的。
7.2 Intel逻辑地址到线性地址的变换-段式管理

逻辑地址通常由段选择符和偏移量两部分构成。段选择符用于选择特定的段,而偏移量则用于确定该段内的详细位置。
计算:根据逻辑地址中的段选择符,从全局或局部形貌符表中选择对应的段形貌符,然后从选中的段形貌符中提取段的基地址,再将逻辑地址中的偏移量与基地址相加,得到线性地址。
7.3 Hello的线性地址到物理地址的变换-页式管理

页式管理将内存划分为固定大小的页面(通常是4KB)。每个页面都有一个唯一的页号,用于标识其在内存中的位置。页式管理通过页表将线性地址中的页号映射到物理地址中的页面,从而实现地址的转换。
处理器首先根据线性地址的高位部分(即页号)在页表中查找对应的页表项。如果页表项有用,则处理器从找到的页表项中提取页面的物理地址。然后,处理器将线性地址的低位部分(即页内偏移量)与提取的物理地址相加,得到终极的物理地址。
为了提高地址转换的效率,处理器通常配备了一个TLB。TLB是页表的缓存,存储了最近使用的PTE。
7.4 TLB与四级页表支持下的VA到PA的变换

当处理器必要访问某个假造地址时,它首先会在TLB中查找PTE。如果TLB掷中,则处理器可以直接使用该条目进行地址转换,无需再访问页表。如果TLB未掷中),则处理器必要访问四级页表来查找对应的物理地址,并将新的PTE添加到TLB中。
四级页表包含4个级别的页表项。前三级的页表项都指向下一个级别的页表,末了一级页表项指向终极的物理页面。处理器逐级查找,直到找到终极物理页面。
多级页表通过分级索引的方式,对于未使用的假造地址空间,可以不在页表中为其分配页表项,通常会节省大量页表空间。

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

在MMU成功计算出物理地址后,该地址被送往L1缓存进行匹配。L1缓存利用PA中的标记和组索引信息来查找对应的数据块。若此时缓存掷中(即找到匹配项且有用位为1),则根据块偏移量直接提取数据并返回给CPU。若缓存未掷中,则系统会按照L1-L2-L3-主存的顺序逐级向下查询。一旦在某一级缓存或主存中找到所需数据,该数据将被返回给CPU,并依据特定的更换策略,将相应的数据块缓存至当前的L1缓存中,以备后续快速访问。
7.6 hello进程fork时的内存映射

当fork被调用时,内核会为子进程创建一个新的假造内存空间,这个空间几乎完全复制了父进程的假造内存空间,包罗代码段、数据段、堆、栈等各个部分,但物理内存并不是立即复制的。父子进程共享雷同的物理内存分页,这些分页被标记为只读,当父子进程中的任何一个试图写入这些共享的分页时,会触发一个写时复制,内核为写入进程创建一个新的物理内存分页,并将所需的数据从原始分页复制到新的分页中。然后,内核会更新写入进程的页表,使其指向新的分页,并允许写入操作继续。
7.7 hello进程execve时的内存映射

execve读取hello可实行文件,解析文件以获取创建新内存映像所需的信息,包罗代码段、数据段等的起始地址和大小。然后,系统会基于这些信息为新进程构建一个新的内存映像,这个映像将覆盖当进步程的整个假造地址空间。这个过程中,当进步程的所有内存映射,包罗之前打开的文件、建立的内存映射等,都会被新的内存映像所更换。
7.8 缺页故障与缺页中断处理

当进程访问的页面不存在于物理内存中时,就会触发缺页故障,操作系统暂停当进步程的实行,并触发一个缺页中断,中断处理步伐随后接管控制权,开始处理缺页中断。
中断处理步伐会先生存当前CPU的状态,然后确定哪个页面缺失并必要被调入内存,从磁盘中调入缺失的页面,将其加载到物理内存中。如果物理内存已满,那么中断处理步伐会采用页面置换算法来选择一个页面捐躯。在页面被成功调入内存后,中断处理步伐会更新页表,将缺失页面的假造地址映射到新的物理地址上。末了中断处理步伐规复之前生存的CPU状态,将控制转移回被中断的进程。进程重新访问之前发生缺页中断的地址,而且掷中。
7.9动态存储分配管理

       动态存储分配管理通过操作系统或语言运行时库提供的内存分配函数来实现。这些方法允许步伐在运行时根据必要动态地申请或开释内存空间。
隐式空闲链表通过每个块的头部中存放的信息来定位下一个块的位置。头部一般包含本块的大小及使用情况(分配或空闲)。当吸收到一个内存分配哀求时,从头开始遍历堆,找到一个空闲的满足大小要求的块。如有剩余,将剩余部分变成一个新的空闲块,并更新相干块的控制信息。在开释内存时,仅需把使用情况标记为空闲即可,但可能涉及合并空闲块的问题。合并操作通常推迟进行,以镌汰系统开销。
显式空闲链表显式地把所有的空闲块通过链表的形式维护起来。每个空闲块中包含两个指针字段,一个指向前面的空闲块,一个指向后面的空闲块。当必要分配内存时,从链表中找到一个合适的空闲块进行分配。如果找不到满足要求的空闲块,可能必要向操作系统申请新的内存空间。在开释内存时,将开释的块重新插入到链表中,并可能必要合并相邻的空闲块。
7.10本章小结

本章说明白逻辑地址、线性地址、假造地址、物理地址的概念,以及它们的联系。说明白逻辑地址到线性地址的变换、线性地址到物理地址的变换是如何完成的。分析了TLB与四级页表支持下的VA到PA的变换。说明白三级Cache支持下的物理内存访问的流程。分析了fork与execve时的内存映射。先容了缺页故障与缺页中断的处理,然后分析了动态存储分配管理。
(第7章 2分)

第8章 hello的IO管理

8.1 Linux的IO装备管理方法

Linux把所有IO装备都当作文件来处理,通过在系统内部使用雷同的read和write函数进行读写操作。这些装备文件通常位于/dev目录下,包罗磁盘、打印机、网络装备等。Linux通过装备驱动来实现IO装备的操作,装备驱动为操作系统和硬件分别预留接口,通过装备驱动来屏蔽操作系统和硬件的差异。
8.2 简述Unix IO接口及其函数

打开文件: open(char *path, int flags, mode_t mode);
关闭一个一打开的文件: close(int fd);
从文件中读取数据: read(int fd, void *buf, size_t count);
向文件中写数据: write(int fd, const void *buf, size_t count);
8.3 printf的实现分析

1. 用户态的格式化字符串处理
printf 函数首先会解析格式字符串,并根据格式字符串中的格式说明符(如 %d、%s、%f 等)以及后续提供的参数,天生要输出的表现信息。这一步骤通常由 vsprintf来完成,它会将格式化的字符串存储在一个缓冲区中。

2. 系统调用
天生了格式化的字符串后,printf必要将这个字符串输出到标准输出装备。在Unix-like系统中,这通常是通过 write系统调用来实现的。write系统调用会将缓冲区中的数据写入到文件形貌符所指向的文件中,对于标准输出,其文件形貌符通常是 1。在进行系统调用时,用户态的步伐会触发一个陷阱或中断,以切换到内核态来实行系统调用的处理函数。

3. 内核态的系统调用处理
当系统调用被触发后,CPU会跳转到内核态,并实行系统调用的处理函数。对于write系统调用,内核会检查文件形貌符的有用性,确定要写入的文件,并将用户态缓冲区中的数据复制到内核缓冲区中。然后,内核会根据文件的类型和状态,将数据写入到相应的装备中。
对于标准输出,数据通常会被写入到终端装备的驱动步伐中。

4. 字符表现驱动子步伐
终端装备的驱动步伐会吸收内核通报过来的字符数据,并将其转换为表现芯片可以明白的格式。这通常涉及到将ASCII码转换为字模库中的字模数据,并将这些数据写入到视频内存(VRAM)中。
字模库是一个包含所有可打印字符的点阵数据的集合,每个字符都由一个固定大小的点阵来表现。驱动步伐会根据字符的ASCII码,在字模库中找到对应的点阵数据,并将其写入到VRAM中相应的位置。

5. 表现芯片和液晶表现器
末了,表现芯片会按照刷新频率逐行读取VRAM中的数据,并通过信号线将这些数据传输到液晶表现器上。液晶表现器会根据吸收到的RGB分量信息,控制每个像素点的颜色和亮度,从而表现出字符和图像。

综上所述,printf 函数的实现涉及从用户态到内核态的多个条理,包罗格式化字符串处理、系统调用、内核态处理、字符表现驱动以及硬件级别的表现控制。这些步骤共同协作,实现了将格式化的数据输出到表现装备上的功能。
8.4 getchar的实现分析

当 getchar 被调用时,它首先检查系统的键盘缓冲区中是否有字符可用。如果缓冲区中有字符,getchar 会从缓冲区中取出下一个字符并返回它。否则,getchar调用read系统函数,键盘中断触发非常处理子步伐,担当按键扫描码转成ascii码,生存到系统的键盘缓冲区,直到担当到回车键才返回。

8.5本章小结

本章讨论了Linux系统中Unix I/O的形式以及实现的函数。对printf和getchar两个函数的实现进行了的探究。
(第8章1分)
结论

1.起始:编写源代码
一切始于一个简单的C语言源文件——hello.c。

2.预处理阶段
编写完成后,源文件进入编译流程的第一步——预处理。预处理器(通常是cpp)处理所有的预处理指令,比如#include、#define等。它展开宏界说,包含头文件,并可能天生一些额外的代码,比如行号信息等,终极天生一个预处理后的文件,通常带有.i后缀。

3.编译阶段
接下来,预处理后的代码被通报给编译器。编译器将C语言源代码转换为汇编语言代码。这一步骤涉及词法分析、语法分析、语义分析、中心代码天生、代码优化等多个子步骤。编译器输出的汇编代码文件通常带有.s后缀。

4.汇编阶段
汇编器(如as)吸收汇编代码文件,将其转换为机器码,即目标代码。目标代码是特定于平台的二进制指令集,但还不是可直接实行的步伐。汇编过程还天生符号表和其他信息,用于后续的链接阶段。天生的目标文件通常带有.o后缀。

5.链接阶段
多个目标文件(如果有多个源文件)以及库文件(如C标准库libc)必要通过链接器(如ld)链接在一起,形成终极的可实行文件。链接器解析符号引用,将各个目标文件中的代码和数据段组合成一个单一的、可实行的文件。在hello的例子中,我们得到的是名为hello的可实行文件。

6.实行阶段
在Shell中,用户通过输入./hello下令来运行这个步伐。Shell首先通过fork系统调用创建一个新的进程,该进程是Shell进程的子进程。然后,通过execve系统调用,新进程加载并实行hello步伐。

7.假造内存与进程管理
操作系统利用假造内存机制为hello进程分配一个独立的地址空间。这包罗代码段(.text)、数据段(.data)、未初始化数据段(.bss)等。mmap系统调用被用来映射这些段到物理内存或交换空间。同时,调度器负责分配CPU时间片给hello进程,使其有机会在CPU上实行。

8.指令实行与系统调用
CPU从hello进程的代码段中逐条取出指令实行。当步伐实行到printf函数调用时,它实际上触发了一个系统调用(syscall),导致进程从用户态切换到内核态。内核中的write系统调用处理这个哀求,将字符串“Hello ……”写入到标准输出。

9.进程结束与资源回收
当hello步伐实行完毕,它通常通过调用exit函数来结束。Shell通过waitpid系统调用等待并收集这个子进程的退出状态。内核负责回收hello进程所占用的所有资源,包罗CPU时间、内存(通过解除映射)、文件形貌符等。如许,系统资源得以高效利用,不会由于已终止的进程而浪费。
   通过上述步骤,hello.c源文件便经历了从编写到实行再到回收的完备生命周期。

附件

hello.i:预处理步伐。
hello.s:汇编语言步伐。
hello.o:可重定位文件。

(附件0分,缺失 -1分)

参考文献

为完本钱次大作业你翻阅的册本与网站等
    《深入明白计算机系统》
  HITICS大作业:HELLO——步伐的一生_机带ram16.0 gb (15.4 gb 可用)-CSDN博客
    https://blog.csdn.net/m0_65601072/article/details/124650579

(参考文献0分,缺失 -1分)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: hitics 计算机系统 大作业 步伐人生 Hello‘s P2P