跳转至

收尾应用与前方的路 — 让关闭按钮活过来,然后看向更远处

这一章讲什么: 没有新理论,全是「让它像个能用的系统」的最后几步: 应用不用敲 apps/ 前缀;长输出用 more 翻页;cat 能吃标准输入, cat > foo 就能造文本文件;画了十五天的关闭按钮终于能点; 文本/图像查看器把屏幕点亮。然后第 31 章放下烙铁,指了几条前方的路。

1. 先看现象:一条从「能用」到「好用」的清单

主线例子:

  grep foo memmap           ← FindCommand:当前目录找不到 → 自动搜 apps/
  ls / | more               ← more 分页读 stdin,满一屏等按键
  cat > foobar              ← cat 无参数 = 读 stdin;配合重定向,三行文本文件诞生
  (点窗口右上角的 ×)        ← GetWindowRegion 判定点击落在关闭按钮区
       → 发 kWindowClose 给窗口所属任务 → 应用收到事件,自己关窗退出
  tview mikanos.txt         ← 日文 + 制表符的文本查看器(用户手册上屏)
  gview fuji.jpg            ← stb_image 解码 JPEG,照片铺满窗口

2. 顶层全景

  30.1 FindCommand(apps/ 搜索路径)
  30.2 more(按页读 stdin;ls | more 的组合)
  30.3 cat 支持 stdin(无参读 stdin;cat > file 造文件)
  30.4 关闭按钮(GetWindowRegion:标题栏/关闭按钮/边框/其他;kWindowClose 消息)
  30.5 tview 文本查看器(选项解析、制表符、UTF-8 日文)
  30.6 gview 图像查看器(BMP=像素数组;JPEG 用 stb_image;HariboteOS 的旧库没跑通)
  第 31 章 前方的路(fork/exec、虚拟内存/交换、内存分配器、驱动、自托管)
  附录(开发环境、MikanOS 源码、EDK II 三件套、模板、iPXE、ASCII 表)

  图说:全是应用层与交互层的活——内核的账到此还清,剩的是体验。

3. 核心原理

3.1 三个小命令,补齐 shell 的骨架

  • FindCommand:敲 grep 时先在当前目录找,找不到就搜 apps/—— PATH 的胚胎,「每次添加 apps/ 都很麻烦」就是它的出生理由1;
  • more:more [-n] [file],按页输出、满屏等按键;没给文件就分页读标准输入—— ls | more 的组合让长输出第一次可读2;
  • cat 支持 stdin:无文件名参数时读标准输入。妙用在重定向: cat > foobar 键盘输入 + Ctrl+D,三行文本文件诞生—— 「一旦可以创建文本文件,就可以随时创建用于检查其他命令运行情况的文件」3。

3.2 关闭按钮:点击判定与消息

关闭按钮此前只是一张贴图。激活它的两步:

  1. 区域判定 GetWindowRegion(x, y):点击坐标落在窗口的哪个区—— 标题栏(拖动)/ 关闭按钮 / 边框 / 其他(内容区归应用)4;
  2. 通知:点在关闭按钮 → SendCloseMessage 给窗口关联的任务发 kWindowClose 消息——应用收到后自己关窗、退出5。 窗口系统管判定,应用管反应——两段的职责划得干净。

3.3 两个查看器:库的取舍

  • tview:约 250 行的文本查看器;选项解析(w/h/制表符宽度)、 UTF-8 日文、制表符对齐;tview mikanos.txt 就是 MikanOS 的用户手册6;
  • gview:BMP 只是像素颜色数组(简单),JPEG 复杂—— 作者先试 HariboteOS 时代的老 JPEG 库,怎么都跑不通,换 stb_image (单头文件库,BMP/JPEG/PNG 通吃),stbi_load_from_memory 从内存解码, 查看器成了7。——库的现场选型:旧的不灵,换公认的;别在一只库上吊死。

3.4 前方的路(第 31 章)

作者列的下一站:把终端从内核里搬出去做成应用(需要 fork/exec 那样的系统调用); 虚拟内存(物理内存不够时把不常用的页换到存储器,应用无感); 更好的内存分配器(伙伴系统之于位图法);SATA/NVMe 驱动让系统真正摸到盘; USB 驱动扩展(集线器、U 盘、摄像头);更野的路——读改 Linux、写自己的 C 编译器、 造自己的 CPU,以及 OpeLa 项目的终极野望:自制语言跑在自制 OS 上、再拿它写 OS 和编译器(自托管)8。他也没忘交代学习方法:这本书值得读两三遍, 第二遍会更轻松;Intel SDM 是 deeper 的入口9。

4. 作者的判断与证据

判断:好用的最后一步都是「小功能」。 搜索路径、分页器、关闭按钮—— 没有一件动内核架构,但缺一件都不像「能给人用的系统」。

判断:库选型的铁律是「不纠缠」。 HariboteOS 的 JPEG 库没能跑通就换 stb_image, 没有深挖「为什么不行」——收尾阶段,交付优先于考古。

证据: 各命令与查看器的运行截图;第 31 章的方向清单是作者自己的 OpeLa 项目 背书的(「我们在 2020 年底启动了 OpeLa 项目」)。

5. 边界与局限

  • more 的分页靠按键事件,没有「按任意键」之外的导航(不能往回翻,那是 less);
  • 关闭按钮只对「会响应 kWindowClose 的应用」有效,老旧应用点了也没反应;
  • gview 靠 stb_image 的内存解码,大图就是内存开销;
  • 附录 A–F(开发环境、源码获取、EDK II 三件套说明、C++ 模板、iPXE、ASCII 表) 是操作手册性质,本拆解不逐节复述,需要时查原书附录。

6. 可带走的

本章主线例子,一行写完: FindCommand 省前缀 → more 分页、cat 吃 stdin(造文件)→ 关闭按钮(区域判定 + kWindowClose)→ tview/gview 点亮屏幕 → 前方的路指向 fork/exec、交换、驱动与自托管。

  1. PATH 的胚胎 = 应用搜索路径;省下的前缀是最好的 UX;
  2. 分页器(more)是管道的下游标配;cat > file 是「stdin + 重定向」造文件的活教材;
  3. 窗口系统管点击判定(区域分类),应用管反应(消息)——职责两段划清;
  4. BMP = 像素数组;JPEG 交给经过考验的库(stb_image),旧库不纠缠;
  5. 前进方向清单:fork/exec、虚拟内存(交换)、伙伴分配器、块设备驱动、USB 扩展;
  6. 终极度:自托管(自制语言 × 自制 OS × 自制编译器);
  7. 这本书至少读两遍;Intel SDM 在更深处等你。

7. 原文地图

主题 原书章 原文位置
FindCommand 30.1 应用路径程序(osbook_day30a) text/188-ch30-01-30-1-osbook-day30a.txt:4(搜「apps/」) · text/188-ch30-01-30-1-osbook-day30a.txt:11(搜「FindCommand」)
more 命令 30.2 more命令(osbook_day30b) text/189-ch30-02-30-2-more-osbook-day30b.txt:25(搜「more和less」) · text/189-ch30-02-30-2-more-osbook-day30b.txt:42(搜「页的行数」)
cat 与 stdin 30.3 使cat与输入相对应(osbook_day30c) text/190-ch30-03-30-3-cat-osbook-day30c.txt:14(搜「无法处理标准输入」) · text/190-ch30-03-30-3-cat-osbook-day30c.txt:20(搜「cat foo」)
关闭按钮区域判定 30.4 关闭按钮(osbook_day30d) text/191-ch30-04-30-4-osbook-day30d.txt:16(搜「只是一张图片」) · text/191-ch30-04-30-4-osbook-day30d.txt:29(搜「关闭按钮的上方」) · text/191-ch30-04-30-4-osbook-day30d.txt:64(搜「GetWindowRegion」)
kWindowClose 30.4 关闭按钮(osbook_day30d) text/191-ch30-04-30-4-osbook-day30d.txt:82(搜「SendCloseMessage」) · text/191-ch30-04-30-4-osbook-day30d.txt:95(搜「kwindowClose」)
tview 30.5 文本查看器(osbook_day30e) text/192-ch30-05-30-5-osbook-day30e.txt:26(搜「tview」) · text/192-ch30-05-30-5-osbook-day30e.txt:68(搜「mikanos.txt」)
gview 与库的取舍 30.6 图像查看器(osbook_day30f) text/193-ch30-06-30-6-osbook-day30f.txt:5(搜「位图图像和JPEG」) · text/193-ch30-06-30-6-osbook-day30f.txt:14(搜「无法工作」) · text/193-ch30-06-30-6-osbook-day30f.txt:21(搜「stb_image.h」) · text/193-ch30-06-30-6-osbook-day30f.txt:34(搜「stbi_load_from_memory」)
前方的路 第31章 前方的路 text/194-ch31.txt:8(搜「重制成一个应用」) · text/194-ch31.txt:10(搜「虚拟内存」) · text/194-ch31.txt:17(搜「Buddy」) · text/194-ch31.txt:26(搜「OpeLa」) · text/194-ch31.txt:43(搜「两三遍」)

  1. 出处:「30.1 应用路径程序」(text/188-ch30-01-30-1-osbook-day30a.txt:4,搜「apps/」;:11,搜「FindCommand」)。 ↩

  2. 出处:「30.2 more命令」(text/189-ch30-02-30-2-more-osbook-day30b.txt:25,搜「more和less」;:36,搜「页的行数」;:42,搜「WaitKey」)。 ↩

  3. 出处:「30.3 使cat与输入相对应」(text/190-ch30-03-30-3-cat-osbook-day30c.txt:14,搜「无法处理标准输入」;:18,搜「cat foo」;:29,搜「省略了文件名」)。 ↩

  4. 出处:「30.4 关闭按钮」(text/191-ch30-04-30-4-osbook-day30d.txt:16,搜「只是一张图片」;:29,搜「关闭按钮的上方」;:64,搜「GetWindowRegion」)。 ↩

  5. 出处:「30.4 关闭按钮」(text/191-ch30-04-30-4-osbook-day30d.txt:82,搜「SendCloseMessage」;:95,搜「kwindowClose」)。 ↩

  6. 出处:「30.5 文本查看器」(text/192-ch30-05-30-5-osbook-day30e.txt:26,搜「tview」;:39,搜「250行」;:68,搜「mikanos.txt」)。 ↩

  7. 出处:「30.6 图像查看器」(text/193-ch30-06-30-6-osbook-day30f.txt:5,搜「位图图像和JPEG」;:8,搜「颜色信息数组」;:34,搜「stbi_load_from_memory」)。 ↩

  8. 出处:「30.6 图像查看器」(text/193-ch30-06-30-6-osbook-day30f.txt:14,搜「无法工作」;:21,搜「stb_image.h」——旧库不通则换公认库)。 ↩

  9. 出处:「第31章 前方的路」(text/194-ch31.txt:8,搜「重制成一个应用」;:10,搜「虚拟内存」;:15,搜「Buddy系统」;:19,搜「SATA或NVMe」;:26,搜「OpeLa」)。 ↩