网易云课堂学习

把write系统调用加入到MenuOS里面

我在试验过程中在MenuOS里加入了time、time-asm、write和write-asm命令。以time和time-asm为例,

步骤如下

  • 更新menu代码到最新版
  • 在main函数中增加MenuConfig
  • 增加对应的Time函数和TimeAsm函数
  • make rootfs

实验结果如图所示



然后使用gdb跟踪分析write系统调用函数。write对应的系统调用函数是sys_write

分析system_call的执行过程

首先看系统调用的初始化,在start_kernel里面有trap_init,也就是中断初始化的一个函数,trap_init里面有set_system_trap_gate(SYSCALL_VECTOR,&system_call)&system_call就是系统调用的入口。代码中一旦出现init 0x80的指令,立即就会跳转到system_call的位置,即ENTRY(system_call).

看一下ENTRY(system_call)的代码

490ENTRY(system_call)
491 RING0_INT_FRAME # can't unwind into user space anyway
492 ASM_CLAC
493 pushl_cfi %eax # save orig_eax
494 SAVE_ALL
495 GET_THREAD_INFO(%ebp)
496 # system call tracing in operation / emulation
497 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
498 jnz syscall_trace_entry
499 cmpl $(NR_syscalls), %eax
500 jae syscall_badsys
501syscall_call:
502 call *sys_call_table(,%eax,4)
503syscall_after_call:
504 movl %eax,PT_EAX(%esp) # store the return value
505syscall_exit:
506 LOCKDEP_SYS_EXIT
507 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
508 # setting need_resched or sigpending
509 # between sampling and the iret
510 TRACE_IRQS_OFF
511 movl TI_flags(%ebp), %ecx
512 testl $_TIF_ALLWORK_MASK, %ecx # current->work
513 jne syscall_exit_work
514
515restore_all:
516 TRACE_IRQS_IRET

关于汇编跳转指令的说明

JNS表示如果符号位没有被置位则跳转。

JAE表示如果超过或等于(>=)则跳转。

JNE表示如果不相等(<>)则跳转。

先判断是否符合跳转条件,再执行后面相应指令。

system_call的中断处理过程如下:

    1. SAVE_ALL保护现场。保护的是发生中断处,进程下一条指令的地址,还包括标志寄存器的内容。
  • 2)通过call *sys_call_table(,%eax,4)调用系统调用表,传递系统调用号,调用相应函数。
  • 3)syscall_after_call: movl %eax,PT_EAX(%esp)保存返回值。
  • 4)检测是否处理syscall_exit_work,如果不处理的话恢复现场。
  • 5)返回用户态。

Linux内核设计与实现

第9章内核同步介绍

(1)多个执行线程同时访问和操作数据,就有可能发生各线程之间相互覆盖共享数据的情况,造成共享数据处于不一致状态。并发访问共享数据是造成系统不稳定的一类隐患,而且这种错误一般难以跟踪和调试。在使用共享内存的应用程序中,程序员必须特别留意保护共享资源,防止共享资源并发访问,内核也不例外。

(2)临界区是访问和操作共享数据的代码段。

(3)避免并发和防止竞争条件称为同步。

(4)原子操作在操作执行结束前不可被打断。

(5)可以通过加锁来保护临界区资源。

  • 内核中可能造成并发的原因:
  • 中断——中断几乎可以在任何时刻异步发生,也就可以随时打断当前正在执行的代码。
  • 软中断和tasklet——内核能在任何时刻唤醒或调度软中断和tasklet,打断当前正在执行的代码。
  • 内核抢占——因为内核具有抢占性,所以内核中的任务可能会被另一任务抢占。

(6)尽管释放锁的顺序和死锁无关,但最好还是以获得锁的相反顺序来释放锁。

第10章内核同步方法

原子操作:

内核提供了两组原子操作接口,一组针对整数进行操作,另一组针对单独的位进行操作。

针对整数的原子操作只能对atomic_t类型的数据进行处理。

原子性与顺序性:原子性确保指令执行期间不被打断,要么全部执行,要么根本不执行。顺序性确保即使两条或多条指令同时出现在独立的执行线程中,他们依然保持本该的执行顺序。顺序性通过屏障指令来实施。

自旋锁:

自旋锁只能被一个可执行线程持有。如果一个线程试图争用自旋锁,他就会处于忙循环——旋转——等待锁重新可用中一直自旋,浪费处理器时间。

所以自旋锁不应被长时间占有。这正是使用自旋锁的初衷:在短期内进行轻量级加锁。

处理锁争用的其他方式:让请求线程睡眠,直到锁重新可用时唤醒他。

中断处理程序中使用自旋锁时要在获取锁之前禁止本地中断,否则中断处理程序会打断正持有锁的内核代码。

下半部可以抢占进程上下文中的代码,所以下半部和进程上下文共享数据时,要保护进程上下文中的共享数据。

信号量

信号量是一种睡眠锁,他比自旋锁提供了更好的处理器利用率,因为没有把时间花费在忙等待上。

在占用信号量的同时不能占用自旋锁。

锁被持有时间长时用信号量,被持有时间短时用自旋锁。

信号量包括互斥信号量和计数信号量。计数信号量在一个时刻至多有count个持有者。

互斥体是相对于信号量更简单的睡眠锁。

自旋锁与信号量的比较

需求 建议的加锁方法
低开销加锁 优先使用自旋锁
短期锁定 优先使用自旋锁
长期加锁 优先使用互斥体
中断上下文中加锁 使用自旋锁
持有锁需要睡眠 使用互斥体

自旋锁方法列表

方法 描述
spin_lock() 获取指定的自旋锁
spin_lock_irq() 禁止本地中断并获得指定的锁
spin_lock_irqsave() 保存本地中断的当前状态,禁止本地中断,并获取指定的锁
spin_unlock() 释放指定的锁
spin_unlock_irq() 释放指定的锁,并激活本地中断
spin_unlock_irqrestore() 释放指定的锁,并让本地中断恢复到以前状态
spin_lock_init() 动态初始化指定的spinlock_t
spin_trylock() 试图获取指定的锁,如果未获取,则返回非0
spin_is_locked() 如果指定的锁当前正在被获取,则返回非0,否则返回0

信号量方法列表

方法 描述
sema_init(struct semaphore *,int) 以指定的计数值初始化动态创建的信号量
init_MUTEX(struct semaphore *) 以计数值1初始化动态创建的信号量
init_MUTEX_LOCKED(struct semaphore *) 以计数值0初始化动态创建的信号量
down_interruptible(struct semaphore *) 以试图获得指定的信号量,如果信号量已被争用,则进入可中断睡眠状态
down (struct semaphore *) 以试图获得指定的信号量,如果信号量已被争用,则进入不可中断睡眠状态
down_trylock (struct semaphore *) 以试图获得指定的信号量,如果信号量已被争用,则立刻返回非0值
up (struct semaphore *) 以释放指定的信号量,如果睡眠队列不空,则唤醒其中一个任务

出现的问题

(1)实验楼的实验环境不稳定,总是出现错误

(2)加入自己写的系统调用的时候,在write函数后面没写(int argc,char *argv[])这句,出现错误,经查询了解到这两个就是用于接受参数和记录参数信息的。

20169219《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. Cisco IOS版本命名规则

    首先说说IOS的运行平台,c2500.c2600.c4500.c2950代表运行此IOS的硬件平台,例如:C2500指2500系列路由器. 其次,看看IOS的版本,IOS有主版本号:11.0.11.1 ...

  2. codeforces 57C 思维

    题意:求出长度为n仅由1到n数字组成的非降序列与非升序列的个数. 思路:转化为求非降序列(非升序列)的个数.n个元素想象为n个离散的点x1,x2,x3,...,xn,在最开头补上一个点x0为1,在最末 ...

  3. mysql 在windows server下发生系统错误 1067, 进程意外终止的解决方法

    mysql 在windows server下发生系统错误 1067, 进程意外终止,请检查系统盘下的windows目录下是否存在mysql的配置文件my.ini,如存在,将其删除或改名即可.

  4. 彻底搞懂word-break、word-wrap、white-space

    原文链接: https://juejin.im/post/5b8905456fb9a01a105966b4 white-space.word-break.word-wrap(overflow-wrap ...

  5. Codeforces 505C Mr. Kitayuta, the Treasure Hunter:dp【考虑可用范围】

    题目链接:http://codeforces.com/problemset/problem/505/C 题意: 有n个宝石,分别在位置p[i].(1 <= n,p[i] <= 30000) ...

  6. ajax技术返回json如何处理

    json只是一种文本字符串. Smarty是一个使用PHP写出来的模板引擎. ajax如何处理json数据格式 ①json的格式如下: "{属性名:属性值,属性名:属性值}". 因 ...

  7. linux应用之make命令详解

    从源代码安装过软件的朋友一定对 ./configure && make && make install 安装三步曲非常熟悉了.然而究竟这个过程中的每一步幕后都发生了些什 ...

  8. unity的一些重要技巧(转)【整理他人的东西】

    刚开始学习Unity3D时间不长,在看各种资料.除了官方的手册以外,其他人的经验也是非常有益的.偶尔看到老外这篇文章,觉得还不错,于是翻译过来和大家共享.原文地址: http://devmag.org ...

  9. Android中高效的显示图片之三——缓存图片

    加载一张图片到UI相对比较简单,如果一次要加载一组图片,就会变得麻烦很多.像ListView,GridView,ViewPager等控件,需要显示的图片和将要显示的图片数量可能会很大. 为了减少内存使 ...

  10. NOIp2018集训test-10-18 (bike day4)

    这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...