Skip to content
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
4 changes: 2 additions & 2 deletions source/chapter1/0intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

不过我们能够隐约意识到编程工作能够如此方便简洁并不是理所当然的,实际上有着多层硬件和软件工具和支撑环境隐藏在它背后,才让我们不必付出那么多努力就能够创造出功能强大的应用程序。生成应用程序二进制执行代码所依赖的是以 **编译器** 为主的开发环境;运行应用程序执行码所依赖的是以 **操作系统** 为主的执行环境。

本章我们将从操作系统最简单但也是最重要的println入手,要求大家实现一个裸机上的println以及带色彩的LOG,如info和warn,error等功能。因为大家是刚刚接触操作系统实验,本章的所有代码已经帮大家写好了,没有大家需要亲自编写代码的部分。但是它作为第一章又是最重要的一个章节:这一章之中,同学们要对整个 C 的 OS 实验框架有一个大致的掌握。对整个框架是如何编译的,之后需要写哪些内容以及如何测试有一个基本的认识。可以说,ch1 打好基础会使得之后的实验难度大大降低。
本章我们将从操作系统最简单但也是最重要的printf入手,要求大家实现一个裸机上的printf以及带色彩的LOG,如info和warn,error等功能。因为大家是刚刚接触操作系统实验,本章的所有代码已经帮大家写好了,没有大家需要亲自编写代码的部分。但是它作为第一章又是最重要的一个章节:这一章之中,同学们要对整个 C 的 OS 实验框架有一个大致的掌握。对整个框架是如何编译的,之后需要写哪些内容以及如何测试有一个基本的认识。可以说,ch1 打好基础会使得之后的实验难度大大降低。

系统调用
---------------------------

在实验开始之前,大家要熟悉一下系统调用(syscall)的概念。相信大家在汇编的课程中一定接触过这个名词。我们 OS 课程中的 syscall 的意义也是一样的,它是操作系统提供给软件的一系列接口,使得软件能够使用系统的功能。syscall 本质上属于一种异常/中断,它在 riscv 的汇编指令中以 ecall 的形式出现。

本章的 println 所需要的在 console 中打印字符,也需要调用到 syscall。syscall 的种类有很多,操作系统通过区分 syscall 的 id 来判断是哪一个syscall。
本章的 printf 所需要的在 console 中打印字符,也需要调用到 syscall。syscall 的种类有很多,操作系统通过区分 syscall 的 id 来判断是哪一个syscall。

实践体验
---------------------------
Expand Down
2 changes: 1 addition & 1 deletion source/chapter1/2remove-std.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ makefile 内部

TOOLPREFIX = riscv64-unknown-elf-
CC = $(TOOLPREFIX)gcc
AS = $(TOOLPREFIX)gas
AS = $(TOOLPREFIX)as
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
Expand Down
2 changes: 1 addition & 1 deletion source/chapter3/2proc-basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
.. code-block:: C
:linenos:

// os/trap.c
// os/proc.h

struct proc pool[NPROC]; // 全局进程池
struct proc idle; // boot 进程
Expand Down
8 changes: 4 additions & 4 deletions source/chapter5/3shell-and-binloader.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ exec会调用bin_loader,将对应文件名的测例加载到指定的进程p之
int bin_loader(uint64 start, uint64 end, struct proc *p)
{
void *page;
// 注意现在我们不要求对其了,代码的核心逻辑还是把 [start, end)
// 注意现在我们不要求对齐了,代码的核心逻辑还是把 [start, end)
// 映射到虚拟内存的 [BASE_ADDRESS, BASE_ADDRESS + length)
uint64 pa_start = PGROUNDDOWN(start);
uint64 pa_end = PGROUNDUP(end);
Expand All @@ -28,10 +28,10 @@ exec会调用bin_loader,将对应文件名的测例加载到指定的进程p之
for (uint64 va = va_start, pa = pa_start; pa < pa_end;
va += PGSIZE, pa += PGSIZE) {
// 这里我们不会直接映射,而是新分配一个页面,然后使用 memmove 进行拷贝
// 这样就不会有对其的问题了,但为何这么做其实有更深层的原因。
// 这样就不会有对齐的问题了,但为何这么做其实有更深层的原因。
page = kalloc();
memmove(page, (const void *)pa, PGSIZE);
// 这个 if 就是为了防止 start end 不对其导致拷贝了多余的内核数据
// 这个 if 就是为了防止 start end 不对齐导致拷贝了多余的内核数据
// 我们需要手动把它们清空
if (pa < start) {
memset(page, 0, start - va);
Expand Down Expand Up @@ -189,4 +189,4 @@ usershell
return len;
}

目前我们只支持标准输入stdin的输入(对应fd = STDIN)。
目前我们只支持标准输入stdin的输入(对应fd = STDIN)。