format titles

This commit is contained in:
yuchen 2015-04-09 19:56:33 +08:00
parent ba1480cf61
commit 0bba4377cf
151 changed files with 145 additions and 272 deletions

View File

@ -160,7 +160,7 @@
* [项目组成](lab7/lab7_2_2_files.md)
* [同步互斥的设计与实现](lab7/lab7_3_synchronization_implement.md)
* [实验执行流程概述](lab7/lab7_3_1_experiment.md)
* [计时器的原理和实现](lab6/lab7_3_2_timer_implement.md)
* [计时器的原理和实现](lab7/lab7_3_2_timer_implement.md)
* [同步互斥的底层支撑](lab7/lab7_3_2_synchronization_basic_support.md)
* [信号量](lab7/lab7_3_3_semaphore.md)
* [管程和条件变量](lab7/lab7_3_4_monitors.md)

View File

@ -1,8 +1,8 @@
## 1.实验目的:
## 实验目的:
- 了解操作系统开发实验环境
- 熟悉命令行方式的编译、调试工程
- 掌握基于硬件模拟器的调试技术
- 熟悉C语言编程和指针的概念
- 了解X86汇编语言
- 了解X86汇编语言

View File

@ -1,5 +1,5 @@
### 2.1 了解OS实验
### 了解OS实验
写一个操作系统难吗别被现在上百万行的Linux和Windows操作系统吓倒。当年Thompson乘他老婆带着小孩度假留他一人在家时写了UNIX当年Linus还是一个21岁大学生时完成了Linux雏形。站在这些巨人的肩膀上我们能否也尝试一下做“巨人”的滋味呢
MIT的Frans Kaashoek等在2006年参考PDP-11上的UNIX Version 6写了一个可在X86上跑的操作系统xv6基于MIT License用于学生学习操作系统。我们可以站在他们的肩膀上基于xv6的设计尝试着一步一步完成一个从“空空如也”到“五脏俱全”的“麻雀”操作系统—ucore此“麻雀”包含虚存管理、进程管理、处理器调度、同步互斥、进程间通信、文件系统等主要内核功能总的内核代码量C+asm不会超过5K行。充分体现了“小而全”的指导思想。

View File

@ -1,5 +1,5 @@
#### 2.2.1 开发OS lab实验的简单步骤
#### 开发OS lab实验的简单步骤
在某git server比如 https://github.com/chyyuu/ucore_lab 可下载我们提供的lab1~lab8实验软件中大致经过如下过程就可以完成使用。

View File

@ -1,5 +1,5 @@
#### 2.2.2 通过虚拟机使用Linux实验环境推荐最容易的实验环境安装方法
#### 通过虚拟机使用Linux实验环境推荐最容易的实验环境安装方法
这是最简单的一种通过虚拟机方式使用Linux并完成OS各个实验的方法不需要安装Linux操作系统和各种实验所需开发软件。首先安装VirtualBox 虚拟机软件有windows版本和其他OS版本可到 http://www.virtualbox.org/wiki/Downloads 下载),然后在[百度云盘上](http://pan.baidu.com/s/11zjRK)下载一个已经安装好各种所需编辑/开发/调试/运行软件的Linux实验环境的VirtualBox虚拟硬盘文件(mooc-os-2015.vdi.xz包含一个虚拟磁盘镜像文件和两个配置描述文件下载此文件的网址址见https://github.com/chyyuu/ucore_lab下的README中的描述)。用2345好压软件(有windows版本可到http://www.haozip.com 下载。一般软件解压不了xz格式的压缩文件先解压到C盘的vms目录下即
C:\vms\mooc-os-2015.vdi

View File

@ -1,5 +1,5 @@
##### 2.2.3.1 实验中可能使用的软件
##### 实验中可能使用的软件
***编辑器***

View File

@ -1,5 +1,5 @@
#### 2.2.3 安装使用Linux实验环境适合希望自己安装Linux系统的同学
#### 安装使用Linux实验环境适合希望自己安装Linux系统的同学
这里我们主要以Ubuntu Linux 14.0464 bit作为整个实验的系统软件环境。首先我们需要安装Ubuntu Linux 14.04。

View File

@ -1,5 +1,5 @@
### 2.2 设置实验环境
### 设置实验环境
我们参考了MIT的xv6、Harvard的OS161和Linux等设计了ucore OS实验所有OS实验需在Linux下运行。对于经验不足的同学推荐参考“通过虚拟机使用Linux实验环境”一节用虚拟机方式进行试验。
> 也有同学在MAC系统和Windows系统中搭建实验环境不过过程相对比较复杂这里就不展开介绍了。

View File

@ -1,5 +1,5 @@
###### 2.3.1.1 编译简单的 C 程序
###### 编译简单的 C 程序
C 语言经典的入门例子是 Hello World下面是一示例代码

View File

@ -1,5 +1,5 @@
##### 2.3.1.2 AT&T汇编基本语法
##### AT&T汇编基本语法
Ucore中用到的是AT&T格式的汇编与Intel格式的汇编有一些不同。二者语法上主要有以下几个不同
```

View File

@ -1,5 +1,5 @@
##### 2.3.1.3 GCC基本内联汇编
##### GCC基本内联汇编
GCC 提供了两内内联汇编语句inline asm statements基本内联汇编语句basic inline asm statement)和扩展内联汇编语句extended inline asm statement。GCC基本内联汇编很简单一般是按照下面的格式

View File

@ -1,5 +1,5 @@
##### 2.3.1.4 GCC扩展内联汇编
##### GCC扩展内联汇编
使用GCC扩展内联汇编的例子如下

View File

@ -1,6 +1,6 @@
#### 2.3.1 gcc的基本用法
#### gcc的基本用法
如果你还没装gcc编译环境或自己不确定装没装不妨先执行
sudo apt-get install build-essential
sudo apt-get install build-essential

View File

@ -1,5 +1,5 @@
#### 2.3.2 make和Makefile
#### make和Makefile
GNU make(简称make)是一种代码维护工具,在大中型项目中,它将根据程序各个模块的更新情况,自动的维护和生成目标代码。

View File

@ -1,5 +1,5 @@
#### 2.3.3 gdb使用
#### gdb使用
gdb 是功能强大的调试程序,可完成如下的调试任务:
- 设置断点

View File

@ -1,6 +1,4 @@
##### 2.3.4 进一步的相关内容
##### 进一步的相关内容
请同学网上搜寻相关资料学习:

View File

@ -1,5 +1,3 @@
### 了解编程开发调试的基本工具
### 2.3 了解编程开发调试的基本工具
在Ubuntu Linux中的C语言编程主要基于GNU C的语法通过gcc来编译并生成最终执行文件。GNU汇编assembler采用的是AT&T汇编格式Microsoft 汇编采用Intel格式。
在Ubuntu Linux中的C语言编程主要基于GNU C的语法通过gcc来编译并生成最终执行文件。GNU汇编assembler采用的是AT&T汇编格式Microsoft 汇编采用Intel格式。

View File

@ -1,5 +1,4 @@
##### 2.4.1.1 Linux运行环境
##### Linux运行环境
QEMU用于模拟一台x86计算机让ucore能够运行在QEMU上。为了能够正确的编译和安装 qemu尽量使用最新版本的qemuhttp://wiki.qemu.org/Download或者os ftp服务器上提供的qemu源码qemu-1.1.0.tar.gz。目前 qemu 能够支持最新的 gcc-4.x 编译器。例如:在 Ubuntu 12.04 系统中,默认得版本是 gcc-4.6.x (可以通过 gcc -v 或者 gcc --version 进行查看)。
@ -8,4 +7,4 @@ QEMU用于模拟一台x86计算机让ucore能够运行在QEMU上。为了能
sudo apt-get install qemu-system
也可采用下面描述的方法对qemu进行源码级安装。

View File

@ -1,5 +1,5 @@
###### 2.4.1.2.1 获得并应用修改
###### 获得并应用修改
编译qemu还会用到的库文件有 libsdl1.2-dev 等。安装命令如下:
@ -21,4 +21,4 @@
qemu.patch qemu
chy@chyhome-PC:~$cd qemu
chy@chyhome-PC:~$patch -p1 -u < ../qemu.patch

View File

@ -1,5 +1,5 @@
###### 2.4.1.2.2 配置、编译和安装
###### 配置、编译和安装
编译以及安装 qemu 前需要使用 <qemu>(表示qemu解压缩路径)下面的 configure 脚本生成相应的配置文件等。而 configure 脚本有较多的参数可供选择,可以通过如下命令进行查看:

View File

@ -1,2 +1,2 @@
##### 2.4.1.2 Linux环境下的源码级安装过程
##### Linux环境下的源码级安装过程

View File

@ -1 +1 @@
#### 2.4.1 安装硬件模拟器QEMU
#### 安装硬件模拟器QEMU

View File

@ -1,5 +1,5 @@
##### 2.4.2.1 运行参数
##### 运行参数
如果 qemu 使用的是默认 /usr/local/bin 安装路径,则在命令行中可以直接使用 qemu 命令运行程序。qemu 运行可以有多参数,格式如:

View File

@ -1,5 +1,5 @@
##### 2.4.2.2 常用调试命令
##### 常用调试命令
qemu中monitor的常用命令

View File

@ -1,2 +1 @@
#### 2.4.2 使用硬件模拟器QEMU
#### 使用硬件模拟器QEMU

View File

@ -1,5 +1,4 @@
#### 2.4.3 基于qemu内建模式调试ucore
#### 基于qemu内建模式调试ucore
调试举例:调试 lab1跟踪bootmain函数

View File

@ -1,4 +1,3 @@
##### 2.4.4.1 编译可调试的目标文件
##### 编译可调试的目标文件
为了使得编译出来的代码是能够被gdb这样的调试器调试我们需要在使用gcc编译源文件的时候添加参数"-g"。这样编译出来的目标文件中才会包含可以用于调试器进行调试的相关符号信息。

View File

@ -1,5 +1,4 @@
##### 2.4.4.2 ucore 代码编译
##### ucore 代码编译
(1) 编译过程:在解压缩后的 ucore 源码包中使用 make 命令即可。例如 lab1中
```

View File

@ -1,5 +1,4 @@
##### 2.4.4.3 使用远程调试
##### 使用远程调试
为了与qemu配合进行源代码级别的调试需要先让qemu进入等待gdb调试器的接入并且还不能让qemu中的CPU执行因此启动qemu的时候我们需要使用参数-S s这两个参数来做到这一点。在使用了前面提到的参数启动qemu之后qemu中的CPU并不会马上开始执行这时我们启动gdb然后在gdb命令行界面下使用下面的命令连接到qemu

View File

@ -1,5 +1,4 @@
##### 2.4.4.4 使用gdb配置文件
##### 使用gdb配置文件
在上面可以看到为了进行源码级调试需要输入较多的东西很麻烦。为了方便可以将这些命令存在脚本中并让gdb在启动的时候自动载入。

View File

@ -1,5 +1,4 @@
##### 2.4.4.5 加载调试目标
##### 加载调试目标
在上面小节我们提到为了能够让gdb识别变量的符号我们必须给gdb载入符号表等信息。在进行gdb本地应用程序调试的时候因为在指定了执行文件时就已经加载了文件中包含的调试信息因此不用再使用gdb命令专门加载了。但是在使用qemu进行远程调试的时候我们必须手动加载符号表也就是在gdb中用file命令。

View File

@ -1,5 +1,4 @@
##### 2.4.4.6 设定调试目标架构
##### 设定调试目标架构
在调试的时候我们也许需要调试不是i386保护模式的代码比如8086实模式的代码我们需要设定当前使用的架构

View File

@ -1,2 +1 @@
#### 2.4.4 结合gdb和qemu源码级调试ucore
#### 结合gdb和qemu源码级调试ucore

View File

@ -1,2 +1 @@
### 2.4 基于硬件模拟器实现源码级调试
### 基于硬件模拟器实现源码级调试

View File

@ -1,5 +1,4 @@
#### 2.5.1 Intel 80386运行模式
#### Intel 80386运行模式
一般CPU只有一种运行模式能够支持多个程序在各自独立的内存空间中并发执行且有用户特权级和内核特权级的区分让一般应用不能破坏操作系统内核和执行特权指令。80386处理器有四种运行模式实模式、保护模式、SMM模式和虚拟8086模式。这里对涉及ucore的实模式、保护模式做一个简要介绍。

View File

@ -1,5 +1,4 @@
#### 2.5.2 Intel 80386内存架构
#### Intel 80386内存架构
地址是访问内存空间的索引。一般而言内存地址有两个一个是CPU通过总线访问物理内存用到的物理地址一个是我们编写的应用程序所用到的逻辑地址也有人称为虚拟地址。比如如下C代码片段
```

View File

@ -1,5 +1,4 @@
#### 2.5.3 Intel 80386寄存器
#### Intel 80386寄存器
这里假定读者对80386 CPU有一定的了解所以只作简单介绍。80386的寄存器可以分为8组通用寄存器段寄存器指令指针寄存器标志寄存器系统地址寄存器控制寄存器调试寄存器测试寄存器它们的宽度都是32位。一般程序员看到的寄存器包括通用寄存器段寄存器指令指针寄存器标志寄存器。

View File

@ -1,4 +1,3 @@
### 2.5 了解处理器硬件
### 了解处理器硬件
要想深入理解ucore就需要了解支撑ucore运行的硬件环境即了解处理器体系结构了解硬件对ucore带来影响和机器指令集读懂ucore的汇编。ucore目前支持的硬件环境是基于Intel 80386以上的计算机系统。更多的硬件相关内容比如保护模式等将随着实现ucore的过程逐渐展开介绍。

View File

@ -1,5 +1,4 @@
#### 2.6.1 面向对象编程方法
#### 面向对象编程方法
uCore设计中采用了一定的面向对象编程方法。虽然C 语言对面向对象编程并没有原生支持,但没有原生支持并不等于我们不能用 C 语言写面向对象程序。需要注意,我们并不需要用 C语言模拟出一个常见 C++ 编译器已经实现的对象模型。如果是这样还不如直接采用C++编程。
@ -29,4 +28,4 @@ uCore的面向对象编程方法目前主要是采用了类似C++的接口(
void (*check)(void);
};
这样基于此数据结构我们可以实现不同连续内存分配算法的物理内存管理子系统而这些物理内存管理子系统需要编写算法把算法实现在此结构中定义的init初始化、init_memmap分析空闲物理内存并初始化管理、alloc_pages分配物理页、free_pages释放物理页函数指针所对应的函数中。而其他内存子系统需要与物理内存管理子系统交互时只需调用特定物理内存管理子系统所采用的pmm_manager数据结构变量中的函数指针即可

View File

@ -1,4 +1,4 @@
##### 2.6.2.1 双向循环链表
##### 双向循环链表
在“数据结构”课程中,如果创建某种数据结构的双循环链表,通常采用的办法是在这个数据结构的类型定义中有专门的成员变量 data, 并且加入两个指向该类型的指针next和prev。例如

View File

@ -1,2 +1 @@
#### 2.6.2 通用数据结构
#### 通用数据结构

View File

@ -1,2 +1 @@
### 2.6 了解ucore编程方法和通用数据结构
### 了解ucore编程方法和通用数据结构

View File

@ -1,3 +1 @@
## 2.准备知识
## 准备知识

View File

@ -1,4 +1,4 @@
## 1.实验目的:
## 实验目的:
操作系统是一个软件,也需要通过某种机制加载并运行它。在这里我们将通过另外一个更加简单的软件-bootloader来完成这些工作。为此我们需要完成一个能够切换到x86的保护模式并显示字符的bootloader为启动操作系统ucore做准备。lab1提供了一个非常小的bootloader和ucore OS整个bootloader执行代码小于512个字节这样才能放到硬盘的主引导扇区中。通过分析和实现这个bootloader和ucore OS读者可以了解到

View File

@ -1,4 +1,3 @@
#### 练习3分析bootloader进入保护模式的过程。要求在报告中写出分析
BIOS将通过读取硬盘主引导扇区到内存并转跳到对应内存中的位置执行bootloader。请分析bootloader是如何完成从实模式进入保护模式的。

View File

@ -1,5 +1,3 @@
#### 练习4分析bootloader加载ELF格式的OS的过程。要求在报告中写出分析
通过阅读bootmain.c了解bootloader如何加载ELF文件。通过分析源代码和通过qemu来运行并调试bootloader&OS

View File

@ -1,4 +1,4 @@
### 2.1 练习
### 练习
为了实现lab1的目标lab1提供了6个基本练习和1个扩展练习要求完成实验报告。
对实验报告的要求:

View File

@ -1,5 +1,4 @@
### 2.2 项目组成
### 项目组成
lab1的整体目录结构如下所示

View File

@ -1,5 +1,3 @@
## 2.实验内容:
## 实验内容:
lab1中包含一个bootloader和一个OS。这个bootloader可以切换到X86保护模式能够读磁盘并加载ELF执行文件格式并显示字符。而这lab1中的OS只是一个可以处理时钟中断和显示字符的幼儿园级别OS。

View File

@ -1,5 +1,4 @@
### 3.1 BIOS启动过程
### BIOS启动过程
当计算机加电后一般不直接执行操作系统而是执行系统初始化软件完成基本IO初始化和引导加载功能。简单地说系统初始化软件就是在操作系统内核运行之前运行的一段小软件。通过这段小软件我们可以初始化硬件设备、建立系统的内存空间映射图从而将系统的软硬件环境带到一个合适的状态以便为最终调用操作系统内核准备好正确的环境。最终引导加载程序把操作系统内核映像加载到RAM中并将系统控制权传递给它。

View File

@ -1,5 +1,4 @@
#### 3.2.1 保护模式和分段机制
#### 保护模式和分段机制
为何要了解Intel 80386的保护模式和分段机制首先我们知道Intel 80386只有在进入保护模式后才能充分发挥其强大的功能提供更好的保护机制和更大的寻址空间否则仅仅是一个快速的8086而已。没有一定的保护机制任何一个应用软件都可以任意访问所有的计算机资源这样也就无从谈起操作系统设计了。且Intel 80386的分段机制一直存在无法屏蔽或避免。其次在我们的bootloader设计中涉及到了从实模式到保护模式的处理我们的操作系统功能比如分页机制是建立在Intel 80386的保护模式上来设计的。如果我们不了解保护模式和分段机制则我们面向Intel 80386体系结构的操作系统设计实际上是建立在一个空中楼阁之上。

View File

@ -1,5 +1,4 @@
#### 3.2.2 地址空间
#### 地址空间
分段机制涉及4个关键内容逻辑地址Logical Address,应用程序员看到的地址在操作系统原理上称为虚拟地址以后提到虚拟地址就是指逻辑地址、物理地址Physical Address, 实际的物理内存地址)、段描述符表(包含多个段描述符的“数组”)、段描述符(描述段的属性,及段描述符表这个“数组”中的“数组元素”)、段选择子(即段寄存器中的值,用于定位段描述符表中段描述符表项的索引)

View File

@ -1,5 +1,4 @@
#### 3.2.3 硬盘访问概述
#### 硬盘访问概述
bootloader让CPU进入保护模式后下一步的工作就是从硬盘上加载并运行OS。考虑到实现的简单性bootloader的访问硬盘都是LBA模式的PIOProgram IO方式即所有的IO操作是通过CPU访问硬盘的IO地址寄存器完成。

View File

@ -1,5 +1,4 @@
#### 3.2.4 ELF文件格式概述
#### ELF文件格式概述
ELF(Executable and linking format)文件格式是Linux系统下的一种常用目标文件(object file)格式,有三种主要类型:

View File

@ -1,5 +1,4 @@
### 3.2 bootloader启动过程
### bootloader启动过程
BIOS将通过读取硬盘主引导扇区到内存并转跳到对应内存中的位置执行bootloader。bootloader完成的工作包括
- 切换到保护模式,启用分段机制

View File

@ -1,5 +1,4 @@
#### 3.3.1 函数堆栈
#### 函数堆栈
栈是一个很重要的编程概念编译课和程序设计课都讲过相关内容与编译器和编程语言有紧密的联系。理解调用栈最重要的两点是栈的结构EBP寄存器的作用。一个函数调用动作可分解为零到多个PUSH指令用于参数入栈一个CALL指令。CALL指令内部其实还暗含了一个将返回地址即CALL指令下一条指令的地址压栈的动作由硬件完成。几乎所有本地编译器都会在每个函数体之前插入类似如下的汇编指令

View File

@ -1,5 +1,4 @@
#### 3.3.2 中断与异常
#### 中断与异常
操作系统需要对计算机系统中的各种外设进行管理这就需要CPU和外设能够相互通信才行。一般外设的速度远慢于CPU的速度。如果让操作系统通过CPU“主动关心”外设的事件即采用通常的轮询(polling)机制则太浪费CPU资源了。所以需要操作系统和CPU能够一起提供某种机制让外设在需要操作系统处理外设相关事件的时候能够“主动通知”操作系统即打断操作系统和应用的正常执行让操作系统完成外设的相关处理然后在恢复操作系统和应用的正常执行。在操作系统中这种机制称为中断机制。中断机制给操作系统提供了处理意外情况的能力同时它也是实现进程/线程抢占式调度的一个重要基石。但中断的引入导致了对操作系统的理解更加困难。

View File

@ -1,5 +1,4 @@
#### 3.3.3 lab1中对中断的处理实现
#### lab1中对中断的处理实现
(1) 外设基本初始化设置

View File

@ -1,5 +1,4 @@
### 3.3 操作系统启动过程
### 操作系统启动过程
当bootloader通过读取硬盘扇区把ucore在系统加载到内存后就转跳到ucore操作系统在内存中的入口位置kern/init.c中的kern_init函数的起始地址这样ucore就接管了整个控制权。当前的ucore功能很简单只完成基本的内存管理和外设中断管理。ucore主要完成的工作包括

View File

@ -1,2 +1 @@
## 3 从机器启动到操作系统运行的过程
## 从机器启动到操作系统运行的过程

View File

@ -1,5 +1,4 @@
## 4 实验报告要求
## 实验报告要求
从git server网站上取得ucore_lab后进入目录labcodes/lab1完成实验要求的各个练习。在实验报告中回答所有练习中提出的问题。在目录labcodes/lab1下存放实验报告实验报告文档命名为lab1-学堂在线ID.md。推荐用**markdown**格式。对于lab1中编程任务完成编写之后再通过git push命令把代码同步回git server网站。最后请一定提前或按时提交到git server网站。

View File

@ -1,4 +1,3 @@
### 练习
对实验报告的要求:

View File

@ -1,4 +1,3 @@
### 项目组成
表1实验三文件列表

View File

@ -1,4 +1,3 @@
## 实验内容
本次实验是在实验二的基础上借助于页表机制和实验一中涉及的中断异常处理机制完成Page

View File

@ -1,4 +1,3 @@
### 基本原理概述
什么是虚拟内存简单地说是指程序员或CPU“看到”的内存。但有几点需要注意

View File

@ -1,4 +1,3 @@
### 实验执行流程概述
本次实验主要完成ucore内核对虚拟内存的管理工作。其总体设计思路还是比较简单即首先完成初始化虚拟内存管理机制即需要设置好哪些页需要放在物理内存中哪些页不需要放在物理内存中而是可被换出到硬盘上并涉及完善建立页表映射、页访问异常处理操作等函数实现。然后就执行一组访存测试看看我们建立的页表项是否能够正确完成虚实地址映射是否正确描述了虚拟内存页在物理内存中还是在硬盘上是否能够正确把虚拟内存页在物理内存和硬盘之间进行传递是否正确实现了页面替换算法等。lab3的总体执行流程如下。

View File

@ -1,5 +1,4 @@
### 3.3 关键数据结构和相关函数分析
### 关键数据结构和相关函数分析
对于第一个问题的出现,在于实验二中有关内存的数据结构和相关操作都是直接针对实际存在的资源--物理内存空间的管理没有从一般应用程序对内存的“需求”考虑即需要有相关的数据结构和操作来体现一般应用程序对虚拟内存的“需求”。一般应用程序的对虚拟内存的“需求”与物理内存空间的“供给”没有直接的对应关系ucore是通过page
fault异常处理来间接完成这二者之间的衔接。

View File

@ -1,2 +1 @@
## 虚拟内存管理

View File

@ -1,4 +1,3 @@
## Page Fault异常处理
实现虚存管理的一个关键是page fault异常处理其过程中主要涉及到函数 -- do\_pgfault的具体实现。比如在程序的执行过程中由于某种原因页框不存在/写只读页等)而使 CPU 无法最终访问到相应的物理内存单元即无法完成从虚拟地址到物理地址映射时CPU 会产生一次页访问异常,从而需要进行相应的页访问异常的中断服务例程。这个页访问异常处理的时机被操作系统充分利用来完成虚存管理,即实现“按需调页”/“页换入换出”处理的执行时机。当相关处理完成后,页访问异常服务例程会返回到产生异常的指令处重新执行,使得应用软件可以继续正常运行下去。

View File

@ -1,4 +1,4 @@
### 5.1 页替换算法
### 页替换算法
操作系统为何要进行页面置换呢?这是由于操作系统给用户态的应用程序提供了一个虚拟的“大容量”内存空间,而实际的物理内存空间又没有那么大。所以操作系统就就“瞒着”应用程序,只把应用程序中“常用”的数据和代码放在物理内存中,而不常用的数据和代码放在了硬盘这样的存储介质上。如果应用程序访问的是“常用”的数据和代码,那么操作系统已经放置在内存中了,不会出现什么问题。但当应用程序访问它认为应该在内存中的的数据或代码时,如果这些数据或代码不在内存中,则根据上一小节的介绍,会产生页访问异常。这时,操作系统必须能够应对这种页访问异常,即尽快把应用程序当前需要的数据或代码放到内存中来,然后重新执行应用程序产生异常的访存指令。如果在把硬盘中对应的数据或代码调入内存前,操作系统发现物理内存已经没有空闲空间了,这时操作系统必须把它认为“不常用”的页换出到磁盘上去,以腾出内存空闲空间给应用程序所需的数据或代码。

View File

@ -1,5 +1,4 @@
### 5.2 页面置换机制
### 页面置换机制
如果要实现页面置换机制,只考虑页替换算法的设计与实现是远远不够的,还需考虑其他问题:

View File

@ -1 +1 @@
## 5. 页面置换机制的实现
## 页面置换机制的实现

View File

@ -1,5 +1,4 @@
## 6. 实验报告要求
## 实验报告要求
从git server网站上取得ucore_lab后进入目录labcodes/lab3完成实验要求的各个练习。在实验报告中回答所有练习中提出的问题。在目录labcodes/lab3下存放实验报告实验报告文档命名为lab3-学生ID.md。推荐用**markdown**格式。对于lab3中编程任务完成编写之后再通过git push命令把代码同步回git server网站。最后请一定提前或按时提交到git server网站。

View File

@ -1,5 +1,4 @@
## 1. 实验目的
## 实验目的
* 了解内核线程创建/执行的管理过程
* 了解内核线程的切换和基本调度过程

View File

@ -1,5 +1,4 @@
### 2.1 练习
### 练习
对实验报告的要求:
- 基于markdown格式来完成以文本方式为主

View File

@ -1,5 +1,4 @@
### 2.2 项目组成
### 项目组成
```
├── boot

View File

@ -1,5 +1,4 @@
## 2. 实验内容
## 实验内容
实验2/3完成了物理和虚拟内存管理这给创建内核线程内核线程是一种特殊的进程打下了提供内存管理的基础。当一个程序加载到内存中运行时首先通过ucore OS的内存管理子系统分配合适的空间然后就需要考虑如何分时使用CPU来“并发”执行多个程序让每个运行的程序这里用线程或进程表示“感到”它们各自拥有“自己”的CPU。

View File

@ -1,5 +1,4 @@
### 3.1 实验执行流程概述
### 实验执行流程概述
lab2和lab3完成了对内存的虚拟化但整个控制流还是一条线串行执行。lab4将在此基础上进行CPU的虚拟化即让ucore实现分时共享CPU实现多条控制流能够并发执行。从某种程度上我们可以把控制流看作是一个内核线程。本次实验将首先接触的是内核线程的管理。内核线程是一种特殊的进程内核线程与用户进程的区别有两个内核线程只运行在内核态而用户进程会在在用户态和内核态交替运行所有内核线程直接使用共同的ucore内核内存空间不需为每个内核线程维护单独的内存空间而用户进程需要维护各自的用户内存空间。从内存空间占用情况这个角度上看我们可以把线程看作是一种共享内存空间的轻量级进程。

View File

@ -1,5 +1,4 @@
### 3.2 设计关键数据结构 -- 进程控制块
### 设计关键数据结构 -- 进程控制块
在实验四中进程管理信息用struct
proc\_struct表示在*kern/process/proc.h*中定义如下:

View File

@ -1,4 +1,4 @@
#### 1. 创建第 0 个内核线程 idleproc
#### 创建第 0 个内核线程 idleproc
在init.c::kern\_init函数调用了proc.c::proc\_init函数。proc\_init函数启动了创建内核线程的步骤。首先当前的执行上下文从kern\_init 启动至今就可以看成是uCore内核也可看做是内核进程中的一个内核线程的上下文。为此uCore通过给当前执行的上下文分配一个进程控制块以及对它进行相应初始化将其打造成第0个内核线程 -- idleproc。具体步骤如下

View File

@ -1,4 +1,4 @@
#### 2. 创建第 1 个内核线程 initproc
#### 创建第 1 个内核线程 initproc
第0个内核线程主要工作是完成内核中各个子系统的初始化然后就通过执行cpu\_idle函数开始过退休生活了。所以uCore接下来还需创建其他进程来完成各种工作但idleproc内核子线程自己不想做于是就通过调用kernel\_thread函数创建了一个内核线程init\_main。在实验四中这个子内核线程的工作就是输出一些字符串然后就返回了参看init\_main函数。但在后续的实验中init\_main的工作就是创建特定的其他内核线程或用户进程实验五涉及。下面我们来分析一下创建内核线程的函数kernel\_thread

View File

@ -1,4 +1,4 @@
#### 3. 调度并执行内核线程 initproc
#### 调度并执行内核线程 initproc
在uCore执行完proc\_init函数后就创建好了两个内核线程idleproc和initproc这时uCore当前的执行现场就是idleproc等到执行到init函数的最后一个函数cpu\_idle之前uCore的所有初始化工作就结束了idleproc将通过执行cpu\_idle函数让出CPU给其它内核线程执行具体过程如下

View File

@ -1,5 +1,4 @@
### 3.3 创建并执行内核线程
### 创建并执行内核线程
建立进程控制块proc.c中的alloc\_proc函数现在就可以通过进程控制块来创建具体的进程/线程了。首先考虑最简单的内核线程它通常只是内核中的一小段代码或者函数没有自己的“专属”空间。这是由于在uCore OS启动后已经对整个内核内存空间进行了管理通过设置页表建立了内核虚拟空间即boot\_cr3指向的二级页表描述的空间。所以uCore OS内核中的所有线程都不需要再建立各自的页表只需共享这个内核虚拟空间就可以访问整个物理内存了。从这个角度看内核线程被uCore OS内核这个大“内核进程”所管理。

View File

@ -1,2 +1 @@
## 3. 内核线程管理
## 内核线程管理

View File

@ -1,5 +1,4 @@
## 4. 实验报告要求
## 实验报告要求
从git server网站上取得ucore_lab后进入目录labcodes/lab4完成实验要求的各个练习。在实验报告中回答所有练习中提出的问题。在目录labcodes/lab4下存放实验报告实验报告文档命名为lab4-学生ID.md。推荐用**markdown**格式。对于lab4中编程任务完成编写之后再通过git push命令把代码同步回git server网站。最后请一定提前或按时提交到git server网站。

View File

@ -1,4 +1,3 @@
## 附录A实验四的参考输出如下
```

View File

@ -1,5 +1,3 @@
## 附录B【原理】进程的属性与特征解析
操作系统负责进程管理即从程序加载到运行结束的全过程这个程序运行过程将经历从“出生”到“死亡”的完整“生命”历程。所谓“进程”就是指这个程序运行的整个执行过程。为了记录、描述和管理程序执行的动态变化过程需要有一个数据结构这就是进程控制块。进程与进程控制块是一一对应的。为此ucore需要建立合适的进程控制块数据结构并基于进程控制块来完成对进程的管理。

View File

@ -1,5 +1,4 @@
## 1. 实验目的
## 实验目的
* 了解第一个用户进程创建过程
* 了解系统调用框架的实现机制

View File

@ -1,5 +1,4 @@
### 2.1 练习
### 练习
对实验报告的要求:
- 基于markdown格式来完成以文本方式为主

View File

@ -1,5 +1,4 @@
### 2.2 项目组成
### 项目组成
```
├── boot

View File

@ -1,4 +1,3 @@
## 2. 实验内容
## 实验内容
实验4完成了内核线程但到目前为止所有的运行都在内核态执行。实验5将创建用户进程让用户进程在用户态执行且在需要ucore支持时可通过系统调用来让ucore提供服务。为此需要构造出第一个用户进程并通过系统调用sys\_fork/sys\_exec/sys\_exit/sys\_wait来支持运行不同的应用程序完成对用户进程的执行过程的基本管理。相关原理介绍可看附录B。

View File

@ -1,5 +1,4 @@
### 3.1 实验执行流程概述
### 实验执行流程概述
到实验四为止ucore还一直在核心态“打转”没有到用户态执行。提供各种操作系统功能的内核线程只能在CPU核心态运行是操作系统自身的要求操作系统就要呆在核心态才能管理整个计算机系统。但应用程序员也需要编写各种应用软件且要在计算机系统上运行。如果把这些应用软件都作为内核线程来执行那系统的安全性就无法得到保证了。所以ucore要提供用户态进程的创建和执行机制给应用程序执行提供一个用户态运行环境。接下来我们就简要分析本实验的执行过程以及分析用户进程的整个生命周期来阐述用户进程管理的设计与实现。

View File

@ -1,5 +1,4 @@
### 3.2 创建用户进程
### 创建用户进程
在实验四中,我们已经完成了对内核线程的创建,但与用户进程的创建过程相比,创建内核线程的过程还远远不够。而这两个创建过程的差异本质上就是用户进程和内核线程的差异决定的。

View File

@ -1,5 +1,4 @@
### 3.3 进程退出和等待进程
### 进程退出和等待进程
当进程执行完它的工作后就需要执行退出操作释放进程占用的资源。ucore分了两步来完成这个工作首先由进程本身完成大部分资源的占用内存回收工作然后由此进程的父进程完成剩余资源占用内存的回收工作。为何不让进程本身完成所有的资源回收工作呢这是因为进程要执行回收操作就表明此进程还存在还在执行指令这就需要内核栈的空间不能释放且表示进程存在的进程控制块不能释放。所以需要父进程来帮忙释放子进程无法完成的这两个资源回收工作。

View File

@ -1,5 +1,4 @@
### 3.4 系统调用实现
### 系统调用实现
系统调用的英文名字是System
Call。操作系统为什么需要实现系统调用呢其实这是实现了用户进程后自然引申出来需要实现的操作系统功能。用户进程只能在操作系统给它圈定好的“用户环境”中执行但“用户环境”限制了用户进程能够执行的指令即用户进程只能执行一般的指令无法执行特权指令。如果用户进程想执行一些需要特权指令的任务比如通过网卡发网络包等只能让操作系统来代劳了。于是就需要一种机制来确保用户进程不能执行特权指令但能够请操作系统“帮忙”完成需要特权指令的任务这种机制就是系统调用。

View File

@ -1,2 +1 @@
## 3 用户进程管理
## 用户进程管理

View File

@ -1,5 +1,4 @@
## 4. 实验报告要求
## 实验报告要求
从git server网站上取得ucore_lab后进入目录labcodes/lab5完成实验要求的各个练习。在实验报告中回答所有练习中提出的问题。在目录labcodes/lab5下存放实验报告实验报告文档命名为lab5-学生ID.md。推荐用**markdown**格式。对于lab5中编程任务完成编写之后再通过git push命令把代码同步回git server网站。最后请一定提前或按时提交到git server网站。

View File

@ -1,4 +1,3 @@
## 附录 A【原理】用户进程的特征
### 从内核线程到用户进程

View File

@ -1,5 +1,4 @@
## 1 实验目的
## 实验目的
* 理解操作系统的调度管理机制
* 熟悉 ucore 的系统调度器框架以及缺省的Round-Robin 调度算法

View File

@ -1,5 +1,4 @@
### 2.1 练习
### 练习
对实验报告的要求:
- 基于markdown格式来完成以文本方式为主

Some files were not shown because too many files have changed in this diff Show More