Skip to content

Commit 1c9bcc5

Browse files
committed
docs(操作系统): 补充注意事项和项目构建说明
1 parent 1d3d545 commit 1c9bcc5

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

docs/教程/正文/项目/MdrOS/build.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
1616
## 自制引导用户
1717

18+
### MBR LegacyBIOS 引导方式
19+
1820
通常你们需要的准备工作要求更多,且编写后的操作系统运行的介质非常有限
1921

2022
可以借鉴《30 天自制操作系统》的 MBR 软盘引导程序
23+
24+
### GPT UEFI BIOS 引导方式
25+
26+
可以使用EDK2开发套件或采用自己编写EFI程序
27+
28+
引导器可以获取到内存布局表后传入内核,即可开始引导.
29+
30+
因系统信息, 文件读取等都有 UEFI 接口提供, 所以编写相对简单一些

docs/教程/正文/项目/MdrOS/项目概述.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
本章教程将教学您如何开发一个 x86 平台的操作系统
55

66
> 该教程有很多不详细之处,并不能直接作为保姆式教程使用
7+
>
8+
> * 实际上该羡项目为参考式项目, 提供了一个大致的开发方向,以及标注了很多开发中可能遇到的问题
79
810
## 概念
911

@@ -76,7 +78,7 @@
7678
- 《30 天自制操作系统》这本书仅供 GUI 部分参考,其他功能实现并不是很好,不建议您全部借鉴
7779
- 64 位长的操作系统会比 32 位保护模式的操作系统实现更难,比如 32 位只需要二级页表即可,64 位需要 4 级甚至更多才能管理所有内存
7880
- ARM 等其他架构的 CPU 与 x86 平台的 CPU 实现截然不同,其中 x86 的很多机制在 ARM 是没有的,同理 ARM 某些机制 x86 也没有
79-
- 本教程只是教学您如何实现一个最简单的宏内核操作系统,如果您想完善您的操作系统,可以去查阅更多的资料
81+
- 本教程只是给予开发的一个大致方向与常见问题解答, 注意事项提醒等
8082
- 操作系统编写好都是要在实体机上测试的,无法在实体机上跑的操作系统就不是一个真正的操作系统
8183

8284
## 注意事项
@@ -89,12 +91,40 @@
8991

9092
> 4Kib: 可以用十进制 `4096` 表示,也可以用十六进制 `0x1000` 表示
9193
94+
### 内存
95+
9296
- cr3 指向的页表基址,必须进行 `4k` 对齐
9397
- 物理内存管理分配出来的页框基址,必须是 `4k` 对齐的再写入页
9498
- `rsp` 的栈基址最好为 16 字节对齐,因为部分实体机机型对此有要求
95-
- 所有设备驱动需要往 `MMIO` 设备寄存器传入物理地址。
96-
- 部分实体机的机型对 `cpuid` 指令的实现有些许差异,编写多核 CPU 初始化等代码时候需要用 `ACPI``lapic_id` 获取核心的代号,不要用 `cpuid` 指令获取
97-
- 锁不要滥用,否则会发生死锁
99+
- 对于物理页框分配器, 在使用提供一个初始页表的引导器操作系统开发中(如 Limine), 需要额外注意内核本身与页表本身的内存占用, 否则容易覆写
100+
- 页表本身需要在物理内存上具有连续性, 且基址必须4k对齐
101+
- 页映射释放后需执行一遍 `TLB` 快表刷新操作, 防止缓存干扰映射规则
102+
103+
### 驱动
104+
105+
- 所有设备驱动需要往 `MMIO` 设备寄存器传入物理地址(设备控制器没有MMU, 传入虚拟地址无法处理)
98106
- 设备 IRQ 中断请求必须要向中断控制器发送 `EOI` 代表请求处理完毕,不然下一次设备请求不会再次发送
99107
- `PS/2` 键盘需要在你获取了扫描码后才会发送下一次中断,否则 `PS/2` 控制器会阻塞
108+
- `PS/2` 设备中断处理需要在最后发送 `EOI`, 否则多个扫描码发送会造成中断嵌套
109+
110+
### CPU
111+
100112
- `qemu` `VMware` 虚拟机对 `wrfsbase` `rdgsbase` 等扩展指令支持性较差,建议使用 `msr``fs` `gs` 段寄存器进行操作
113+
- 部分实体机的机型对 `cpuid` 指令的实现有些许差异,编写多核 CPU 初始化等代码时候需要用 `ACPI``lapic_id` 获取核心的代号,不要用 `cpuid` 指令获取
114+
- 特殊的扩展指令(如syscall)需要特别设置控制寄存器或 `MSR`去启用, 且多核环境下需要为每一个核心都执行一遍启用操作
115+
- 内核中不要滥用 `pause` `hlt` 等指令, 这些指令会造成CPU功耗、频率降低,从而影响性能.
116+
117+
### 并发 / 异步
118+
119+
- 锁不要滥用,否则会发生死锁
120+
- 调度器时钟频率不要太高, 否则调度器本身未执行完毕会再一次进入调度器造成中断嵌套
121+
- 异步冲突临界区必须加锁, 否则会造成资源竞争冲突
122+
123+
### 开发
124+
125+
- 编译器最好开一下严格模式, 因为操作系统本身是非常不好调试的, 而且BUG溯源极其困难, 一个小小的错误会让你头疼一个星期甚至一个月
126+
- 详见 [编程交流生存指南](/杂项/技术无关/1_编程交流群生存指南.md) 第 1 标题, 第 40,41,43 条
127+
- 作为内核, 你永远要以最坏的情况去针对用户态程序, 用户 `syscall` 传来的参数要严格检查是否是空指针以及地址合法性
128+
- 对于内核中对参数有要求的接口, 要对参数打好断言, 这样可以在自己犯傻后可以快速找出问题
129+
130+
> 你要清楚自己写的是什么, 有哪些不足, 应该如何安排项目结构

0 commit comments

Comments
 (0)