系统与基础设施cs.bham.ac.uk编辑精选
从零编写一个简单的操作系统(2010)[PDF]
Writing a simple operating system from scratch (2010) [pdf]
2014 — 2022,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是 2010 年伯明翰大学一门操作系统课程(作者 Nick Blundell)的讲义 PDF,讲的是从零手写一个简单的 x86 操作系统:从引导扇区起步,从 16 位实模式切到 32 位保护模式,再为键盘、屏幕、磁盘等硬件写自己的驱动,最终跑起一个玩具内核。篇幅不大,是典型的入门级实操教程,而不是理论教材。
为什么经久不衰:它把「从开机第一条指令到能跑 C 代码的内核」这条路一步步走通,代码可以照着敲,二十多年来一直是 OS 爱好者的第一课;读完正好接上 osdev wiki、xv6 继续深入。
HN 评论精选
讲义只到内核雏形、没有用户态进程;深入资料稀缺,得靠 osdev wiki 和 phil-opp 的博客补。
遗憾的是,这份(写得相当好的)PDF 并不完整。在我看来,操作系统意味着用户态里有进程,可惜它没讲到那一步。我现在用 Rust 写自己的 x86 32 位 OS,参考了 [0][1]。这类资料确实很缺——比如写 USB 驱动非常难,我找不到容易上手的教程,只能硬啃各种 *HCI 和 USB 规范。
Dzugaru查看英文原文
Unfortunately, this (really nice) PDF isn't complete. For me an Operating System means processes in userland, sadly it comes short of that. I'm now pushing my own x86 32bit OS in Rust using [0][1]: There is definitely a shortage of information on this stuff (for example writing a USB driver is really hard and I couldn't find easily available tutorials - you have to resort to raw *HCI and USB specs to get things done). [0] https://wiki.osdev.org/Expanded_Main_Page [1] https://os.phil-opp.com/
保护模式下 BIOS 不可用,必须自带驱动;但「临时切回 16 位调 BIOS」的取巧做法实测可行。
PDF 里说:32 位保护模式下 BIOS 例程(只适用于 16 位实模式)不再有效,用了很可能让机器崩溃,所以 32 位 OS 必须自己为所有硬件写驱动;理论上可以临时切回 16 位用 BIOS,但得不偿失。我自己写的玩具 32 位 OS 里,易用的磁盘访问和文本输出比性能更重要,所以我还是实现了这个技巧,通过 BIOS 访问磁盘和屏幕,而不是写 ATA 驱动。我找不到最小但完整可用的「降回 16 位再恢复 32 位」示例,只好自己拼出 enter_16bit_real 和 resume_32bit_mode 两个汇编函数,目前运行良好(但项目还在剧烈变动,而且是出于自举原因用十六进制编码写的)。
rmasters查看英文原文
From the PDF: "It is true: in our quest to make full use of the CPU, we must abandon all of those helpful routines provided by BIOS. As we will see when we look in more detail at the 32-bit protected mode switch-over, BIOS routines, having been coded to work only in 16-bit real mode, are no longer valid in 32-bit protected mode; indeed, attempting to use them would likely crash the machine. "So what this means is that a 32-bit operating system must provide its own drivers for all hardware of the machine (e.g. the keybaord, screen, disk drives, mouse, etc). Actually, it is possible for a 32-bit protected mode operating system to switch temporarily back into 16-bit mode whereupon it may utilise BIOS, but this teachnique can be more trouble than it is worth, especially in terms of performance." -- In the toy 32-bit OS I am currently writing, having easy disk access and text output was more important to me than performance, so I decided to implement this technique to access the disk and screen via the BIOS instead of writing an ATA disk driver. Although I could not find any minimal yet complete working examples of dropping to 16 bit and later resuming 32 bit mode, I was able to piece it together and write assembly functions called enter_16bit_real and resume_32bit_mode. See https://github.com/ironmeld/builder-hex0/blob/main/builder-hex0.hex0. Those routines are working well but beware the project is a volatile work in progress and is coded in hex for bootstrapping reasons.
技术勘误:切换保护模式后必须远跳转是为了加载 CS 描述符,与 CPU 流水线无关。
勘误:第 37 页说设置 CR0 进入 32 位模式后必须 jmp 是因为流水线,这不对。执行模式属于 CS 描述符,设置 CR0 只是表示下一次段跳转(CS:EIP)时应把段当作描述符选择子,而不是 16 位段。否则就成了和流水线抢跑的未定义行为。流水线是实现细节,你依然不用关心——你知道 386SX 的流水线有多长吗?不知道,也不需要知道。其实你完全可以继续执行 16 位代码,只把 DS/ES 装成 32 位选择子。真正的原因不是「近跳转可能不足以冲刷流水线」,而是你必须用远跳转把新选择子装入 CS,描述符才会被加载。想深入了解请看 osdev wiki。
knorker查看英文原文
Errata: Page 37 says that pipelining is the reason we need to jmp after setting 32bit mode in CR0, but that's not true. The execution mode is part of the CS descriptor, and setting CR0 merely means that "on next segment (CS:EIP) jump" we should treat the segment part not as a 16bit segment, but as a segment descriptor selector. Otherwise, dude, that would be a race against the pipelining with undefined behaviour. So no, pipelining is an implementation detail you STILL don't have to care about. Like, do you know the instruction pipeline length on a 386SX? No, because you don't have to. There's no rush to jump. (though what else are you going to do?) Actually, you could continue executing 16bit code, loading only DS/ES with 32bit selectors. Why, I don't know, but you could. > a near jump[…] may not be sufficient to flush the pipeline Nope, that's not it. You are literally jumping into a 32bit address space by loading the descriptor. The descriptor is not loaded until you load a new selector into CS by using a far jump. Mind you, this is from memory when I made my OS in high school. Back when there was a lot of moving floppies back and forth to iterate. :-/ For more on this (and the resource I wish I had back then), see https://wiki.osdev.org/
推荐 MIT 6.828 / xv6 作为进阶:代码量小、有书有录像,是理解真实 OS 的最佳下一步。
如果你对这类东西感兴趣,我个人推荐 MIT 的 6.828(操作系统工程)课程作补充,重点看为课程实现的教学 OS xv6。它小到可以打印成带交叉引用的代码清单,还有一本书逐部分讲解——你离完全理解操作系统的基本概念只差 9000 行代码。我上这门课已是几年前,但过程极其过瘾;2011 年的版本还有课堂录像。
timsally查看英文原文
If you're interested in this type of stuff I can personally recommend MIT's 6.828 course (Operating Systems Engineering) as an additional resource. Specifically, you'll want to take a look at xv6, a teaching OS implemented for the course (http://pdos.csail.mit.edu/6.828/2014/xv6.html). The OS is small enough to print as cross referenced code listing (http://pdos.csail.mit.edu/6.828/2014/xv6/xv6-rev8.pdf) and has a book that fully explains each piece (http://pdos.csail.mit.edu/6.828/2014/xv6/book-rev8.pdf). You are only 9,000 lines of code away from fully understanding basic operating systems concepts! It's been a few years since I took the class but it was an absolute blast. The offering in 2011 has recorded lecture videos (http://pdos.csail.mit.edu/6.828/2011/schedule.html).
历次讨论
同类还值得读
TTY 揭秘(2008)
The TTY demystified (2008)
经典文章深入剖析了 Unix/Linux 中 TTY 子系统的工作原理,包括线路规程、终端驱动、信号与控制字符等机制。
系统与基础设施上首页 11 次 · 2009–2025linusakesson.net编辑精选为什么 GNU grep 这么快
Why GNU grep is Fast
FreeBSD 邮件列表上一篇广为流传的帖子,解释 GNU grep 为什么快:核心在于 Boyer-Moore 字符串搜索算法配合精心优化的内部循环和 I/O,让程序在搜索时“…
系统与基础设施上首页 9 次 · 2010–2022lists.freebsd.orgXplain:为普通人讲解 X11
Xplain – Explaining X11 for the rest of us
《Xplain》是作者(HN 用户 Jasper_)写的一系列 X11 长文,用他在浏览器中重建的 X11 绘图模型做交互演示,讲解 X11 的绘图模型与窗口系统设计。
系统与基础设施上首页 6 次 · 2013–2020magcius.github.io编辑精选旋风教程:为 Linux 创建极小 ELF 可执行文件(1999)
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux (1999)
breadbox 写于 1999 年的经典教程,主题是如何为 Linux 手工构造并裁剪出体积极小的 ELF 可执行文件。
系统与基础设施上首页 6 次 · 2007–2025muppetlabs.comPostgreSQL 内部原理
The internals of PostgreSQL
《The Internals of PostgreSQL》是一本免费在线书籍,系统讲解 PostgreSQL 的内部实现,包括查询处理、并发控制、WAL、缓冲区管理等核心机制。
系统与基础设施上首页 5 次 · 2017–2025interdb.jp编辑精选