操作系统『1』概述

文章目录

    • 一、预备知识
    • 二、什么是操作系统
    • 三、操作系统软件的分类
    • 四、Kernel
    • 五、操作系统历史
    • 六、操作系统结构

一、预备知识

  • 预备知识
  • 计算机结构原理(Intel 80386+)
  • 数据结构
  • C和汇编语言

   

二、什么是操作系统

  • 什么是操作系统

  • 在用户的角度,操作系统是一个 控制软件
          用于管理应用程序:控制这些应用程序如何运行;并限制不同的应用程序占用不同的资源;为应用程序提供服务(如IO、访问服务);

  • 在管理者的角度,为应用程序、底层硬件提供相应的管理、控制 和 服务功能。

  • 在计算机内部的角度,操作系统是 资源管理器操作系统把 CPU 、 磁盘 和 内存 这三部分物理资源,分别 抽象成 进程、文件 和 地址空间,给应用程序使用。
    【操作系统代码必须是高效的,低耗 CPU、磁盘、内存。】
       

    操作系统『1』概述

       操作系统需要权衡:
    (1)空间与时间
    (2)性能和可预测性
    (3)公平和性能

    三、操作系统软件的分类

    • 操作系统软件的分类
      Shell (外壳):命令行接口
      GUI(图形用户界面)
      Kernel(操作系统内部):内核 ,是我们研究的重点。
         

    四、Kernel

    (1) Kernel 组件包括:

    • CPU调度源
    • 物理内存管理‘
    • 虚拟内存管理
    • 文件系统管理
    • 中断处理 、IO 与设备驱动 (和硬件(重要的硬件:CPU、内存、硬盘)直接打交道,是需要了解和掌握的)
         

    (2) OS Kernel 的特征:

    • 并发
         计算机系统中同时存在多个运行的程序,需要 OS 管理和调度。
    • 共享
         “同时”访问(因为内存块之间相互是隔离的) 或者是 互斥共享、分时访问,是由具体资源的特征决定。
    • 虚拟
         利用多道程序设计技术,让每个用户都觉得有一个计算机专门为他服务。
    • 异步
         程序的执行不是一贯到底,而是走走停停,向前推进的速度不可预知。但只要运行环境相同,OS 需要保证程序运行的结果也是相同的。

    五、操作系统历史

    • 单用户系统
    • 批处理系统(体现了并发的特征)
    • 多道程序系统(保持多个工作在内存中并且在各工作间复用CPU
    • 分时(现在计算机的时间片是千分之一秒,时钟这个外设会定期产生中断,把控制权交给操作系统,让操作系统完成中断。)
    • 个人计算机:每个用户一个系统
    • 分布式计算:每个用户多个系统(通过网络实现松耦合。)
         

    (安卓用的是 Linux 内核。)

    六、操作系统结构

       “单体”,比如之后实验会用到 UCore,意味着,它的各个模块之间,是通过函数调用来实现访问的。【紧耦合】
    (1)微内核架构
       希望不是上述的紧耦合的方式,而是松耦合的方式,更方便扩展,基于这样的思想——微内核架构:在操作系统的内核中,只放最基本的功能 (比如中断处理、消息传递; 而文件系统、内存管理、网络协议栈都是放在外围,以 服务 的形式存在,而服务与服务之间是通过内核的消息传递机制进行通信,这样的话就是松耦合啦。因为地址隔离,所以相互之间无法恶意破坏对方的空间。酱紫就灵活而安全,不过性能会有所下降,毕竟数据倒腾来倒腾去的。) 尽可能把内核功能移到用户空间。
    (2)外核结构
       还有另一种更加极端的架构——“外核”,希望内核分成两部分,一部分和硬件打交道,另一部分和具体应用打交道。
    (3)虚拟机管理器 VMM
       在一台物理计算机上虚拟出多台计算机系统,给上层的操作系统使用。
       虚拟机管理器将单独的机器接口转换成很多的虚拟机,每个虚拟机都是一个原始计算机系统的有效副本, 并能完成所有的处理器指令。
       相当于有隔离,操作系统下是VMM,VMM 之下才是硬件。

    操作系统『1』概述
  • ps 查询当前进程:
    :可以列出系统当前运行的所有进程,包括由其他用户启动的进程。
    操作系统『1』概述
    • 管道:LInux的强大之处在于它能把几个简单的命令联合成为复杂的功能,通过键盘上的管道符号 “|” 完成。如以下语句的作用就是 搜索 0917.text(前提是已经有这个文件了)中的命令,将输出分类 并 写入分类文件 到 result.text。(因为没啥排序的,所以 result.text 是空白的。)

    -i:忽略大小写的不同。

    操作系统『1』概述
    less -l 是显示不隐藏的文件与文件夹详细信息,|less 是对文件或其他输出进行分页显示。
    • less 与 more 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会加载整个文件。

    • Vim:
          Vim是一款极方便的文本编辑软件,是 UNIX 下的同类型软件 VI 的改进版本。Vim经常被看作是“专门为程序员打造的文本编辑器”,功能强大且方便使用,便于进行程序开发。

    • gcc
         gcc 是由 GNU 推出的一款功能强大的、性能优越的多平台编译器。
         Gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。
      写个最简单的C代码:

      操作系统『1』概述
          执行 该命令将文件 hello.c 中的代码编译为机器码并存储在可执行文件 hello 中。 选项 -Wall 开启编译器几乎所有常用的警告。机器码的文件名是通过 选项指定的。该选项通常作为命令行中的最后一个参数。如果被省略,输出文件默认为 ‘a.out’。注意到如果当前目录中与可执行文件重名的文件已经存在,它将被覆盖。
          要运行该程序,输入可执行文件的路径如下:,这将可执行文件载入内存,并使 CPU 开始执行其包含的指令。 路径 ./ 指代当前目录,因此 ./hello 载入并执行当前目录下的可执行文件 ‘hello’。
      • AT&T汇编基本语法
           Ucore 中用到的是 AT&T 格式的汇编,与 Intel 格式的汇编有一些不同。二者语法上主要有以下几个不同:
        (1)寄存器命名原则
        AT&T: %eax
        Intel: eax
        (2)源/目的操作数顺序
        AT&T: movl %eax, %ebx
        Intel: mov ebx, eax
        (3)常数/立即数的格式 
        AT&T: movl $_value, %ebx
        Intel: mov eax, _value
        (4)把 value 的地址放入eax寄存器
        AT&T: movl KaTeX parse error: Expected ‘EOF’, got ‘&’ at position 60: … (5)操作数长度标识 AT&: movw %ax, %b…是表示地址引用,不加是表示值引用。对于局部变量,可以通过堆栈指针引用。
        (2)寄存器间接寻址
        AT&T: (%eax) Intel: [eax]
        (3)变址寻址
        AT&T: _variable(%eax) Intel: [eax + _variable]
        AT&T: _array( ,%eax, 4) Intel: [eax × 4 + _array]
        AT&T: _array(%ebx, %eax,8)
      • make
            GNU make (简称make) 是一种代码维护工具,在大中型项目中,它将根据程序各个模块的更新情况,自动的维护和生成目标代码。
            make命令执行时,需要一个 makefile (或Makefile)文件,以告诉make 命令需要怎么样的去编译和链接程序。首先,我们用一个示例来说明 makefile 的书写规则。这个示例来源于 gnu 的 make 使用手册,在这个示例中,我们的工程有 8个c文件,和3个头文件,我们要写一个 makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:
        (1)如果这个工程没有编译过,那么我们的所有 c 文件都要编译并被链接。
        (2)如果这个工程的某几个 c 文件被修改,那么我们只编译被修改的 c 文件,并链接目标程序。
        (3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的c文件,并链接目标程序。
        (4)只要我们的 makefile 写得够好,所有的这一切,我们只用一个 make 命令就可以完成,make 命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。
        makefile的规则:

      gdb 调试实例:
          先写一个有错误的例子:

      操作系统『1』概述
          为了查找该程序中出现的问题,利用 gdb ,按照以下步骤进行:
      (1)运行 “gdb bugging” ,加载 bugging 可执行文件;

      (2)执行装入的 bugging 命令;

      (3)使用 where 命令查看程序出错的地方;

      (4)利用 list 命令查看调用 gets 函数附近的代码;

      (5) 在 gdb 中,我们在第 11 行处设置断点,看看是否是在第11行出错;

      (6)程序重新运行到第 11 行处停止,这时程序正常,然后执行单步命令next;

      (7) 程序确实出错,能够导致 gets 函数出错的因素就是变量 string。重新执行测试程序,用 print 命令查看 string 的值;

      就会看到:(gdb) $1=0x0
      截图如下:

      操作系统『1』概述
      (8) 问题在于 string 指向的是一个无效指针,修改程序,在10行和11行之间增加一条语句 “string=buff; ”,重新编译程序,然后继续运行,将看到正确的程序运行结果。
          用gdb查看源代码可以用list命令,但是这个不够灵活。可以使用”layout src”命令,或者按Ctrl-X再按A,就会出现一个窗口可以查看源代码。 操作系统『1』概述
      • BIOS 【Basic Input Output System,即基本输入/输出系统】启动过程
            当计算机加电后,一般不直接执行操作系统,而是执行 系统初始化软件 ,完成基本 IO 初始化引导加载功能。简单地说,系统初始化软件就是在操作系统内核运行之前运行的一段小软件。通过这段小软件,我们可以初始化硬件设备、建立系统的内存空间映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。最终引导加载程序把操作系统内核映像加载到 RAM 中,并将系统控制权传递给它。
            对于绝大多数计算机系统而言,操作系统和应用软件是存放在磁盘(硬盘/软盘)、光盘、EPROM、ROM、Flash等可在掉电后继续保存数据的存储介质上。计算机启动后,CPU一开始会到一个特定的地址开始执行指令,这个特定的地址存放了系统初始化软件,负责完成计算机基本的 IO初始化,这是系统加电后运行的第一段软件代码。对于Intel 80386的体系结构而言,PC机中的系统初始化软件由 BIOS (其本质是一个固化在主板 Flash/CMOS 上的软件)和位于软盘/硬盘引导扇区中的 OS Boot Loader(在 ucore 中的 bootasm.S 和 bootmain.c)一起组成。BIOS实际上是被固化在计算机ROM(只读存储器)芯片上的一个特殊的软件,为上层软件提供最底层的、最直接的硬件控制与支持。 更形象地说,BIOS 就是 PC 计算机硬件与上层软件程序之间的一个”桥梁”,负责访问和控制硬件。
            以 Intel 80386 为例,计算机加电后,CPU 从物理地址0xFFFFFFF0(由初始化的CS:EIP 确定,此时 CS 和 IP 的值分别是 0xF000 和 0xFFF0 ) 开始执行。在 0xFFFFFFF0 这里只是存放了一条跳转指令,通过跳转指令跳到BIOS例行程序起始点。BIOS 做完计算机硬件自检和初始化后,会选择一个启动设备(例如软盘、硬盘、光盘等),并且读取该设备的第一扇区(即主引导扇区或启动扇区)到内存一个特定的地址0x7c00处,然后CPU控制权会转移到那个地址继续执行。至此BIOS的初始化工作做完了,进一步的工作交给了 ucore 的 bootloader。
            
      • bootloader启动过程
            BIOS 将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行 bootloader。bootloader完成的工作包括:
        (1)切换到保护模式,启用分段机制
        (2)读磁盘中ELF执行文件格式的ucore操作系统到内存
        (3)显示字符串信息
        (4)把控制权交给ucore操作系统
            
      • 操作系统启动过程
            当 bootloader 通过读取硬盘扇区把 ucore 在系统加载到内存后,就转跳到 ucore 操作系统在内存中的入口位置(kern/init.c中的kern_init函数的起始地址),这样 ucore 就接管了整个控制权。当前的ucore功能很简单,只完成基本的内存管理和外设中断管理。ucore主要完成的工作包括:
        初始化终端;显示字符串;显示堆栈中的多层函数调用关系;切换到保护模式,启用分段机制;初始化中断控制器,设置中断描述符表,初始化时钟中断,使能整个系统的中断机制;
        执行while(1)死循环。

      每日一问
      问:
          操作系统中的“管道”是什么 意思

          管道是单向的、先进先出的、无结构的、固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。
          管道提供了简单的流控制机制,进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样地,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。

      来源:Ang Ga Ga

      声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年8月16日
下一篇 2020年8月16日

相关推荐