• 2019-2020-1 20199304《Linux内核原理与分析》第三周作业


    1.操作系统是如何工作的?

    计算机三个法宝(3个关键性的方法机制):

    存储程序计算机、函数调用堆栈、中断机制。

    1.1堆栈:

    在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。

    1.1.1堆栈作用

     -记录函数调用框架
     -传递函数参数
     -保存返回值的地址
     -提供函数内部局部变量的存储空间
    

    1.1.2堆栈的特性:

    最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列。 堆栈中定义了一些操作。 两个最重要的是PUSH和POP。 PUSH操作在堆栈的顶部加入一 个元素。POP操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一。

    1.2中断

    中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。

    1.2.1中断分类

     -硬件中断(Hardware Interrupt)
        -可屏蔽中断(maskable interrupt)。硬件中断的一类,可通过在中断屏蔽寄存器中设定位掩码来关闭。
        -非可屏蔽中断(non-maskable interrupt,NMI)。硬件中断的一类,无法通过在中断屏蔽寄存器中设定位掩码来关闭。典型例子是时钟中断(一个硬件时钟以恒定频率—如50Hz—发出的中断)。
        -处理器间中断(interprocessor interrupt)。一种特殊的硬件中断。由处理器发出,被其它处理器接收。仅见于多处理器系统,以便于处理器间通信或同步。
        -伪中断(spurious interrupt)。一类不希望被产生的硬件中断。发生的原因有很多种,如中断线路上电气信号异常,或是中断请求设备本身有问题。
     -软件中断(Software Interrupt)
        -软件中断。是一条CPU指令,用以自陷一个中断。由于软中断指令通常要运行一个切换CPU至内核态(Kernel Mode/Ring 0)的子例程,它常被用作实现系统调用(System call)。
    

    1.2.2中断作用

     -提高计算机系统效率。计算机系统中处理机的工作速度远高于外围设备的工作速度。通过中断可以协调它们之间的工作。当外围设备需要与处理机交换信息时,由外围设备向处理机发出中断请求,处理机及时响应并作相应处理。不交换信息时,处理机和外围设备处于各自独立的并行工作状态。
     -维持系统可靠正常工作。现代计算机中,程序员不能直接干预和操纵机器,必须通过中断系统向操作系统发出请求,由操作系统来实现人为干预。主存储器中往往有多道程序和各自的存储空间。在程序运行过程中,如出现越界访问,有可能引起程序混乱或相互破坏信息。为避免这类事件的发生,由存储管理部件进行监测,一旦发生越界访问,向处理机发出中断请求,处理机立即采取保护措施。
     -满足实时处理要求。在实时系统中,各种监测和控制装置随机地向处理机发出中断请求,处理机随时响应并进行处理。
     -提供故障现场处理手段。处理机中设有各种故障检测和错误诊断的部件,一旦发现故障或错误,立即发出中断请求,进行故障现场记录和隔离,为进一步处理提供必要的依据。
    

    2.实验

    2.1实验内容:

    完成一个简单的时间片轮转多道程序内核代码

    -根据老师指导按照实验步骤,在实验楼环境下打开shell:
    cd LinuxKernel/linux-3.9.4

    rm -rf mykernel

    patch -p1 < ../mykernel_for_linux3.9.4sc.patch

    make allnoconfig

    make

    qemu -kernel arch/x86/boot/bzImage

    然后 cd mykernel

    看到mymain.c和myinterrupt.c.
    mymain.c代码如下:

    myinterrupt.c代码如下:

    下面是一个简单的时间片轮转多道程序内核代码。
    mypcb.h

    define MAX_TASK_NUM 4

    define KERNEL_STACK_SIZE 1024*8

    /* CPU-specific state of this task */

    struct Thread {

    unsigned long ip;

    unsigned long sp;

    };

    typedef struct PCB{

    int pid;

    volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

    char stack[KERNEL_STACK_SIZE];
    /* CPU-specific state of this task */

    struct Thread thread;

    unsigned long task_entry;

    struct PCB *next;

    }tPCB;

    void my_schedule(void);

    定义一个进程控制块pcb结构体

    task_entry:进程入口函数

    thread:保存eip和esp

    state:进程状态,用于判断是否调度

    其中的内嵌汇编代码为核心:

    "pushl %%ebp " /* save ebp */

    "movl %%esp,%0 " /* save esp */

    "movl %2,%%esp " /* restore esp */

    "movl %2,%%ebp " /* restore ebp */

    "movl $1f,%1 " /* save eip */

    "pushl %3 "

    "ret " /* restore eip */

    "=m" (prev->thread.sp),"=m" (prev->thread.ip)

    "m" (next->thread.sp),"m" (next->thread.ip)

    "pushl %%ebp " /* save ebp */

    "movl %%esp,%0 " /* save esp */

    "movl %2,%%esp " /* restore esp */

    "movl %2,%%ebp " /* restore ebp */

    "movl $1f,%1 " /* save eip */

    "pushl %3 " "ret " /* restore eip */

    "=m" (prev->thread.sp),"=m" (prev->thread.ip)

    "m" (next->thread.sp),"m" (next->thread.ip)

    3.对操作系统是如何工作的学习理解。

        Linux将内核程序和基于之上的用户程序分开处理,分别运行在用户态和内核态。当一个程序在用户态执行时,它不能直接访问内核数据结构或内核的程序。然而,当应用程序在内核态下运行时,这些限制就不再有效。在一个程序执行时,大部分时间都处在用户态下,只有需要内核所提供的服务时才切换到内核态。当内核满足了用户程序的请求后,它让程序又回到用户台下。
       进程是动态的实体,内核是进程的管理者。在单处理系统中,任何时候只有一个进程在运行,它要么处于用户态,要么处于内核态。稍后我们会分析用户态与内核态之间的转换。
       然而在linux内核是可重入的,这意味着若干个进程可以同时在内核态下执行。当然,在单处理系统上只有一个进程在真正运行,但是有许多进程可能在等待CPU或某一I/O操作完成时在内核态下被阻塞。例如,当内核代表某一进程发出一个读磁盘请求后,就让磁盘控制器处理这个请求并且恢复执行其它进程。当设备满足了读请求时,有一个中断就会通知内核,从而恢复以前的进程继续执行。
  • 相关阅读:
    层模型--绝对定位(position:absolute)
    什么是层模型?
    浮动模型
    流动模型(二)
    插值方法
    CFS调度分析(内核版本:2.6.34)
    CRC检验
    ubuntu误删home目录
    随想
    Android——Activity生命周期
  • 原文地址:https://www.cnblogs.com/20199304lbs/p/11606673.html
Copyright © 2020-2023  润新知