Linux内核第五节 20135332武西垚

20135332武西垚

  1. 在MenuOS中通过添加代码增加自定义的系统调用命令
  2. 使用gdb跟踪调试内核
  3. 简单分析system_call代码了解系统调用在内核代码中的处理过程

由于本周实验是在Kali虚拟机上进行操作的,具体实现过程中的代码和实验楼里的环境有一定的差异,在解决了各种报错之后终于完成了实验,在这次的实验报告中将较为详细的记录实验过程中遇到的问题以及解决方案,以便以后更加熟练地理解与掌握Kali的操作原理和步骤。

实验——分析system_call中断处理过程

给MenuOS增加time和time-asm命令

  • 在源代码中增加getpid和getpid-asm的代码

    Kali虚拟机中menu文件夹存放的目录为/home/YL/menu,打开目录即可看到内核相关代码,通过vim test.c指令打开并编辑源代码,在其中加入自定义添加的函数代码

  • 在main函数中增加MenuConfig

    在main函数中添加对应的函数调用代码,格式与代码中原有的函数调用格式保持一致。

  • make rootfs(将分步编译的过程编写在脚本当中自动生成)

    进行这一步的时候无论是使用make rootfs脚本编译还是make all都会出现错误:Nothing to be done,make clean指令也无效。其原因是该文件目录下有一个名为rootfs的文件夹,导致编译失败,删除该文件夹后即可成功编译,结果如下图所示。

使用gdb跟踪系统调用内核函数sys_time

  • 启动内核到调试状态

    qemu-system-x86_64 -kernel bzImage -initrd /home/YL/rootfs.img -S -s
  • 重新启动一个终端进行调试

    在内核中加载符号表:

    file /usr/src/linux-source-4.4/vmlinux

    由于Kali是64位机所以要进行设置否则会报错"Remote ‘g‘packet reply is too long"。

    set arch i386:x86-64

    之后使用1234端口连接并开始调试。运行结果如下图所示。

  • 设置断点并单步跟踪调试

    注意不能在start _ kernel处设置断点因为此时还没有完整设置好64位的运行环境,因此无法设置断点进行调试。

    s单步执行,sys _ getpid 函数返回之后进入汇编代码处理,gdb无法继续跟踪,在sys _ call处设置断点也无法停下来调试。

系统调用在内核代码中的处理过程

系统调用在内核代码中的工作机制和初始化

系统调用的工作机制

系统调用机制的初始化

\init\main.c start _ kernel中调用了trap _ init()函数。

\arch\x86\kernel\traps.c代码中定义了系统调用的初始化。

#ifdef CONFIG_X86_32
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
//系统调用的中断向量和system_call的入口。一旦执行0x80,系统就自动跳转到system _call执行
set_bit(SYSCALL_VECTOR, used_vectors);
#endif
分析system_call伪代码
ENTRY(system_call)          #0x80的下一条 指令
    RING0_INT_FRAME         # can‘t unwind into user space anyway
    ASM_CLAC
    pushl_cfi %eax          # save orig_eax
    SAVE_ALL                # 保存系统寄存器信息
    GET_THREAD_INFO(%ebp)   # 获取thread_info结构的信息
                # system call tracing in operation / emulation
    testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) # 测试是否有系统跟踪
    jnz syscall_trace_entry   # 如果有系统跟踪,先执行,然后再回来
    cmpl $(NR_syscalls), %eax # 比较eax中的系统调用号和最大syscall,超过则无效
    jae syscall_badsys # 无效的系统调用 直接返回
syscall_call:
    call *sys_call_table(,%eax,4) # 调用实际的系统调用程序
syscall_after_call:
    movl %eax,PT_EAX(%esp)      # 将系统调用的返回值eax存储在栈中
syscall_exit:
    LOCKDEP_SYS_EXIT
    DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don‘t miss an interrupt

    TRACE_IRQS_OFF
    movl TI_flags(%ebp), %ecx
    testl $_TIF_ALLWORK_MASK, %ecx  # 判断当前的任务是否需要进程调度
    jne syscall_exit_work           # 未完成,则去执行这些任务
restore_all:
    TRACE_IRQS_IRET         # iret 从系统调用返回
系统调用流程分析

时间: 2024-10-13 22:23:11

Linux内核第五节 20135332武西垚的相关文章

Linux内核第六节 20135332武西垚

如何描述一个进程:进程描述符的数据结构: 如何创建一个进程:内核是如何执行的,以及新创建的进程从哪里开始执行: 使用gdb跟踪新进程的创建过程. 进程的描述 操作系统三大功能: 进程管理(最核心最基础) 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息.struct task_struct数据结构很庞大. 进程的状态:Linux进程的状态(就绪态.运行态.阻塞态)与操作

Linux内核第七节 20135332武西垚

预处理.编译.链接和目标文件的格式 可执行程序是怎么得来的 以C语言为例,c代码经过编译器的预处理,编译成汇编代码,由汇编器编译成目标代码,再链接成可执行文件,由操作系统加载到cpu里来执行. (截图) .c----.asm(.s)-----.o(二进制文件)-----A.out(可执行文件) 预处理负责把include的文件包含进来及宏替换等工作 可执行文件是使用共享库的. 静态编译 -static 把库里的东西都放在里面了所以比较大 可执行文件的内部是怎样的? 目标文件的格式ELF (截图)

Linux内核总结博客 20135332武西垚

http://www.cnblogs.com/wuxiyao/p/5220677.htmlhttp://www.cnblogs.com/wuxiyao/p/5247571.htmlhttp://www.cnblogs.com/wuxiyao/p/5272748.htmlhttp://www.cnblogs.com/wuxiyao/p/5299117.htmlhttp://www.cnblogs.com/wuxiyao/p/5325392.htmlhttp://www.cnblogs.com/wu

Linux内核第三节 20135332武西垚

总结部分: Linux内核源代码: Arch 支持不同cpu的源代码:主要关注x86 Init   内核启动的相关代码:主要关注main.c,整个Linux内核启动代码start_kernel函数 Kernel 核心代码 installing the kernel source:如何安装内核源代码 构建Linux系统os 使用gdb跟踪内核运行过程 -S cpu在初始化之前将其冻结 -s 在tcp端口创建server 分析start_kernel函数 Trap init 涉及中断 这个函数用来做

Linux内核第八节 20135332武西垚

第一种分类: I/O-bound:频繁进行I/O,并且需要花费很多时间等待I/O完成 CPU-bound:计算密集,需要大量的CPU时间进行运算 第二种分类: 批处理进程:不必与用户交互,常在后台进行:不必很快响应(典型的批处理系统:编译程序.科学计算). 实时进程:有实时需求,不应被低优先级进程阻塞,响应时间短.要稳定(典型的实时进程:视频/音频.机械控制等). 交互式进程:需要经常与用户交互,因此要花很多时间等待用户输入操作,响应时间要快,平均延迟要低(典型的交互式程序:shell.文本编辑

Linux学习第五节课-标准I/O和管道

Linux学习第五节课 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 三十一.标准输入和输出 程序:指令+数据 读入数据:Input 输出数据:Output 打开的文件都有一个fd: file descriptor (文

linux内核(五)虚拟文件系统

虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备. 虚拟文件系统本身是linux内核的一部分,是纯软件的东西,并不需要任何硬件的支持. 1. 虚拟文件系统的作用 虚拟文件系统(VFS)是linux内核和存储设备之间的抽象层,主要有以下好处. - 简化了应用程序的开发:应用通过统一的系统调用访问各种存储介质 - 简化了新文件系统加入内核的过程:新文件系统只要实现VFS的各个接口即可,不需要修改内核部分

linux内核---嵌入式linux内核的五个子系统

转自:https://blog.csdn.net/qq_27522735/article/details/63251168 Linux内核主要由进程调度(SCHED).内存管理(MM).虚拟文件系统(VFS).网络接口(NET)和进程间通信(IPC)5个子系统组成,如图1所示. 图1 Linux内核的组成部分与关系 1.进程调度 进程调度控制系统中的多个进程对CPU的访问,使得多个进程能在CPU中"微观串行,宏观并行"地执行.进程调度处于系统的中心位置,内核中其他的子系统都依赖它,因为

linux入门-第五节:Linux的用户及用户组管理

[认识/etc/passwd和/etc/shadow] /etc/passwd由':'分割成7个字段,每个字段的具体含义是: 1)用户名(如第一行中的root就是用户名),代表用户账号的字符串.用户名字符可以是大小写字母.数字.减号(不能出现在首位).点以及下划线,其他字符不合法.虽然用户名中可以出现点,但不建议使用,尤其是首位为点时,另外减号也不建议使用,因为容易造成混淆. 2)存放的就是该账号的口令,为什么是'x'呢?早期的unix系统口令确实是存放在这里,但基于安全因素,后来就将其存放到/