2018-2019-1 20189221 《Linux内核原理与分析》第六周作业

实验五

实验过程

将Fork函数移植到Linux的MenuOS

fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程。在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。通过fork返回的值来判断当前进程是子进程还是父进程。

启动MenuOS:

在test.c中添加代码如下:


int Fork(int argc, char *argv[])
{ pid_t fpid;
int count = 0;
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n",getpid());
count++;
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
count++;
}
printf("count: %d\n",count);
return 0;
} int main()
{
PrintMenuOS();
SetPrompt("MenuOS>>");
MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
MenuConfig("quit","Quit from MenuOS",Quit);
MenuConfig("fork","fork a child process",Fork); ExecuteMenu();

运行结果:

sys_call过程分析

gdb调试:

由于实验楼多次卡顿,十分浪费时间

调试代码:

$ gdb
(gdb) file linux-3.18.6/vmlinux
(gdb) target remote:1234
(gdb) continue

在sys_fork设置断点,在qemu中输入fork-asm命令,可以看到停在了sys_fork()函数中。

然后s单步执行,finish返回do_fork函数,返回值$2=866,即分配了pid=866的子进程。继续单步,到了schedule()中,此时发生了进程调度。finish后schedule返回。

再次单步执行,出现Cannot find bounds of current function。此时gdb已无法跟踪。

gdb中输入c继续执行,看到qemu中输出fid = 866,即子进程的pid为866。

system_call的代码:

ENTRY(system_call)
RING0_INT_FRAME
ASM_CLAC
pushl_cfi %eax //保存系统调用号;
SAVE_ALL //可以用到的所有CPU寄存器保存到栈中
GET_THREAD_INFO(%ebp) //ebp用于存放当前进程thread_info结构的地址
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax //检查系统调用号(系统调用号应小于NR_syscalls),
jae syscall_badsys //不合法,跳入到异常处理
syscall_call:
call *sys_call_table(,%eax,4) //合法,对照系统调用号在系统调用表中寻找相应服务例程
movl %eax,PT_EAX(%esp) //保存返回值到栈中
syscall_exit:
testl $_TIF_ALLWORK_MASK, %ecx //检查是否需要处理信号
jne syscall_exit_work //需要,进入 syscall_exit_work
restore_all:
TRACE_IRQS_IRET //不需要,执行restore_all恢复,返回用户态
irq_return:
INTERRUPT_RETURN //相当于iret

system_call流程:

实验总结

系统调用是特殊的中断函数,是多种中断处理过程的集合

系统调用的过程其实是另一种上下文切换的实现:

首先SAVE ALL保存上下文

根据IDT调用内核函数

执行RESTORE_ALL并返回用户模式

系统调用与中断的共同之处

  • 保存现场

    在系统调用时,用SAVE_ALL来保存系统调用时的上下文。

    中断处理的第一步也是要保存中断程序现场。

    中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。

  • 确定中断信息

    在系统调用中,需要将系统调用号通过eax传入,通过sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。

    中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。

  • 处理中断

    跳转到相应的中断处理程序后,对中断进行处理。

  • 返回

    系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。

    同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。

系统调用与一般函数的不同之处

  • 不是通过“CALL”指令而是通过“INT”指令发起调用;

  • 不是通过“RET”指令,而是通过“IRET”指令完成调用返回;

  • 当到达内核态后,操作系统需要严格检查系统调用传递的参数,确保不破坏整个系统的安全性;

  • 执行系统调用可导致进程等待某事件发生,从而可引起进程切换;

2018-2019-1 20189221 《Linux内核原理与分析》第六周作业的更多相关文章

  1. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  3. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  4. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  5. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  6. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

  10. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

随机推荐

  1. STL之map学习实例

    ``` #include<iostream> #include<algorithm> #include<vector> #include<map> #i ...

  2. [No000012E]WPF(6/7):概念绑定

    WPF 的体系结构,标记扩展,依赖属性,逻辑树/可视化树,布局,转换等.今天,我们将讨论 WPF 最重要的一部分——绑定.WPF 带来了优秀的数据绑定方式,可以让我们绑定数据对象,这样每次对象发生更改 ...

  3. tensorflow的tile使用

    当你需要按照矩阵维度复制数据时候,可以使用tensorflow的tile函数 a1 = tf.tile(a, [2, 2]) 表示把a的第一个维度复制两次,第二个维度复制2次.注意使用tf.nn.so ...

  4. 【数论】Prime Time UVA - 10200 大素数 Miller Robin 模板

    题意:验证1~10000 的数 n^n+n+41 中素数的个数.每个询问给出a,b  求区间[a,b]中质数出现的比例,保留两位 题解:质数会爆到1e8 所以用miller robin , 另外一个优 ...

  5. zabbix客户端自动注册

    1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中.我们本篇内容与上篇相反,这次是Active age ...

  6. Xcode编译警告Assigning to 'id<XXXDelegat> ——Nullable' from incompatible type 'XXXView *const_strong'

    编译报警告 可能是 自定义分类使用协议时出现与父类协议的冲突 解决方法如下:    

  7. PHP进阶-网络编程基础概念

    以太网协议图: 以太网协议: 发送header(发送至mac地址,接收者mac地址).data到网线中所有连接的计算机,然后每个机子接收数据包的时候都是用以太网协议的, 然后解析header头,看是否 ...

  8. [network] netfilter

    netfilter 是什么? netfilter.org is home to the software of the packet filtering framework inside the Li ...

  9. [linux] 对一个虚拟机的研究

    今天拿到了一个vmware的虚拟机硬盘镜像,是其他公司的演示产品. 启动之后是带着ubuntu字样的grub.进入系统之后也不是shell,而是一个定制的命令行.所以如果想了解细节的话,只能单独挂硬盘 ...

  10. el表达式获取对象属性值 返回值类型

    实现 数字页码时 遇到的一个问题. 后端servlet 在request.setAttribute("page",page); page 为pagebean的实例对象,pagebe ...