Forfun OS - 用户程序开发

1 前言 Forfun-OS 简介 前几章我们介绍了内核实现,但由于是微内核,很多功能需要在用户层实现。本章将介绍如何开发 Forfun OS 用户程序,以及文件系统和 Shell 的实现。 2 用户程序 简单起见,用户程序也使用 rust 开发。用户程序运行在 Forfun OS 上,而不是 linux 上,因此也需要使用 no_std 模式编程。 在 user/src 路径下,我们可以看到如下文件,相当于一个基础的 Forfun OS 标准库和编译环境。 lib.rs rust lib 库的主文件,定义了 entry 函数,初始化了堆 console.rs: 实现了 rust println! 宏,方便开发 lang_items.rs: 由于使用 no_std 模式开发,需要实现一些必要的接口,如 panic linker.ld: 链接脚本,定义 entry 地址 syscall.rs: 定义了所有系统调用函数 signal.rs: 定义了 signal 类别,用处不大,后面可删掉 在这个环境中进行应用程序开发,rust 语言的特性基本都可以使用,只是在使用 syscall 的时候需要了解下 syscall 用法。 应用程序暂且都放在 user/src/bin 文件夹下,后面也可以成独立项目,将编译环境作为 lib 引入 3 用户程序示例 下面是一个最简单的示例,可以看出,和 std 模式下开发差不多,只是需要加一些定义...

July 20, 2024 · 2 min · 280 words · Croak

Forfun OS - 进程管理和 IPC

1 前言 Forfun-OS 简介 本章主要介绍 Forfun OS 的进程管理和 IPC 功能。目前简单考虑,没有设计线程功能,所以每一个进程就是一个任务,后期再考虑增加线程功能。 对于微内核来说,IPC 是非常重要的功能,因为微内核不提供文件系统,也不提供驱动,这些基础组件都是一个独立的用户进程。因此内核需要提供方便好用的 IPC 功能,帮助进程间通信。 2 进程管理 Forfun OS 的进程管理采用经典的 UNIX 式方式,通过 Fork,Exec,Wait 三个函数实现父进程对子进程的创建到回收。内核在启动时,会启动初始进程,再由初始进程启动子进程。子进程完全由父进程进行管理。 一个进程只存在一个任务,因此进程管理和任务控制块放在一个对象里即可,在 Forfun OS 中叫做 Process,内容如下 pub struct Process { pub tick: usize, // 运行时间片 pub status: ProcessStatus, // 任务状态, ready,running,sleep,exited pub pid: PidHandler, pub parent: Option<usize>, // 父进程 pub children: BTreeMap<usize, Arc<Mutex<Self>>>, // 子进程 ctx: SwitchContext, // 任务上下文 mm: MemoryManager, // 内存集 asid: AisdHandler, // 内存空间 id fds: Vec<Option<Arc<dyn File>>>, // 文件描述符 signals: SignalFlags, // 信号,用于 ipc signals_mask: SignalFlags, // 信号掩码 signal_actions: Vec<Option<SignalAction>>, // 信号量 handler trap_ctx_backup: Option<TrapContext>, // trap 上下文备份 } 主要通过以下三个函数管理进程从创建到回收...

July 19, 2024 · 3 min · 550 words · Croak

Forfun OS - 内存管理

1 前言 Forfun-OS 简介 本章主要介绍 Forfun OS 的内存管理功能。该功能主要设计以下方面 页表管理 内存区域管理 内存集管理 物理页帧管理 虚拟页面管理 elf 文件解析和加载 请注意,目前不包括对内核堆的管理,内核在启动使用时,预先分配一块固定大小内存,用于堆管理,而不是动态分配内存。 2 概念介绍 2.1 虚拟内存 在本章之前,我们一直使用的都是实地址模式。实地址模式简单,但存在两个问题, 操作系统需要预先分配一块内存区域,这个区域大小很难决定 每个应用程序需要预先知道自己被放置在哪块区域,并在链接脚本中说明起始地址 因此,前人发明了虚拟内存机制。简单来说,就是每个应用程序独享一块虚拟内存空间,让其产生独占内存空间的错觉(和让其觉得独占 CPU 一样)。同时通过页表机制,建立虚拟内存和物理内存之间的联系。关于虚拟内存的详细介绍可参考 虚拟内存 2.2 页表 页表用于 虚拟内存 -> 物理内存 的转换过程,CPU 在执行指令时,会根据页表查询到对应的物理内存地址。关于页表的详细说明可参考 rCore 文档介绍 页表介绍 每个进程都有独立的地址空间,即一套页表,所以在切换进程时,也需要切换页表。下面就是页表切换函数,它会在 __switch 函数之前执行。 // 页表切换函数 // os/src/process/app.rs pub fn activate(&mut self) { let satp: usize = self.satp(); unsafe { satp::write(satp); asm!("sfence.vma"); // 刷新块表,确保切换成功 } } 这就是为什么进程切换比线程切换的代价更大,因为进程切换需要切换页表,而线程切换则不用 2.3 内存区域和内存集 我们将一段在虚拟内存上连续的区域叫做内存区域,而这些内存区域的集合就叫做内存集。一个进程拥有一个内存集,代码中如下 pub struct Process { ....

July 18, 2024 · 2 min · 386 words · Croak

Forfun OS - 系统调用及任务调度

1 前言 Forfun-OS 简介 本章主要介绍 Forfun OS 的系统调用和任务调度功能的设计和实现细节 系统调用:指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务 任务调度:操作系统为每个任务分配时间片,轮流执行任务,让每个用户进程认为自己独占了 CPU 这两章实现参考 rCore-OS,可以参考 rCore 中的以下两章 批处理系统 多道程序与分时多任务 2 系统调用 系统调用流程如下图 kernelkernelappappTrap 软中断Trap...保存用户上下文保存用户上下文syscall 处理函数syscall 处理函数寄存器填结果 恢复用户上下文寄存器填结果 恢复用户上下文返回用户空间返回用户空间Text is not SVG - cannot displaysyscall 流程 用户空间执行系统调用后,触发软件中断,进入 trap_handler 2.1 用户空间 syscall # user/src/syscall.rs fn syscall(id: usize, args: [usize; 4]) -> isize { let mut ret: isize; unsafe { asm!( "ecall", # riscv trap into kernel space # set args into a0~a3 register, syscall id into a7 register, and get return from a0 inlateout("x10") args[0] => ret, in("x11") args[1], in("x12") args[2], in("x13") args[3], in("x17") id ); } ret } 2....

July 15, 2024 · 5 min · 965 words · Croak

Forfun OS - 简介

1 前言 在学习 rcore 之后,为了更加了解其中的细节,萌生了自己写一个操作系统练练手的想法。这个操作系统只是用于个人学习所用,所有设计都是简化处理。 Forfun OS 项目源码-Github kernelkernelArch-related features (linker scripts, entry assembly...)Arch-related features (linker scripts, entry assembly...)Memory Manager (PageTable, Phys Frame Allocator, Virtual Address Allocator, MemoryArea, Memory Manager for process)Memory Manager (PageTable, Phys Frame Allocator, Virtual Address Allocator, MemoryArea, Memory Manager for proce...Board-related (Not used now)Board-related (Not used now)RUSTSBI/BootloaderRUSTSBI/BootloaderProcess Manager (TCB)Process Manager (TCB)Scheduler (Task Switch, Round-robin)Scheduler (Task Switch, Round-robin)Interrupt& Trap HandlerInterrupt...Timer Timer IPC (sem, pipe, signal, shared memory...)IPC (sem, pipe, signal, shared memory....

June 14, 2024 · 2 min · 234 words · Croak