第六篇章 启动update&shell

日期:2022-10-11

版本号:V1.0

作者:snow

一、基础概念

二、准备输入信息

2.1 解除进程2与tty0的关联

在进程2中,filep指向了与进程1相同的filetable内核空间,即使用了相同的filep。而在拷贝过程中,filep与shell进程进行关联,会导致所有文件的使用次数也会相应增加。而进程2暂时不需要filep[0]所对应tty0。故需要将shell进程与tty0解除关联。

  1. 将filetable中tty0的使用次数减一
  2. 将进程2的filep[0]清空,不再指向filetable中tty0的位置

2.2 打开/etc/rc文件

同进程1打开tty0文件过程一致,只是rcinode节点位置不同,且其存储在filetable不同位置。rc作为资源配置文件,其中的内容后续将会作为shell进程参数使用。

2.3、EIP数据压栈

将EIP数据压入进程2的用户栈中

2.4、对输入参数结构初始化

相当于初始化一块内存区域,后续存放输入的环境变量和参数

三、准备shell环境

shell程序可以进一步拓展外设与主机的交互能力。

3.1、检测shell文件

3.1.1 获取shell文件i节点

同获取/etc/tty0过程

3.1.2 建立参数页面

计算参数与环境变量的数据量大小,并据此申请相应数量的内存页面。参数和环境变量存储在内核数据栈中,数据量的数量存放在用户进程栈中。同时定义N个页面指针。

3.1.3 判断shell文件属性

(1)判断/bin/sh是否为为“常规文件”(非设备文件、目录文件、管道文件等特殊文件),由于/bin/sh是做作为普通文件存在,即判断通过。

(2)获取shell文件的文件头

正常请款下文件头位于该文件的第一个逻辑块内。获取后会将其存放在进程2的用户栈中,同时释放获取过程中所使用的超级块

(3)判断shell文件是否为脚本文件

/bin/sh是脚本文件(以#!开头)

(4)文件属性判断

shell可执行需要满足以下条件:是分页可执行文件+代码重定位部分长度为0+数据重定位信息长度为0+代码+数据+堆段实际值小于等于50MB+i节点属性中该值必须大于等于实际值+文件头长度等于一个缓冲块,

3.1.4 拷贝参数与环境变量

将环境变量和输入参数拷贝指定的内存页面中。并将页面位置存放在在3.1.2所生命page数组中。

3.2、加载进程2的信息

3.2.1 加载进程2的执行文件

(1)进程2的执行文件继承于进程1,故需要解除

(2)将/bin/sh的i节点加载到进程2的执行文件中中

3.2.2 清除继承于父进程的信号

进程2信号函数继承于进程1,但相关信号理应只触发进程1,而不需要进程2处理,故需要解除进程2的所有信号句柄。

3.2.3 清除继承于父进程的执行文件

进程2执行文件继承于进程1,但相关信号理应只会由进程1执行,而不需要进程2执行,故需要解除进程2的执行文件,并将执行文件队列清0。

3.2.4 清除继承于父进程的页表

进程2的LDT于GDT继承于进程1,并且在继承过程中导致相应页面引用次数+1。由于进程2将会执行新的执行文件,会加载新的页面,故不需要再使用父进程的页面(小彩蛋:在这之前可以理解为复制母体,该步骤则是完成与母体分离。在进程0~进程2的过程中可以可以理解为在复制母体的基础上进行进化)。

3.2.5 清除继承于父进程的协处理器

父进程(1)可能占用了协处理器,但子进程(2)默认不能同时使用协处理器,故需要清除相应的可用标志以及使用标志

四、加载shell代码

4.1、加载shell文件信息

4.1.1 加载shell的LDT

(1)从LDT中取出当前进程的代码段、数据段的基址与限长

(2)计算shell的代码段限长(代码长度+一个存储环境变量和参数的页面)

(3)将shell的代码段限长作为当前进程的代码段限长

(4)将新代码段、数据段的基址与限长写入到LDT

(5)将参数和环境变量写入到数据段中(最后一个页面)

4.1.2 建立指针管理表

(1)在参数和环境变量的随后位置,定义N+M+2个字符串指针数组

(2)让其中N个指针分别指向N个环境变量字符串的起始地址

(3)同理让让其中M个指针分别指向M个参数字符串的起始地址。多申请的两个指针指向空地址。

(4)然后argc=M,argv=参数指针数组的首地址,让envp指向环境变量指针数组的首地址

4.1.3 调整进程管理结构

(1)更新代码段、数据段、堆栈段、用户ID、用户组ID等信息

(2)将内存BSS段页面清0

4.2、载入shell首段代码

4.2.1 设置EIP&ESP

在2.3节中压入了下一行的代码的地址,现在将这个地址替换为shell程序的入口地址,并通过直接访问栈的方式设置esp所在的地址。

4.2.2 缺页中断

在2.3开始到4.1节的代码执行完毕后,系统会返回,并将shell程序的入口地址的内容作为下一句代码执行。

(1)触发缺页中断。在执行入口地址的指令前,系统需要将这个入口地址(线性地址)解析为逻辑地址,但是由于页目录表和页表并无相关内容,所以无法完成解析,此时则发生缺页中断(软中断)

(2)确定缺页原因,由于是内容缺失,故需要调取内容

(3)确定是否可以共用已有页面,若可以共享其他进程的相同页面,则共用(并行相同进程)。

(4)无法共用且为内容缺失,申请新一个新的页面(4KB)

(5)确定当前进程(2)的当前执行文件(/bin/sh)的前四个逻辑块(每个1KB)的位置

(6)将这个四个逻辑块内容读取到页面中

4.2.3 建立地址映射表

将缺页的虚拟地址与页表建立连接,然后将该虚拟地址设为可用状态。随后shell程序将会被执行

五、创建进程update&进程2退出

5.1、获取/etc/rc内容

shell程序启动后,首先从标准输入设备中获取需要执行的shell代码,然后将其执行。即通过文件读取的方式获取/etc/rc文件中包含的shell命令,由于rc文件作为普通文件,读取完毕后会返回0。

5.2、创建进程update

通过新进程-update执行rc文件中的创建update进程等命令,其中比较重要的一项是将输出缓冲区的内容同步到外设,执行完毕后该进程将被挂起,并作为update进程常驻内核,并用作缓冲区与外设数据同步使用。每隔一段时间都会被周期性调用。

5.3、释放进程2所使用的页面

此处仅是将所使用的页面的引用次数减1,并不删除实际内容

5.4、设置update父进程

由于进程2即将退出,故将update的父进程改为进程1

5.5、释放关联资源

将进程2打开的所有文件目录等的i节点引用次数减一,同时释放相关的文件,例如执行文件等,释放完毕后进程2即进入僵死状态,进程2会将自身结束的信息释放给其父进程1。然后系统江湖重新回到进程1。

在调度器中进程1收到这些信息后,进程1将会将会切换为就绪状态,并在随后被执行,启动后将会释放进程2的进程管理结构以及使用的页面,即意味这进程2的彻底消亡。

六、启动shell进程

在第3~5章,系统将进程2暂时作为shell进程进行使用,并搭配/etc/rc文件为系统创建了update进程,但进程2将/etc/rc作为输入,无法实现人机交互过程。需要将tty0作为输入输出设备才能基础的人机交互功能。

6.1、创建shell进程

与进程1创建进程2一致

6.2、准备shell环境

与进程2准备shell环境基本一致,唯一差异是输入输出设备改为tty0

6.3、执行shell命令

shell进程会从tty0文件读取指令,但是由于刚启动缓冲区肯定没有数据指令,所以会被挂起并进入可中断等待状态,而不是直接退出。若后续用户通过键盘输入数据到缓冲区,则会唤醒shell进程。并由shell进程解析并执行相关命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值