计算机结构基础

#计算机架构

cpu执行过程

1、处理器无限循环寻址执行指令
2、程序包含内核态和用户态,用户态不能直接访问内存和IO等操作
3、用户态程序通过调用系统调用产生软件中断,可以将用户态转换出内核态,内核程序根据中断向量表查找该系统调用产生的中断对应的处理程序的地址,跳转到该地址继续进行执行;系统调用一般都是预先编写好的库文件函数;
4、各程序通过时间片调度执行,当一个用户程序执行完了他的当前时间片,则会产生一个硬件中断,操作系统会切换到用户态并且跳转到下一条指令位置执行;操作系统需要保存现场并且加载接下来要执行的程序的内容;循环此过程来实现分时执行程序;用户态程序是时间片调度执行的,内核态程序也是时间片抢占式调度执行的;
5、可执行程序执行过程:
用户态输入命令行执行程序;用户态调用系统调用指令;切换到内核态;内核态加载二进制文件,按照格式解析二进制文件并尝试寻找对应格式的处理程序;如果找到对应格式的处理程序,则保存当前程序的执行现场,替换为即将执行的程序;
在linux中执行二进制程序的系统调用函数是execve,其中v代表argv 传入的执行参数; e代表envp,要执行的环境信息参数,此函数还有一个参数为执行程序的文件名,表明执行程序的路径
6、真正执行的函数为do_execveat_common。需要确定存储程序的路径,解释器名称,文件缓冲buf加载程序的前256字节数据,此数据用于检测文件格式并加载脚本;
7、内核会遍历一系列的binfmt 二进制格式的处理程序。如果有程序能够处理当前的程序则交给它执行;否则返回错误代码;
8、动态链接过程,方便使用库函数
9、执行
要运行ELF文件,如果要执行的二进制文件需要动态链接,则不能直接跳转到二进制文件的代码;而是先把要链接的库函数加载进内存;
读取ELF文件头后,内核为新程序设置内存结构,将所有段加载到内存中,填充程序的静态数据、BSS空间和机器代码;如果是动态链接的,内核还会加载ELF解释器并且加载解释器的数据、BSS以及代码;
内核设置CPU返回用户态时要恢复的指令指针,如果是动态链接的,指令指针指向内存中ELF解释器代码的开头位置;如果不是动态链接的,指令指针指向可执行文件的开头位置;
内核当前还处于系统调用中,需要把参数和环境变量放入堆栈中;供用户程序启动时读取
清楚寄存器,在处理系统调用前,内核会将寄存器的当前值存入堆栈中,以便在切换回用户态时恢复、在返回用户态之前,内核会将堆栈的这一部分归零;
最后,系统调用结束,内核返回到用户态,恢复寄存器,并跳转到存储的指令指针,该指针现在是新程序或者ELF解释器的起点,当前的进程就被替换掉了。

ELF executable and linkable format

就是linux系统的exe文件,执行这种文件是linux会使用特定的处理器进行处理:binfmt_elf.c

ELF Header 文件头

表明可运行的处理器
表明此文件是直接运行的还是作为其他程序的运行库
表明程序的执行入口,执行入口是一个内存地址,指向第一行机器码指令的位置
指示出PHT和SHT的偏移位置

Program Header Table 程序头表

用于表明程序应当如何加载和执行
指明ELF文件中的数据位置
指明数据应当被加载到什么虚拟内存地址
指明数据的长度,指明内存长度
指明改程序允许的读写运行权限

Section Header Table 段头表

不是程序运行的必须位置
一般用于详细指明数据段每个位置的作用,多用于调试解析

Data 数据

具体的数据段数据

程序表段表和数据表位置

register

ram

instruction

pointer

machine code

kernel - operating system core

syscall

software interrupts

interrupt vector table

library function

调用高级库函数,lib、dll等不会产生内核状态和用户状态的切换?待考

time slice

分时系统的基础,时间到了以后通过硬件中断,使得kernel切换到下一个程序。

paging

memory is fake

cpu从内存读写数据时,并没有真正的指向物理内存,而是指向了虚拟内存空间的位置

MMU memory management unit

MMU负责映射虚拟内存地址和物理内存地址
计算机启动时,内存直接访问的物理RAM;启动后,操作系统做虚拟内存映射并且告知cpu开始使用MMU寻址;
映射关系通常被称作页表,映射寻址过程又被称作寻页
系统启动时,内核会构建页表,向PTBR(页表基址寄存器)保存起始页表的物理地址。
当操作系统切换程序时,会重新映射虚拟内存空间到一个新的物理内存空间,
每个页会有权限标志,表明该页是可读或可写或仅内核访问;
分级分页

进程间如何做内存隔离的,即内存安全如何实现的

操作系统和mmu单元配合实现内存安全

fork 多进程

fork是内核提供的系统调用,它会克隆当前进程及其内存,将保存的指令指针留在原处,然后允许这两个进程照常进程;
新运行的程序称为子进程,最初的进程称为父进程,进程可以多次调用fork,因此可以具有多个子进程;每个子进程都用PID进行编号,从1开始。
fork的系统调用在子进程和父进程中返回的值不同,在父进程上,它返回新的子进程的PID,在子进程上,返回0;这样就可以在新进程上做不同的工作了。以上就是fork-exec模式
https://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html
fork会通知MMU为新进程创建旧进程页表的副本,并保持映射指向相同的底层物理内存;
COW页面允许两个进程进行内存隔离,无需克隆整个内存空间;克隆父进程后,他会将两个进程的所有页面标记为只读,当程序写入内存时,写入失败,因为内存是只读的。这时会触发由内核处理的段错误(硬件中断),内核复制内存,更新页面以允许写入,并从中断返回以重新尝试写入;
init进程是所有进程的祖先;由内核设置,PID为1;是第一个运行的用户态程序,也是关机时最后一个被关掉的程序。

计算机启动顺序

1、主板内置了一段程序,可以在磁盘上搜素系统引导代码;找到系统引导程序后将其机器码加载到RAM中,然后执行;
2、引导程序负责查找内核并将其加载到RAM中执行
3、内核程序启动后开始执行许多初始化任务,包括设置中断处理程序、加载驱动程序、创建初始内存映射。最后内核将权限级别切换到用户态并启动init程序
4、init程序还是执行init脚本,启动服务并执行shell/ui等程序;init使用fork-exec模式启动各种用户程序。

用户程序执行过程

计算机启动后,内核启动init进程
init进程启动图形环境程序,并启动其他软件
每次启动程序都使用fork系统调用实现,所有内存页都是COW,不需要在物理RAM中复制内存
这两个进程都会检查它们是否是发起fork的进程,如果是则会使用exec系统调用要求内核用新程序替换当前程序;
新程序可能是一个ELF文件,内核会解析ELF文件并加载其代码和数据。如果是动态链接的,内核还会准备一个ELF解释器
然后,内核可以加载程序的虚拟内存映射,并在程序运行时返回到用户态。这实际上表示cpu的指令指针设置为虚拟内存中新程序的开头。

  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值