Skip to content

Commit

Permalink
wip: update lab 2
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Jan 27, 2024
1 parent 1e97b8c commit ba49681
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions docs/labs/0x02/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

!!! note "请阅读 [x64 数据结构概述](../../wiki/structures.md) 部分,了解 x64 架构中的 GDT、TSS 和 IDT。"

在我们的操作系统中,GDT、TSS 和 IDT 均属于全局静态的数据结构,因此我们将它们定义为 `static` 类型,并使用 `lazy_static` 宏来实现懒加载,其本质上也是通过 `Once` 来保护全局对象,但是它的初始化函数无需参数传递,因此可以直接声明,无需手动调用 `call_once` 函数来传递不同的初始化参数。
在本实验的操作系统中,GDT、TSS 和 IDT 均属于全局静态的数据结构,因此需要将它们定义为 `static` 类型,并使用 `lazy_static` 宏来实现懒加载,其本质上也是通过 `Once` 来保护全局对象,但是它的初始化函数无需参数传递,因此可以直接声明,无需手动调用 `call_once` 函数来传递不同的初始化参数。

```rust
lazy_static! {
Expand Down Expand Up @@ -86,9 +86,9 @@ lazy_static! {

`exceptions.rs` 中描述了 CPU 异常的处理,这些异常由 CPU 在内部生成,用于提醒正在运行的内核需要其注意的事件或情况。`x86_64``InterruptDescriptorTable` 中为这些异常处理函数提供了定义,如 `divide_error``double_fault` 等。

对于中断请求(IRQ)和硬件中断,我们将在独立的文件中进行处理`clock.rs` 中描述了时钟中断的处理,`serial.rs` 中描述了串口输入中断的处理。
对于中断请求(IRQ)和硬件中断,将在独立的文件中进行处理`clock.rs` 中描述了时钟中断的处理,`serial.rs` 中描述了串口输入中断的处理。

对于软件中断,如在 `x86` 架构中的系统调用 `int 0x80`我们将在 `syscall.rs` 中进行处理。从而统一地对中断进行代码组织。这部分内容将在后续实验中进行实现。
对于软件中断,如在 `x86` 架构中的系统调用 `int 0x80`将在 `syscall.rs` 中进行处理。从而统一地对中断进行代码组织。这部分内容将在后续实验中进行实现。

之后按照项目规范,为 `interrupt` 模块添加 `pub fn init()` 函数,将中断系统的初始化工作统一起来:

Expand Down Expand Up @@ -215,7 +215,7 @@ impl XApic {
</tr>
</table>

因此,我们需要在保持其他位不变的情况下,将 EN bit 设置为 1,并将 Vector 设置为 `Irq::Spurious`,但是请注意实际设置的中断向量号需要加上 `Interrupts::IrqBase`。同时,此寄存器的 0-3 bit 无法被修改,始终为 1
因此,需要在保持其他位不变的情况下,将 EN bit 设置为 1,并将 Vector 设置为 `Irq::Spurious`,但是请注意实际设置的中断向量号需要加上 `Interrupts::IrqBase`。同时,此寄存器的 0-3 bit 无法被修改,始终为 1

最终代码如下:

Expand Down Expand Up @@ -356,7 +356,7 @@ impl XApic {

- 清除错误状态寄存器。

APIC 中的错误状态寄存器(Error Status Register, 0x280)用于记录 APIC 内部的错误状态。当 APIC 发生错误时,CPU 会将错误信息写入此寄存器。为了避免错误状态寄存器中的错误信息影响后续的错误处理,我们需要在初始化 APIC 时清除错误状态寄存器中的错误信息。
APIC 中的错误状态寄存器(Error Status Register, 0x280)用于记录 APIC 内部的错误状态。当 APIC 发生错误时,CPU 会将错误信息写入此寄存器。为了避免错误状态寄存器中的错误信息影响后续的错误处理,需要在初始化 APIC 时清除错误状态寄存器中的错误信息。

参考代码如下:

Expand Down Expand Up @@ -444,7 +444,9 @@ impl XApic {

## 时钟中断

在顺利配置好 XAPIC 并初始化后,APIC 的中断就被成功启用了。为了响应时钟中断,我们需要为 IRQ0 Timer 设置中断处理程序。创建 `src/interrupt/clock.rs` 文件,参考如下代码,为 Timer 设置中断处理程序:
在顺利配置好 XAPIC 并初始化后,APIC 的中断就被成功启用了。为了响应时钟中断,需要为 IRQ0 Timer 设置中断处理程序。

创建 `src/interrupt/clock.rs` 文件,参考如下代码,为 Timer 设置中断处理程序:

```rust
use super::consts::*;
Expand Down Expand Up @@ -492,7 +494,7 @@ x86_64::instructions::interrupts::enable();

## 串口输入中断

遵循 I/O 中断处理的 Top half & Bottom half 原则,在中断发生时,我们只在中断处理中做尽量少的事:读取串口的输入,并将其放入缓冲区。而在中断处理程序之外,我们可以在合适的时机,从缓冲区中读取数据,并进行处理。
遵循 I/O 中断处理的 Top half & Bottom half 原则,在中断发生时,仅仅在中断处理中做尽量少的事:读取串口的输入,并将其放入缓冲区。而在中断处理程序之外,选择合适的时机,从缓冲区中读取数据,并进行处理。

为了开启串口设备的中断,你需要参考如下代码,在 `src/drivers/uart16550.rs``init` 函数末尾为串口设备开启中断:

Expand All @@ -511,7 +513,7 @@ static int init_serial() {

为了承接全部(可能的)用户输入数据,并将它们统一在标准输入,需要为输入准备缓冲区,并将其封装为一个驱动,创建 `src/drivers/input.rs` 文件,并借助 `crossbeam_queue` crate 实现一个输入缓冲区。

!!! tip "在 memory 初始化的过程中,我们已经有了内核堆分配的能力,可以动态分配内存。"
!!! tip "在 memory 初始化的过程中,你已经有了内核堆分配的能力,可以动态分配内存。"

按照下列描述,补全 `src/drivers/input.rs` 驱动代码:

Expand Down Expand Up @@ -628,6 +630,8 @@ pub fn kernel_main(boot_info: &'static boot::BootInfo) -> ! {

5. 如果在 TSS 中为中断分配的栈空间不足,会发生什么情况?请分析 CPU 异常的发生过程,并尝试回答什么时候会发生 Triple Fault。

6. 在未使用 `set_stack_index` 函数时,中断处理程序的栈可能哪里?尝试结合 gdb 调试器,找到中断处理程序的栈,并验证你的猜想是否正确。

## 加分项

1. 😋 为**全部可能的 CPU 异常**设置对应的处理程序,使用 `panic!` 输出异常信息。
Expand Down

0 comments on commit ba49681

Please sign in to comment.