博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟踪sys_mkdir的系统调用过程
阅读量:2172 次
发布时间:2019-05-01

本文共 3172 字,大约阅读时间需要 10 分钟。

原创作品转载请注明出处 《Linux内核分析》MOOC课程

  1. 向MenuOS系统中加入自己写的系统调用函数:
    1.1我们首先下载最新的MenuOS代码,此代码中将time加入了MenuOS中,而且修改了Makefile,输入make rootfs即可制作根文件系统,使用qemu启动内核加载rootfs.img文件系统。
    我们输入命令:
git clone  https://github.com/mengning/menu.gitcd menumake rootfs

即可完成环境的配置。

1.2然后我们打开test.c文件加入上次实验写的系统调用函数
加入两个函数

int newdir(int argc, char *argv[]){    if(mkdir("new dir", S_IRWXU) == 0)        printf("new dir create success\n");    else        printf("new dir create failed\n");    return 0;    }int newdirAsm(int argc, char *argv[]){        char *dirName = "new dirAsm";        mode_t mode = S_IRWXU;        int returnValue = 0;        asm        (                "movl $39, %%eax\r\n"                "movl %1, %%ebx\r\n"                "movl %2, %%ecx\r\n"                "int $0x80\r\n"                "movl %%eax,  %0"                :"=m"(returnValue)                :"d"(dirName),"D"(mode)        );        if(returnValue == 0)            printf("new dirAsm create success\n");        else            printf("new dirAsm create failed\n");               return 0;}

并且在main函数里面加入

MenuConfig("newdir","create a new directory",newdir);MenuConfig("newdir-asm","create a new directory(asm)",newdirAsm);

完成之后我们重新编译,make rootfs编译并且进入内核。

输入newdir和newdir-asm就会发现命令生效了

这里写图片描述

这里写图片描述
2. 跟踪中断处理的代码
我们使用gdb来调试跟踪一下MenuOS中mkdir的系统调用过程。
首先在终端输入

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s –S

并且在另一个终端打开gdb

输入

gdbtui(gdb)file linux-3.18.6/vmlinux #加载符号表(gdb)target remote:1234 #建立gdb和gdbserver之间的连接(gdb)b sys_mkdir #在sys_mkdir建立断点(gdb)c

然后我们在qemu中输入newdir,会触发断点,然后我们进入gdb跟踪调试

这里写图片描述
断点停到SYSCALL_DEFINE2.
这个SYSCALL_DEFINE2在这里其实就是

asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode)

因为:我们打开源码中/linux-3.18.6/include/linux/syscalls.h文件,会看到一堆宏定义。

我们拿刚才那个定义为例:、

#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)

这是把SYSCALL_DEFINE2定义为SYSCALL_DEFINEx然后把name与下划线连接(##表示前后两个参数当做串连接)

然后看下SYSCALL_DEFINEx的定义

#define SYSCALL_DEFINEx(x, sname, ...)				\	SYSCALL_METADATA(sname, x, __VA_ARGS__)			\	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

我们继续找到__SYSCALL_DEFINEx的定义。

#define __SYSCALL_DEFINEx(x, name, ...)					\asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))…

剩余部分省略

__这里把SYSCALL_DEFINEx定义为asmlinkage long sys##name…
而name就是前面的_name,在这里也就是_mkdir。
所以SYSCALL2_DEFINE2定义为了asmlinkage long sys_mkdir,正式我们要找的系统调用。
弄清楚了之后,接下来我们继续跟踪。
我们在此处x/s pathname打印一下参数,看到参数正是我们要创建的文件夹名字
这里写图片描述
我们按s步入执行,发现进入了一个函数SYSCALL_DEFINE3,根据上面的理解,这里应该是sys_mkdirat系统调用
这里写图片描述
我们来看下这个函数里面的操作

user_path_create security_path_mkdirvfs_mkdirdone_path_create

我们步入执行进入user_path_create

这里写图片描述
里面会调用kern_path_create
然后进入kern_path_create,里面还会调用do_path_lookup
然后我们返回到SYSCALL_DEFINE3中执行完毕,会跳入到schedule中

这里写图片描述

如果继续执行的话就会进入到不可调试的部分只能通过阅读代码来跟踪了。
这里写图片描述
上面的调用过程我们来用一个流程图来描述一下:
这里写图片描述
3. 分析系统调用过程的汇编代码
/linux-3.18.6/arch/x86/kernel/entry_32.S中ENTRY(system_call)与ENDPROC(system_call)之间的内容就是完成系统调用的汇编代码。
提取出主要的处理过程就是:

ENTRY(system_call)SAVE_ALLsystem_call:	call *sys_call_table(,%eax,4)#根据系统调用号来调用系统调用的处理函数…system_exit:	testl $_TIF_ALLWORK_MASK, %ecx #判断当前任务是否需要处理syscall_exit_work	jne syscall_exit_work #如果需要处理则跳转到syscall_exit_workrestore_all:	RESTORE_INT_REGS #不需要处理的话进行RESTORE_ALLirq_return:	INTERRUPT_RETURN #返回ENDPROC(system_call)

整个中断处理的过程我们可以用一个流程图画出来

这里写图片描述

你可能感兴趣的文章
Java并发指南8:AQS中的公平锁与非公平锁,Condtion
查看>>
Java网络编程和NIO详解6:Linux epoll实现原理详解
查看>>
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
查看>>
Java网络编程与NIO详解8:浅析mmap和Direct Buffer
查看>>
Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型
查看>>
Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)
查看>>
深入理解JVM虚拟机1:JVM内存的结构与消失的永久代
查看>>
深入理解JVM虚拟机3:垃圾回收器详解
查看>>
深入理解JVM虚拟机4:Java class介绍与解析实践
查看>>
深入理解JVM虚拟机5:虚拟机字节码执行引擎
查看>>
深入理解JVM虚拟机6:深入理解JVM类加载机制
查看>>
深入了解JVM虚拟机8:Java的编译期优化与运行期优化
查看>>
深入理解JVM虚拟机9:JVM监控工具与诊断实践
查看>>
深入理解JVM虚拟机10:JVM常用参数以及调优实践
查看>>
深入理解JVM虚拟机11:Java内存异常原理与实践
查看>>
深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战
查看>>
深入理解JVM虚拟机13:再谈四种引用及GC实践
查看>>
Spring源码剖析1:Spring概述
查看>>
Spring源码剖析2:初探Spring IOC核心流程
查看>>
Spring源码剖析3:Spring IOC容器的加载过程
查看>>