网易云课堂学习

把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. shell 字符串操作

    赋值: str="i am vincen" 计算字符串长度: ${#str} 字符串截取: ${str:2} ${str:2:3} 从开头删除匹配的子串: ${str#" ...

  2. In a Web Application and Mobile (hybrid), how to know which this platform running?

    needed depending on the platform to change the CSS to suit the size of the font. for example the DbG ...

  3. 大话设计模式--中介者模式 Mediator --C++实现实例

    1. 中介者模式: 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立改变他们之间的交互. Mediator的出现减少了各个Colleague的耦 ...

  4. Struts2的使用

    Struts2的核心类库 名称 说明 Struts2-core-2.3.4.jar 核心类库 Xwork-core-2.3.4.jar Xwork的核心类库 Ognl-3.0.5.jar Ognl表达 ...

  5. 属性 visibility

    http://www.w3school.com.cn/cssref/pr_class_visibility.asp 可能的值 值 描述 visible 默认值.元素是可见的. hidden 元素是不可 ...

  6. Codeforces 479E Riding in a Lift:前缀和/差分优化dp

    题目链接:http://codeforces.com/problemset/problem/479/E 题意: 有一栋n层的房子. 还有一个无聊的人在玩电梯,每次玩电梯都会从某一层坐到另外一层. 他初 ...

  7. python 面试题(一)

    1 Python的函数参数传递 看两个例子: Python   1 2 3 4 5 a = 1 def fun(a):     a = 2 fun(a) print a  # 1   Python   ...

  8. 51nod 1829(函数)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1829 本题目相当于: n个不同的小球,放入到m个可区分的盒子 ...

  9. 【leetcode刷题笔记】Plus One

    Given a non-negative number represented as an array of digits, plus one to the number. The digits ar ...

  10. CodeForces - 1017E :The Supersonic Rocket (几何+KMP,判定凸包是否同构)

    After the war, the supersonic rocket became the most common public transportation. Each supersonic r ...