Linux-0.11 kernel目录进程管理asm.s详解

这篇具有很好参考价值的文章主要介绍了Linux-0.11 kernel目录进程管理asm.s详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux-0.11 kernel目录进程管理asm.s详解

模块简介

该模块和CPU异常处理相关,在代码结构上asm.s和traps.c强相关。 CPU探测到异常时,主要分为两种处理方式,一种是有错误码,另一种是没有错误码,对应的方法就是error_codeno_error_code。在下面的函数详解中,将主要以两个函数展开。

函数详解

no_error_code

对于一些异常而言,CPU在出现这些异常时不会将error code压入栈中。其和一般的中断类似,会将ss,esp,eflags,cs,eip这几个寄存器的值压入内核栈中。如下图所示:

Linux-0.11 kernel目录进程管理asm.s详解

接下来,以divide_error为例,其会将do_divide_error的地址压入内核栈中, no_error_code第一步便是将do_divide_error的值存入eax中。

no_error_code:
	xchgl %eax,(%esp)

no_error_code接下来就是保存一些CPU上下文,

pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs

在保护好CPU上下文之后,接下来就是为调用do_divide_error做一些准备,将入参压入栈。

pushl $0		# "error code"
lea 44(%esp),%edx
pushl %edx

将下来初始化段寄存器,加载内核的数据段选择符。

movl $0x10,%edx
mov %dx,%ds
mov %dx,%es
mov %dx,%fs

这些工作都准备完成之后,就通过call去调用do_divide_error这个c函数。

call *%eax

调用完毕之后,恢复现场。

addl $8,%esp
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret

error_code

对于一些异常而言,CPU在出现这些异常除了会将ss,esp,eflags,cs,eip这几个寄存器的值压入内核栈中以外,还会将error_code压入内核栈中。如下图所示:

Linux-0.11 kernel目录进程管理asm.s详解

以double_fault为例,出现该异常时,会将do_double_fault的地址压入栈中。

double_fault:
	pushl $do_double_fault

error_code最初会将error_code的值写入eax寄存器中,将do_double_fault的地址写入ebx寄存器中。

error_code:
	xchgl %eax,4(%esp)		# error code <-> %eax
	xchgl %ebx,(%esp)		# &function <-> %ebx

接下来保存CPU的上下文

pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs

接下来做的也是为调用c函数做准备,首先将error_code和出错的地址压入栈中

pushl %eax			# error code
lea 44(%esp),%eax		# offset
pushl %eax

将下来初始化段寄存器,加载内核的数据段选择符。

movl $0x10,%edx
mov %dx,%ds
mov %dx,%es
mov %dx,%fs

这些工作都准备完成之后,就通过call去调用do_divide_error这个c函数。

call *%ebx

最后的工作便是用于恢复CPU上下文,

addl $8,%esp
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret

divide_error:

无error code,其将do_divide_error的地址压入栈中。

pushl $do_divide_error

debug

无error code,其将do_int3的地址压入栈中,进而调用no_error_code

debug:
	pushl $do_int3		# _do_debug
	jmp no_error_code

nmi

无error code,其将do_nmi的地址压入栈中,进而调用no_error_code

nmi:
	pushl $do_nmi
	jmp no_error_code

int3

无error code,其将do_int3的地址压入栈中,进而调用no_error_code

int3:
	pushl $do_int3
	jmp no_error_code

overflow

无error code,其将do_overflow的地址压入栈中,进而调用no_error_code

overflow:
	pushl $do_overflow
	jmp no_error_code

bounds

无error code,其将do_bounds的地址压入栈中,进而调用no_error_code

bounds:
	pushl $do_bounds
	jmp no_error_code

invalid_op

无error code,其将do_invalid_op的地址压入栈中,进而调用no_error_code

invalid_op:
	pushl $do_invalid_op
	jmp no_error_code

coprocessor_segment_overrun

无error code,其将coprocessor_segment_overrun的地址压入栈中,进而调用no_error_code

coprocessor_segment_overrun:
	pushl $do_coprocessor_segment_overrun
	jmp no_error_code

reserved

无error code,其将reserved的地址压入栈中,进而调用no_error_code

reserved:
	pushl $do_reserved
	jmp no_error_code

double_fault

有error code,其将do_double_fault的地址压入栈中,进而调用error_code

double_fault:
	pushl $do_double_fault

invalid_TSS

有error code,其将do_invalid_TSS的地址压入栈中,进而调用error_code

invalid_TSS:
	pushl $do_invalid_TSS
	jmp error_code

segment_not_present

有error code,其将do_segment_not_present的地址压入栈中,进而调用error_code

segment_not_present:
	pushl $do_segment_not_present
	jmp error_code

stack_segment

有error code,其将do_stack_segment的地址压入栈中,进而跳转执行error_code

stack_segment:
	pushl $do_stack_segment
	jmp error_code

general_protection

有error code,其将do_general_protection的地址压入栈中,进而跳转执行error_code文章来源地址https://www.toymoban.com/news/detail-471705.html

general_protection:
	pushl $do_general_protection
	jmp error_code

Q & A

到了这里,关于Linux-0.11 kernel目录进程管理asm.s详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 0.11: 从开机到执行shell

    参考闪客的系列,将开机到执行shell的整个过程浓缩成本文。 https://github.com/dibingfa/flash-linux0.11-talk 当按下开机键的那一刻,在主板上提前写死的固件程序  BIOS  会将硬盘中 启动区的 512 字节 的数据,原封不动复制到 内存中的 0x7c00  这个位置,并跳转到那个位置进行执行。

    2024年04月13日
    浏览(29)
  • 无法获得dpkg前端锁、Linux之E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?(解决方法)

    无法获得dpkg前端锁的解决方法 sudo rm /var/lib/dpkg/lock sudo rm /var/lib/dpkg/lock-frontend sudo rm /var/cache/apt/archives/lock 输入以上三个命令即可解除占用。解除后,继续运行apt命令,已经顺利运行了。 解除前端锁后,Linux之E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它? 这

    2024年04月27日
    浏览(39)
  • Linux Kernel:thread_info与进程调度

    环境: Kernel Version:Linux-5.10 ARCH:ARM64      一:概述 Linux是多任务系统,它支持(看上去)并发执行的若干进程。系统中同时真正在运行的进程数目最多不超过CPU数目,因此内核会按照短的时间间隔在不同的进程之间切换(用户是注意不到的),这样就造成了同时处理多进

    2024年02月08日
    浏览(59)
  • 操作系统实验 2.3系统调用:linux-0.11-lab “为版本0内核增加一个系统调用getjiffies” 和 “在用户程序中使用新增的系统调用”

    打开 vscode ,在如图所示位置打开 ~/os/linux-0.11-lab/0 文件夹 1.定义getjiffies系统调用 题目中给的提示:进入到 unistd.h 文件中 阅读代码,可以发现上图划线处有个系统调用名为 getpid :返回当前进程号——这与我们期望实现的功能类似:通过系统调用返回jiffies值。 于是此时希望

    2023年04月08日
    浏览(97)
  • 【Linux0.11代码分析】07 之 kernel execve() 函数 实现原理

    系列文章如下: 系列文章汇总:《【Linux0.11代码分析】之 系列文章链接汇总(全)》 https://blog.csdn.net/Ciellee/article/details/130510069 . 1.《【Linux0.11代码分析】01 之 代码目录分析》 2.《【Linux0.11代码分析】02 之 bootsect.s 启动流程》 3.《

    2024年02月03日
    浏览(46)
  • linux 查看某个进程所在目录

    1、通过 ps -ef | grep xxx 查看进程信息 2、通过 ll /proc/PID 命令查看进程所在目录位置 Linux在启动一个进程时,系统会在 /proc 下创建一个以PID命名的文件夹,在该文件夹下会有我们的进程的信息,其中包括一个名为exe的文件即记录了绝对路径,通过 ll 或 ls –l 命令即可查看. cw

    2024年02月16日
    浏览(62)
  • windows一键安装redis7.0.11

    下载地址: https://gitcode.net/zengliguang/windows_redis7.0.11_offline_install.git   使用git进行进行clone下载   在电脑桌面或者其他文件夹下 ,鼠标右键点击  选择git clone  ,下图中url为下载地址,Directory为本地存储路径,点击ok开始下载 如下图所示已成功下载   双击 redis-install-win.ba

    2024年02月08日
    浏览(46)
  • Linux Kernel内核整体架构(图文详解)

    本文是“Linux内核分析”系列文章的第一篇,会以内核的核心功能为出发点,描述Linux内核的整体架构,以及架构之下主要的软件子系统。之后,会介绍Linux内核源文件的目录结构,并和各个软件子系统对应。 注:本文和其它的“Linux内核分析”文章都基于如下约定: a) 内核版

    2024年02月11日
    浏览(41)
  • Linux查看某进程所部署的目录路径

    1.首先查看系统中正在跑的进程都有什么 2.然后通过抓取你要看的进程名,比如哪些服务 Linux在启动一个进程时,系统会在 /proc 下创建一个 以PID命名的文件夹; 在该文件夹下会有我们的进程的信息; 通过 ll 或 ls –l 查看/proc/xxx服务的pid(上面第二步抓取的) 为exe的文件即

    2024年02月16日
    浏览(43)
  • linux根据进程PID查找任务安装目录

    1、通过top 命令 找到PID,执行top命令后可以按住shift+m 按照内存从大到小倒序排列 2、假设pid为23730 通过 如下命令 可以查看任务详情 ps -aux|grep -v grep |grep 23730 3、通过cd /proc/23730 查看任务目录 4、进入目录后执行 ls -ail 出现的列表中 cwd- 开头的是任务目录

    2024年02月12日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包