Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第一二三阶段卓堂越 #677

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
title:2024 秋冬季开源操作系统训练营第四阶段总结-卓堂越
date: 2024-12-22 12:48:00
categories:
- report
tags:
- author: nusakom
- repo: https://github.com/nusakom/OPENcv.git
---
## 从小白到操作系统开发者:我的训练营历程与成长

参加训练营已经快一年了,回顾这段时间的学习与实践,感觉收获满满,成长也非常明显。虽然过程中经历了不少挑战,但我从中学到了很多,也更加明白了自己未来的目标和方向。

### 从初识RTOS和操作系统

在训练营的第一阶段,我还是一个对RTOS(实时操作系统)了解甚少的“小白”。当时,我的理解仅限于知道 **FreeRTOS** 是什么,而对于操作系统的具体结构和工作原理几乎没有任何概念。然而,通过这段时间的学习,我开始接触并逐步理解操作系统的基本组成部分,像是内核、调度、进程管理等。这个阶段的学习让我明白了操作系统不仅仅是运行应用程序的基础,更是硬件和软件之间的重要桥梁。

#### 网络问题与任务挑战

不过,学习的过程并不是一帆风顺的。由于网络不稳定,很多简单的任务总是上传不了,这让我有时感到非常沮丧。更有一次,我因为任务时间限制和一些技术难题,没能在结课期间按时完成所有的任务。这些问题让我认识到,技术的实现不仅仅依赖于个人的能力,还需要更好的时间管理和稳定的技术环境支持。

### 深入探索异步编程与Python适配

进入训练营的第二阶段后,任务的难度逐步增加。我选择了一个相对较简单的方向,与其他小伙伴们一起研究 **异步编程**。虽然这与我之前的经验较为接近,但在实际实现过程中,我还是遇到了不少挑战,尤其是在理解异步编程模型时。

然而,通过逐步的实现,我不仅加深了对异步编程的理解,还接触了Python适配的相关知识。实际上,这个阶段让我学到了很多之前没有涉及的技术,这些新知识极大地丰富了我的技术栈,也让我对未来的技术方向更加清晰。

### Python与OpenCV的结合

尽管我没有完全按预期完成所有任务,但这个阶段让我深入思考了自己的学习方法。我曾经盲目追求高难度的任务,而忽略了任务的实际意义和自己的能力匹配。因此,在这个阶段,我主动选择了一个相对简单的任务——**OpenCV** 的相关实践。尽管我最终未能在 **Starry** 上完成OpenCV的测例,但这个过程让我更加明白了如何进行项目规划和任务分配。

在这阶段,我还负责了Python与OpenCV的结合,进行了一些与图像处理相关的实验和项目。通过这些实践,我深入了解了Python的图像处理能力,尤其是OpenCV库在计算机视觉中的应用。例如,如何使用OpenCV进行图像读取、处理和展示,这些操作帮助我了解了计算机如何通过视觉来感知和分析信息。

#### 实现Python3.11的syscall系统调用

作为实习任务的一部分,我参与了分析和实现支持 **Python3.11** 程序的 **syscall** 系统调用,尤其是在 **ArceOS/Starry** 系统中,逐步完善Python程序所依赖的系统调用。具体来说,这个过程涉及了用户态程序的交叉编译、依赖库的交叉编译、以及系统模拟器 **Qemu** 中的实验。

1. **交叉编译Python程序**:首先,我需要交叉编译 **Python3.11**,以支持 **aarch64** 架构。这包括了编译所需的依赖库(如 **libffi**、**zlib**、**libuuid** 和 **xz** 等),并且每个依赖库都必须交叉编译,以保证在目标架构上能够正常运行。

2. **Qemu模拟环境**:为了测试在交叉编译后的Python程序,我在 **Qemu** 模拟环境中运行了一个 **aarch64** 架构的 **Alpine Linux**,并在其中加载了交叉编译生成的Python库。通过这种方式,我能够测试并调试系统调用,确保它们能够在模拟器中正常执行。

3. **系统调用分析**:我使用 **strace** 工具来统计Python程序所使用的所有系统调用,并分析它们在不同架构下的表现。通过这个过程,我深入了解了 **syscall** 的工作机制,并能够在实际操作系统中正确实现这些调用。

通过这个任务,我不仅加深了对操作系统内核和系统调用机制的理解,还在实践中学会了如何处理复杂的交叉编译任务。

### 未来的目标--操作系统与编译器

回顾这一年的学习,我不仅了解了操作系统的基本原理,还在逐步实现的过程中积累了不少经验。尤其是从一个仅仅知道FreeRTOS的小白,到如今能够理解操作系统结构的程度,我感到自己有了明显的进步。

最令我兴奋的是,未来我希望能够在自己写的操作系统上运行自己开发的编译器。这是我一直以来的梦想,虽然这需要我不断努力和学习,但我相信,通过这段时间的积累,我已经打下了坚实的基础。

### 总结

参加训练营的这一年里,我收获了很多,不仅有热心的助教和同学的帮助,还有机会接触到多种新技术和工具。虽然遇到了一些困难,但这些都成为了我成长的动力。我相信,未来我会继续沿着这个方向前行,实现自己在操作系统和编译器领域的梦想。

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title:2024 秋冬季开源操作系统训练营第一二三阶段总结-卓堂越
date: 2024-12-05 21:07:52
categories:
- report
tags:
- author: nusakom
- repo: https://github.com/LearningOS/2024a-rcore-nusakom
---
## 第一阶段实验总结

在本次实验中,我深入探讨了Rust编程语言中的多个高级概念,并通过实际操作加深了对这些特性的理解。实验的重点涉及了Rust的内存管理、类型系统、并发编程等方面,帮助我更好地掌握了Rust的独特设计思想。

首先,我学习了**Option类型**,通过实践我了解了如何使用`Some`和`None`来表示可能不存在的值。这个特性不仅帮助我更好地处理空值,还为后续的错误处理打下了基础。接下来,我研究了Rust中的**结构体**和**枚举**,这两者是Rust数据建模的核心工具。通过定义常规结构体、元组结构体和单元结构体,我体会到了Rust在数据表示上的灵活性。尤其是在枚举的使用中,我学会了如何通过模式匹配来处理不同类型的值,这让代码更加简洁且易于维护。

在处理**字符串**时,我深入了解了Rust中`String`与`str`类型的差异,以及它们在内存管理中的不同表现。我通过字符串切片、拼接等操作,进一步掌握了Rust如何高效地处理内存。对于Rust的**模块系统**,我学习了如何通过`pub`关键字控制模块的可见性,并使用`use`语句引入外部模块,逐步掌握了Rust的模块化管理和命名空间管理技巧。

通过操作**HashMap**,我加深了对哈希表这种数据结构的理解。尤其是在函数间传递哈希表时,我学习了如何处理生命周期问题,确保数据在访问时的安全性。在**错误处理**方面,我通过`Option`和`Result`类型的应用,掌握了Rust中优雅的错误处理机制,学习了如何通过模式匹配有效地捕捉和处理错误。

在学习**泛型**和**性状**时,我认识到泛型使得Rust的代码更加灵活和可复用,而性状则赋予了类型更多的行为定义能力。通过实现和使用性状,我体会到了Rust的面向对象编程思想与函数式编程思想的结合。**生命周期**的学习使我更清晰地理解了Rust的内存管理机制,特别是在避免悬空引用和内存泄漏方面,通过生命周期注解,我能够精确控制数据的有效期,确保内存的安全使用。

通过对**迭代器**和**智能指针**(如`Rc`、`Arc`、`Box`)的学习,我掌握了Rust如何高效地处理集合数据和内存管理,尤其是智能指针帮助我理解了如何管理共享内存和避免内存泄漏的问题。最后,**宏**的学习让我认识到宏在Rust中的重要性,它不仅简化了代码,还提高了代码的复用性和灵活性。**多线程编程**部分则让我进一步理解了Rust的线程模型,学会了如何在保证数据安全的前提下,进行并发操作。

总结来说,通过本次实验,我不仅强化了对Rust基础概念的理解,还深入学习了Rust在内存管理、类型系统以及并发编程方面的独特设计。通过实验中的实际操作,我能够更熟练地使用Rust编写健壮、高效的代码,进一步提升了我的编程能力。

## 第二阶段实验总结

### 引言

在操作系统的开发过程中,系统调用是操作系统与用户程序之间的接口,负责提供底层的服务与功能。在本次操作系统实验中,我们实现了几个核心系统调用,包括任务信息查询、内存映射、进程创建等功能。通过实现这些系统调用,我们可以深入理解操作系统的基本原理,如进程管理、内存管理和调度机制。此外,我们还探讨了如何利用不同的调度算法优化任务调度,尤其是通过实现 Stride 调度算法来确保系统中各个进程能够公平地获得 CPU 时间。本文将详细介绍这些系统调用的设计与实现思路。

### 任务信息查询:`sys_task_info`

`sys_task_info` 系统调用的主要目的是提供关于当前正在运行的任务的详细信息。每当操作系统需要调试或监控任务时,可以通过调用这个系统调用来获取相关的任务状态、系统调用次数和任务运行时间等信息。操作系统维护每个进程的相关数据,包括进程的状态、系统调用的计数和执行时间等,而这些信息对于开发人员调试系统、分析性能至关重要。

为了实现 `sys_task_info`,我们首先需要获取当前进程的相关信息。这通常通过存储在进程控制块(PCB)中的数据实现,PCB 记录了每个进程的状态、CPU 寄存器的值、已执行时间以及系统调用计数等信息。当用户或系统调用 `sys_task_info` 时,操作系统会返回当前任务的这些信息,包括任务的运行状态(如就绪、运行、等待等),系统调用的数量,以及进程自启动以来已经占用的 CPU 时间。通过这些信息,开发人员可以判断进程的执行状态,分析是否存在性能瓶颈或资源争用等问题。

### 内存映射与取消映射:`sys_mmap` 和 `sys_munmap`

在现代操作系统中,虚拟内存是每个进程独立的内存空间,而物理内存则是实际存在的硬件资源。为了有效地利用物理内存,操作系统采用虚拟内存与物理内存之间的映射机制。`sys_mmap` 系统调用的功能是将虚拟地址空间映射到物理内存上。通过 `mmap`,操作系统可以将某个文件的内容映射到进程的虚拟内存中,从而让程序可以像访问内存一样直接访问文件数据,而不需要每次都通过传统的 I/O 操作。

在实现 `sys_mmap` 时,操作系统首先检查请求的虚拟地址是否有效,并验证内存区域是否已经被映射。如果没有冲突,操作系统将通过页表将虚拟地址映射到物理地址。这需要操作系统处理页表的更新,并确保映射区域的权限设置正确。例如,映射的内存区域可能是可读、可写或可执行,操作系统需要为每个映射区域设置合适的访问权限,以避免非法访问或数据损坏。

与 `sys_mmap` 相对的 `sys_munmap` 系统调用则负责取消已经映射的虚拟内存区域。当进程不再需要某段内存时,可以调用 `munmap` 来解除映射。操作系统需要确保取消映射时,虚拟地址没有其他进程在使用,同时也需要回收该内存区域所占用的物理资源。为了实现这一点,操作系统会更新页表,释放相关的物理内存,并将其标记为可重用。通过这种方式,操作系统能够有效管理内存资源,避免内存泄漏和浪费。

### 进程创建:`sys_spawn`

进程创建是操作系统中非常重要的一部分功能。通过 `sys_spawn` 系统调用,操作系统可以根据用户给定的程序路径创建一个新的进程,并将该进程添加到调度队列中。进程创建的过程涉及多个步骤,包括路径验证、程序加载、内存分配和任务调度等。

在实现 `sys_spawn` 时,操作系统首先需要验证用户提供的程序路径是否有效。这意味着操作系统必须能够访问到指定的文件,并确认该文件是一个有效的可执行文件。接着,操作系统会为新进程分配一个进程控制块(PCB),用于保存该进程的状态、寄存器信息、内存映射、文件描述符等关键数据。然后,操作系统将程序的内容加载到新进程的虚拟内存中,并为其分配栈、堆等内存区域。

一旦新进程的资源分配完成,操作系统会将其添加到调度队列中,等待 CPU 的调度。此时,进程已经具备了执行的基本条件,可以在操作系统的控制下执行。在实际的操作系统中,进程的创建还会涉及到权限管理、父子进程关系的维护以及资源继承等问题,这些都是确保系统稳定和安全运行的关键部分。

### Stride 调度算法

进程调度是操作系统中的一个核心任务,关系到系统性能和资源利用率。Stride 调度算法是一种基于权重的调度策略,旨在通过分配不同的权重来实现不同进程之间的公平调度。在 Stride 调度中,每个进程被分配一个 `stride` 值,该值与进程的优先级相关,优先级较高的进程将获得较小的 `stride` 值,而优先级较低的进程将获得较大的 `stride` 值。每个进程在执行时消耗一定的 `stride`,当它的 `stride` 值达到一定阈值时,该进程就会被调度执行。

Stride 调度算法的优点在于,它能够在多任务环境下有效地保证进程之间的公平性。每个进程的调度机会与其 `stride` 值成反比,这意味着优先级较高的任务会被调度得更频繁,而优先级较低的任务则会较少获得 CPU 时间。每当一个进程被调度执行后,操作系统会更新该进程的 `stride` 值,使得其调度机会逐渐减少,从而避免了高优先级进程过度占用 CPU 资源的问题。

通过实现 Stride 调度算法,操作系统能够根据每个进程的优先级动态地调整其调度频率。高优先级的任务能够更快速地完成,而低优先级的任务则能够平衡获得一定的执行时间,避免了优先级反转和过度竞争 CPU 的情况。这种方法提高了系统资源的使用效率,同时也保持了调度的公平性。

### 结语

本次操作系统实验通过实现多个核心功能,深入探讨了系统调用的原理与实现方法。通过任务信息查询、内存映射与取消映射、进程创建等功能的实现,我们不仅加深了对操作系统基本原理的理解,也锻炼了我们如何设计和实现高效的内核功能。同时,Stride 调度算法的实现则帮助我们理解了操作系统如何管理进程的调度和资源分配,以保证公平性和系统性能。

这些操作系统的核心机制为我们未来开发更复杂、更高效的操作系统打下了坚实的基础。在实际的操作系统开发过程中,继续优化调度算法、内存管理、进程调度等底层功能,是提高操作系统性能、稳定性和可扩展性的关键。通过这次实验,我们不仅掌握了这些技术的实现方法,还为我们在更大规模的操作系统设计中奠定了理论基础。

---

### 2024 秋冬季开源操作系统训练营第三阶段总结 - 卓堂越

通过第三阶段的学习,我深入理解了组件化操作系统内核的设计理念。这种思想强调以模块化方式构建内核,能够根据实际需求增量式地扩展功能,从而在不同场景下灵活构建各种模式的内核。具体而言,这种方法能够带来以下显著优势:

1. **提高开发效率**:模块化设计减少了重复工作,使开发者可以快速实现复杂功能。
2. **降低维护难度**:各模块间解耦降低了修改与调试的成本。
3. **促进功能复用与协作**:组件化方法支持功能模块的复用与团队协作开发。

#### 学习成果回顾

**第一周**
学习了 **Unikernel** 的增量开发方法。从一个简单的内核开始,逐步扩展了文件系统等模块。同时,完成了基础设施建设,包括实现 `HashMap` 和简单的内存分配算法,并掌握了终端控制的技巧。

**第二周**
通过组件化设计,将 Unikernel 扩展为 **Monolithic Kernel**。深入学习了 RISC-V 架构,以及 Arceos 中的线程控制设计。除此之外,我还完成了缺页异常处理,并实现了基本的 Unix 工具功能。

**第三周**
了解了虚拟化的基本原理,并基于模块化方法为 Arceos 添加了虚拟化支持。具体包括虚拟设备接口和多虚拟机支持,同时优化了系统性能与架构设计。

#### 收获与展望

本阶段的学习让我切身感受到组件化设计在操作系统开发中的强大优势。通过将复杂问题拆解为模块,开发变得更加高效,系统也更易于维护。未来,我希望能将这一思想应用于更多实际项目中,持续提升内核开发能力,打造高效且可靠的系统。

---