HIT_OS_LAB2 调试分析 Linux 0.00 多任务切换

2023-11-04 23:20

本文主要是介绍HIT_OS_LAB2 调试分析 Linux 0.00 多任务切换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

操作系统实验二

2.1 实验目的

  1. 通过调试一个简单的多任务内核实例,使大家可以熟练的掌握调试系统内核的方法;
  2. 掌握Bochs虚拟机的调试技巧;
  3. 通过调试和记录,理解操作系统及应用程序在内存中是如何进行分配与管理的;

2.2 实验内容

通过调试一个简单的多任务内核实例,使大家可以熟练的掌握调试系统内核的方法。 这个内核示例中包含两个特权级 3 的用户任务和一个系统调用中断过程。我们首先说明这个简单内核的基本结构和加载运行的基本原理,然后描述它是如何被加载进机器 RAM 内存中以及两个任务是如何进行切换运行的。

2.2.1 掌握Bochs虚拟机的调试技巧

  • 设置断点 (b): 可以在指定的内存地址处设置断点,当程序执行到该地址时,会中断执行,方便用户进行调试。

  • 显示断点状态 (blist): 可以查看当前所有断点的状态,包括断点地址和是否启用。

  • 读/写断点 (unwatch/watch): 可以设置或清除读或写的断点,当指定内存地址被读取或写入时,会触发断点中断。

  • 显示寄存器状态 (trace-reg on): 在单步调试时,会显示每个寄存器的状态,帮助用户了解程序执行的过程。

  • 打印当前堆栈 (print-stack): 可以打印当前的堆栈信息,帮助用户跟踪函数调用和返回。

  • 继续向下执行 ( c): 用于继续执行程序,直到遇到下一个断点或程序结束。

  • 单步执行 (s): 逐步执行程序,一次执行一条指令,方便用户逐行跟踪代码执行流程。

  • 查看寄存器信息 (info cpu/r/sreg/creg): 可以查看CPU寄存器、段寄存器和控制寄存器的信息,帮助用户了解当前的CPU状态。

  • 查看内存内容 (xp /nuf): 可以查看指定内存地址处的内容,用户可以指定显示的单元数量、单元大小和显示格式。支持十六进制、十进制、无符号十进制、八进制和二进制等不同的显示格式。

  • 反汇编指定范围的内存 (u): 可以对指定范围的内存进行反汇编,帮助用户查看内存中的指令内容。

2.3. 实验报告

1.当执行完 system_interrupt 函数,执行 153 行 iret 时,记录栈的变化情况。

若从task1中调用int 0x80 进入 system_interrupt,执行iret之前,栈底地址为0x10e0,即目前使用krn_stk1

在这里插入图片描述

栈中的内容:

地址意义
0x10CC0x10ff代码指针(即eip)
0x10D00x000f当前局部空间代码段选择符(即cs)
0x10D40x0202标志寄存器值(即eflags)
0x10D80x1308堆栈指针(即esp)
0x10DC0x0017当前局部空间数据段(堆栈段)选择符(即ds)
0x10e00x17b8栈底

若从task1中调用int 0x80 进入 system_interrupt,执行iret之后,栈底指针为0x1308,即目前使用usr_stk1。同时,栈底指针与执行iret前栈内0x10D8处的值相等,证明此处存储堆栈指针。

在这里插入图片描述

栈中的内容:

地址意义
0x13080x0000栈底

若从task0中调用int 0x80 进入 system_interrupt,执行iret之前,栈底指针为0x0E60,即目前使用krn_stk0

在这里插入图片描述

栈中的内容:

地址意义
0x0E4C0x10eb代码指针(即eip)
0x0E500x000f当前局部空间代码段选择符(即cs)
0x0E540x0246标志寄存器值(即eflags)
0x0E580x0bd8堆栈指针(即esp)
0x0E5C0x0017当前局部空间数据段(堆栈段)选择符(即ds)
0x0E600x0000栈底

若从task0中调用int 0x80 进入 system_interrupt,执行iret之后,栈底指针为0x0BD8,即目前使用init_stack。同时,栈底指针与执行iret前栈内0x0E58处的值相等,证明此处存储堆栈指针。

在这里插入图片描述

栈中的内容:

地址意义
0x0BD80x0bd8栈底

2.当进入和退出 system_interrupt 时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?

请添加图片描述

  • 特权级的切换: 通过调用中断,修改程序运行时的cs。在进入中断前,程序当前的特权级为3,即用户模式。而触发int 0x80中断后,程序会进入内核模式,特权级变为0。在返回中断前,特权级又从0变为3,从而完成特权级的切换。
  • 栈的切换: 在进入中断时,程序会自动将当前的一些寄存器的值压入栈内,以确保能够正确地返回原程序。然后,在执行iret指令前,程序会将之前压入栈内的信息弹出,覆盖掉现有的cs,使程序的特权级从0变为3。同时,堆栈指针(即esp)也会发生变化,当前使用的栈会从一个内核栈(krn_stk0或krn_stk1)变成用户栈(usr_stk1)。

因此,通过int指令和iret指令完成的模式切换和特权级的切换。此外,这种切换也是为了确保程序的正确执行和系统的稳定运行。

3.当时钟中断发生,进入到 timer_interrupt 程序,请详细记录从任务 0 切换到任务 1 的过程。

  • **将1存入currnt: **这个操作通常是为了标记当前正在执行的任务,以便在后续的处理中能够正确地切换到任务 1。
  • 通过ljmp指令从任务0切换至任务1: 在 timer_interrupt 程序内,使用 ljmp 指令进行任务切换。ljmp 是一个汇编指令,它用于在任务之间进行切换。在进行切换之前,需要先将当前任务的各寄存器状态和值保存到 tss0 内。这个操作是为了保存当前任务的上下文,以便在需要时可以正确地恢复。

imer_interrupt 处理程序内,执行ljmp指令从任务0切换至任务1之前,tss0的状态。

在这里插入图片描述

timer_interrupt 处理程序内,执行ljmp指令从任务0切换至任务1之后,tss0的状态。

在这里插入图片描述

  • 查找得到tss1的地址并加载各寄存器的值: 在切换到任务 1 之前,需要通过 $TSS1_SEL 选择符从 gdt 中查找得到 tss1 的地址。然后从 tss1 中获取任务 1 的各寄存器值,并将这些值加载进各寄存器中。这个操作是为了恢复任务 1 的上下文。

    timer_interrupt 处理程序内,执行ljmp指令从任务0切换至任务1之前,tss1以及当前各个寄存器的状态。

    在这里插入图片描述

timer_interrupt 处理程序内,执行ljmp指令从任务0切换至任务1之后,tss1以及当前各个寄存器的状态。

在这里插入图片描述

  • **执行任务1: **最后,根据新加载进来的 cs:eip 以及各寄存器的状态和值,执行任务 1。cs:eip 是代码段寄存器和偏移量寄存器,它们用于确定下一条要执行的指令。这个步骤是真正执行任务 1 的开始。

4.又过了 10ms ,从任务1切换回到任务 0 ,整个流程是怎样的? TSS 是如何变化的?各个寄存器的值是如何变化的?

  • 将0存入currnt: 使下次执行时钟中断处理函数时,执行ljmp时选择的是$TSS1_SEL。
  • 通过 ljmp 指令从任务0切换至任务1: 确保再从任务0切换回任务1时,可以正常进行,将当前各寄存器的状态和值存入tss1内。

在 timer_interrupt 处理程序内,执行ljmp指令从任务1切换至任务0之前,tss1的状态。(注:0xe78至0xedf为tss1)

在这里插入图片描述

在 timer_interrupt 处理程序内,执行ljmp指令从任务1切换至任务0之后,tss1的状态。

在这里插入图片描述

  • 将任务0的各寄存器状态和值从 tss0 中加载到各寄存器中: 通过 $TSS0_SEL 选择符从gdt中查找得到tss0的地址,进而在tss0内得到各寄存器的值,将其加载进各寄存器中。

在 timer_interrupt 处理程序内,执行ljmp指令从任务1切换至任务0之前,tss0以及当前各个寄存器的状态。(注:0xbf8至0xc5f为tss0)

在这里插入图片描述

在 timer_interrupt 处理程序内,执行ljmp指令从任务1切换至任务0之后,tss0以及当前各个寄存器的状态。

在这里插入图片描述

  • 执行任务0: 按照新加载进来的cs:eip,以及各寄存器值和状态,执行任务0。

5.请详细总结任务切换的过程。

  • 在时钟中断处理函数中,首先根据current的值判断执行ljmp时应该使用哪个tss的选择符作为参数。current的值通常指向当前正在执行的任务的tss。
  • 在执行ljmp指令之前,需要将当前任务的各寄存器状态和值保存到当前的tss内。这个操作是为了保存当前任务的上下文,以便在需要时可以正确地恢复。
  • 执行ljmp指令进行任务切换。这个指令会根据参数中的tss选择符去gdt表内查找对应的tss地址。然后,通过这个地址获取到新的tss内容,并将这些内容加载到各寄存器中。
  • 此时,已经恢复到了上次进行任务切换时的状态,并开始执行导致切换的那条指令的下一条指令。

任务切换过程是通过保存和恢复任务的上下文来实现的。在保存上下文时,需要将各寄存器的状态和值存储到tss中。在恢复上下文时,需要从tss中获取各寄存器的值并将其加载到相应的寄存器中。这样就可以实现在一个任务执行过程中,能够在不同任务之间进行切换。

这篇关于HIT_OS_LAB2 调试分析 Linux 0.00 多任务切换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345868

相关文章

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的