linux跟踪系统调用到内核,跟踪分析 Linux 内核 5.0 系统调用处理过程

跟踪分析 Linux 内核 5.0 系统调用处理过程

学号尾号: 155

基于 Ubuntu kylin 18.10 虚拟机

实验准备

下载和编译内核wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.tar.xz # 下载内核

# 解压文件

xz-dLinux-5.0.1.tar.xz

tar-xvfLinux-5.0.tar.xz

cdLinux-5.0

# 编译内核

make i386_defconfig

此处出现报错:

ab7653affab982b574eb7acc55df2e04.gif

执行以下命令

apt-get install flex

再次执行

make i386_defconfig

出现报错

ab7653affab982b574eb7acc55df2e04.gif

执行以下命令

apt-get install bison

再次执行make i386_defconfig

make

出现报错

ab7653affab982b574eb7acc55df2e04.gif

执行以下命令

apt-get install libssl-dev

再次执行

make

等待一段时间后, 控制台会输出如下信息, 表示编译完成

ab7653affab982b574eb7acc55df2e04.gif

制作根文件系统cd..

mkdir rootfs

Gitclone https://github.com/mengning/menu.git

cd menu

gcc-pthread-o init linktable.c menu.c test.c-m32-static

此处出现问题:

ab7653affab982b574eb7acc55df2e04.gifapt install gcc-multilib

gcc-pthread-o init linktable.c menu.c test.c-m32-static

再次出现问题

ab7653affab982b574eb7acc55df2e04.gifapt-getinstall gcc-4.8gcc-4.8-multilib g++-4.8g++-4.8-multilib

gcc-pthread-o init linktable.c menu.c test.c-m32-static

成功了

ab7653affab982b574eb7acc55df2e04.gifcd../rootfs

cp../menu/init./

find.|cpio-o-Hnewc|gzip-9>../rootfs.img

制作成功!

ab7653affab982b574eb7acc55df2e04.gif

启动 MenuOScd..

qemu-kernelLinux-5.0/arch/x86/boot/bzImage-initrd rootfs.img

启动成功!

ab7653affab982b574eb7acc55df2e04.gif

---

跟踪系统调用

我的学号尾号是 155, 在查阅系统调用表后, 发现 155 号系统调用是

#define __NR_sched_getparam 155

函数的原型是#include

// 该函数用于根据进程号获取进程的调度参数, pid 用于指定要获取调度参数的进程号, 为 0 时表示获取当前进程的调度参数

//param 用于存储获得的进程调度参数

// 返回 0 时表示成功获得进程的调度参数, 返回 - 1 时表示出错, 并设置 errno

//errno 有两种, EPERM: 调用进程没有足够的权限来获取调度参数. ESRCH: 进程 pid 不存在.

intsched_getparam(pid_tpid,structsched_param*param);

structsched_param

{

int32_tsched_priority;// 获取调度参数时, 此成员将反映分配给线程或进程的优先级

int32_tsched_curpriority;// 获取调度参数时, 此成员将设置为线程或进程当前运行的优先级. 这是内核在进行调度决策时使用的值.

union

{

int32_treserved[8];

struct

{

int32_t__ss_low_priority;

int32_t__ss_max_repl;

structtimespec __ss_repl_period;

structtimespec __ss_init_budget;

}__ss;

}__ss_un;

}

#definesched_ss_low_priority __ss_un.__ss.__ss_low_priority

#definesched_ss_max_repl __ss_un.__ss.__ss_max_repl

#definesched_ss_repl_period __ss_un.__ss.__ss_repl_period

#definesched_ss_init_budget __ss_un.__ss.__ss_init_budget

对于该系统调用, 我们可以写出如下代码对其进行测试// 在 menu 文件夹中的 test.c 文件中加入如下代码

#include

inttest_get_param()

{

structsched_param param;

sched_getparam(0,¶m);

printf("The original priority of the process is %d\n",param.sched_priority);

}

intmain()

{

PrintMenuOS();

SetPrompt("MenuOS>>");

MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);

MenuConfig("quit","Quit from MenuOS",Quit);

MenuConfig("time","Show System Time",Time);

MenuConfig("time-asm","Show System Time(asm)",TimeAsm);

MenuConfig("get_param","根据进程号获取进程的优先级",test_get_param);

ExecuteMenu();

}

重新制作根文件系统gcc-pthread-o init linktable.c menu.c test.c-m32-static

cd../rootfs

cp../menu/init./

find.|cpio-o-Hnewc|gzip-9>../rootfs.img

使用 gdb 跟踪调试内核cd..

qemu-kernelLinux-5.0/arch/x86/boot/bzImage-initrd rootfs.img-S-s-append nokaslr

此时启动的 qemu 窗口是 stopped 的状态

ab7653affab982b574eb7acc55df2e04.gif

另开一个 shell 窗口gdb

file vmlinux# target remote 之前加载符号表

target remote:1234# 建立 gdb 和 gdbserver 之间的连接, 按 c 让 qemu 上的 Linux 系统继续运行

b sys_sched_getparam# 打上断点

ab7653affab982b574eb7acc55df2e04.gif

在 gdb 窗口中输入

c

ab7653affab982b574eb7acc55df2e04.gif

在 qemu 窗口中输入

get_param

ab7653affab982b574eb7acc55df2e04.gif

在 gdb 窗口中输入

c

ab7653affab982b574eb7acc55df2e04.gif

系统调用分析

可以看到, sched_getparam 系统调用的流程如下:

用户调用 sched_getparam 接口

将系统调用号 155 放入 eax 寄存器

执行 int $0x80 指令产生一个向量为 128 的编程异常, 进入内核态

保护现场

根据系统调用号, 查找系统调用表, 找到中断处理程序的地址并执行中断处理程序

恢复现场, 进入用户态

由此可以看出, 用户态进程是无法访问内核的内存空间的, 只有内核态进程才能访问内核. 因此当执行系统调用时, 必须要先将进程转换成内核态才能执行系统调用, 执行完毕后再恢复到用户态.

来源: http://www.bubuko.com/infodetail-2993095.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值