一.分析system_call中断处理过程

实验

下载最新menu,并在test.c中增加mkdir与mkdir-asm函数原型

rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
vim test.c

增加下面的代码:

int Mkdir(int argc,char *argv[]){
if(mkdir(argv[1],S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0)
printf("New dir successfully!\n");
else
printf("New dir failed!\n");
return 0;
}
int MkdirAsm(int argc,char *argv[]){
int intr;
mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
__asm__ __volatile__(
"int $0x80;\n\t"
: "=a" (intr)
: "a"(39),"b"(argv[1]),"c"(mode)
:"memory"
);
if(intr == 0)
printf("New dirasm successfully!\n");
else
printf("New dirasm failed!\n");
return 0;
}

有两点需要强调,这也是我实验过程中出现过问题,才改进之后的代码!

  • 注意加头文件#include <sys/stat.h> #include <sys/types.h>
  • mkdir系统调用的结果是创建一个目录,而MenuOS并没有ls这个命令,所以为了验证我们添加mkdir和mkdir-asm命令成功,必须在函数中添加相应的判断与输出的语句,所以与上次实验代码相比,这里多了if与else语句和printf语句。否则我们无法验证在MenuOS中命令是否执行成功。





    上面这个图我是先用mkdir创建了一个testdir目录,显示创建成功;随后我又用mkdir-asm又创建testdir这个目录,因为这个目录刚才已经用mkdir创建过,所以必然失败,这也变相说明上一步mkdir创建成功;随后我又用mkdir-asm创建了testdir1,显示创建成功。

    下一步进行gdb调试:
cd ..
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S //启动并“冰冻”
gdb linux-3.18.6/vmlinux
target remote:1234 //连接到刚启动的虚拟机



上图为b start_kernel之后的结果。

根据39号系统调用的内核函数sys_mkdir,执行b sys_mkdir



结果系统停在了启动的“半路上”。并不是像断sys_time那样。很显然,这说明在内核启动过程中,必然要调用sys_mkdir该系统调用(虽然我现在还不知道有哪些过程要调用它,但可以肯定的是一定有过程调用它!)。

还得出一条心得就是实验楼环境是真的不好用,每当我把当前界面换到启动的虚拟机,则必然造成死机。只有重新开始实验,这样造成的结果就是我还得重新下载menu,重新编写test.c。不仅如此,还无法实施对mkdi与mkdir-asm的跟踪,因为一切换到MenuOS就卡掉了,根本没法输入命令。

总结

system_call到iret之间的简化后伪代码:

ENTRY(system_call)
SAVE_ALL
syscall_call:
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%eax) //保存返回值
syscall_exit:
testl $_TIF_ALLWORK_MASK,%ecx //current—>work
jne syscall_exit_work
restore_all:
RESTORE_INT_REGS
irq_return:
INTERRUPT_PETURN
ENDPROC(system_call)
syscall_exit_work:
testl $_TIF_WORK_SYSCALLEXIT,%ecx
jz work_pending
END(syscall_exit_work)
work_pending:
testb $_TIF_NEED_RESCHED,%c1
jz work_notifysig
work_resched:
call schedule
jz restore_all
work_notifysig:
...
END(work_pending)

流程图:



简化后的伪代码中只留下了一部分重要代码。比如对系统调用结束时要做的工作,这里只留下了两个判断,一个是是否有需要处理的信号,如果有,那就跳到相应的处理入口地址;第二个是是否需要进程调用,如果有那就转去处理进程调用,如果没有就结束。其实我们浏览没有简化的代码会发现,在这个过程中还有判断是否发生异常及异常处理等代码。

二.课本第九、十章内核同步

临界区的引出

共享资源之所以要防止并发访问,是因为如果多个执行线程同时访问和操作数据,就有可能发生各个线程之间相互覆盖共享数据的情况,造成被访问数据处于不一致状态。而访问和操作共享数据的代码段就被称为临界区。所以两个执行中的线程不可能处于同一个临界区中共同执行,一个临界区在执行完之前不可被打断。

同步和互斥

互斥指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。

同步是散布在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。

加锁

如果有一个线程对共享的数据加锁,则其他的线程就不能再访问该共享数据,必须等解锁之后才能去访问。简而言之,对同一共享数据,特定时间内只有一个线程可以进入与该共享数据对应的临界区。

死锁

  • 若系统中存在一组进程(两个或多个进程),它们中的每一个进程都占用了某种资源而又都在等待其中另一个进程所占用的资源,这种等待永远不能结束,则说系统出现了“死锁”。或说这组进程处于“死锁”状态。
  • 死锁产生的必要条件
    • 互斥使用资源
    • 占有并等待资源
    • 不可抢夺资源
    • 循环等待资源
  • 解决死锁的办法就是打破上述一个或多个必要条件。

自旋锁

自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图获得一个被已经持有的自旋锁,那么该线程就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求锁的执行线程便能立刻得到它们继续执行。在任意时间,自旋锁都可以防止多于一个的执行线程同时进入临界区。同一个锁可以用在多个位置。

信号量

  • 计数信号量,比如读者-写者问题中的读者的数量。
  • 二值信号量,比如读者-写者问题中对读者数量count的访问。

BLK:大内核锁

BLK是一个全局自旋锁,使用它主要是为了方便Linux最初的SMP过度到细粒度加锁机制。

  • 持有BLK的任务仍然可以睡眠。
  • BLK是一种递归锁。
  • BLK只可用在进程上下文中。
  • 新的用户不允许使用BLK。

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

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

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

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

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

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

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

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

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

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

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

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

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

  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. 《Linux内核原理与分析》第一周作业 20189210

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

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

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

随机推荐

  1. VSCode打开大文件插件

    hexdump for vscode 其实没什么插件,上面的是十六进制文件的插件,对于大文件还是建议用专业的ST或者Notepad++这些.

  2. mysql 性能容量评估

    性能容量评估   分析上线业务场景 评估数据库服务器所需性能指标 预估可能成为瓶颈的服务器资源 帮助数据库性能调优   数据库服务器硬件性能指标项: 磁盘IO性能 内存容量 CPU 网络吞吐量 磁盘容 ...

  3. 鼠标悬浮弹出标题制作JQuery

    今天给客户制作的网站里面加个效果,当鼠标在列表图片之外时,标题不显示,当鼠标悬浮在图片之上时,标题从底部弹出. 效果图如下: 鼠标悬浮前: 鼠标悬浮后: html代码如下: <ul class= ...

  4. 单源最短路Dijstra算法

    Dijstra算法是寻找从某一顶点i出发到大其他顶点的最短路径.Distra算法的思想与Prim算法很像,它收录顶点的规则是按照路径长度递增的顺序收录的.设v0是源顶点,我们要寻找从v0出发到其他任意 ...

  5. curl的用法

    1.官网:https://curl.haxx.se/ 2.版本安全漏洞:https://curl.haxx.se/docs/security.html 3.github:https://github. ...

  6. 出现“Windows资源管理器已停止工作”错误

    出现"Windows资源管理器已停止工作"错误 什么是资源管理器呢,explorer.exe进程的作用就是让我们管理计算机中的资源! 今天开电脑的时候就一直提示windows资源管 ...

  7. vue2.X props 数据传递 实现组件内数据与组件外的数据的双向绑定

    vue2.0 禁止 子组件修改父组件数据 在Vue2中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribute传递props给组件内,组件内只能 ...

  8. c# out ref

    out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字.例如 ...

  9. mysql经常使用查询:group by,左连接,子查询,having where

    前几天去了两个比較牛的互联网公司面试.在sql这块都遇到问题了,哎.可惜呀,先把简单的梳理一下 成绩表 score 1.group by 使用 按某一个维度进行分组 比如: 求每一个同学的总分 SEL ...

  10. MVC初了解

    MVC:Model-View-Controller,将数据和显示形式分离. Model:能够看做是三层中的D层+B层,实现业务逻辑和与数据库的交互. View:看做是U层,用来显示数据. Contro ...