12 - Building the application ecosystem

12 - 构建应用生态

我们已经了解了一个典型的操作系统给应用程序提供的 “一切”:从操作系统为应用程序提供的对象和 API 到可执行文件的链接和加载,操作系统实现了管理硬件资源的底层机制。这是狭义 “操作系统” 负责的功能。

本讲内容:一个真实的 “操作系统”,如何使用操作系统的对象和 API,构建丰富的应用生态?其中又有怎样的实用工具起到了决定性的作用?

1. 从 UNIX 到 Linux

1.1. Evolution of the UNIX Time Sharing System

最早的版本甚至没有 fork

  1. Shell 关闭所有打开的文件,然后为 0, 1 fd 打开终端文件

    1. 单进程的 不支持多进程的

  2. 从终端读取命令行

  3. 打开文件,把加载器代码复制到内存并执行 (相当于 exec)

    1. 当时还没有 fork()

  4. exit 会重新加载 shell

      • 先做一堆垃圾出来

      • 见过的所有大系统,一开始都是几个大学生组队开发的...几个好朋友...

      • 最后就成功了

所以,从零开始做很重要

早期版本的操作系统其实和我们的 MiniLab 很像...

1.2. Minix

Minix1 (1987)

  • UNIXv7 兼容

  • Linus 实现 Linux 的起点

  • 同时兼容 16-bit 和 32-bit

    • 真实展示 16-bit 编程

Minix2arrow-up-right (1997)

  • POSIX 兼容

  • 随书附有代码

微内核的处理器,源代码很简单...甚至可以随书附赠...

这时候已经能实现现代 OS 的一些常用功能了...

Tips:Minix 是32位的,意味着 sizeof(int) == 2

1.3. 年轻人的第一个操作系统

Minix3arrow-up-right (2006): POSIX/NetBSD 兼容

  • 一度是世界上应用最广的操作系统 (Intel ME)

1.4. August, 1991, The Birthday of Linux

Hello, everybody out there using minix – I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones. This has been brewing since April, and is starting to get ready.

—— Linus Torvalds (时年 21 岁)

类似于 “我写了个加强版的 OSLab,现在与大家分享”

  • 发布在 comp.os.minix

    • (“百度贴吧”)

    • 因为还依赖 Minix 的工具链 (从零开始做东西是不现实的)

    • 跑的都是 GNU 的程序:gcc, bash, ...

  • 合适的人、合适的时间

    • 386(486) 的时间点

    • 计算机硬件刚好起飞

1.5. "Just for fun"

The story of an accidental revolutionary

Revolutionaries aren’t born. Revolutions can’t be planned. Revolutions can’t be managed. Revolutions happen....

—— David Diamond (本书作者)

教育部印发《关于加强高校有组织科研 推动高水平自立自强的若干意见》

  • 就推动高校充分发挥新型举国体制优势,加强有组织科研,全面加强创新体系建设,着力提升自主创新能力,更高质量、更大贡献服务国家战略需求作出部署。

  • “在人-机-物融合时代实现操作系统的弯道 (换道) 超车”

在学校里总是被一些莫名其妙的事情拖住...因为我们的国家要生存...所以我们只能在夹缝中生存

1.6. "Linux is Obsolete" Debate

在 comp.os.minix 上关于 Linux 的讨论越来越多了

  • Andrew Tanenbaum 做出了 “官方回应”

    • 觉得 “太落后”

  • Linus 完全不服气

  • Ken Thompson 也参与了讨论

    • 他已经在 ~10 年前获得了图灵奖……

1.7. 后来的事

linux 代码指数增长???

  • Linux 2.0 引入多处理器 (Big Kernel Lock, 内核不能并行)

  • Linux 2.4 内核并行

  • 2002 年才引入 Read-Copy-Update (RCU) 无锁同步

  • 2003 年 Linux 2.6 发布,随云计算开始起飞

1.8. Linux 的“两面”

Kernel

  • 加载第一个进程

    • 相当于在操作系统中 “放置一个位于初始状态的状态机”

    • “Initramfs” 模式

  • 包含一些进程可操纵的操作系统对象

  • 除此之外 “什么也没有” (Kernel 就是一个 trap handler)

Linux Kernel 系统调用上的发行版和应用生态

2. Linux 和应用程序的接口 🌶️

2.1. 除了对象和系统调用 API

The last piece: “初始状态”

  • Everything is a state machine

    • “操作系统中的对象” 应该也有一个初始状态

它是什么呢?

  • 观察到 Linux 的系统更新

    • “update-initramfs... (漫长的等待)”

    • 这就是 Linux Kernel 启动后的 “初始状态”

2.2. initramfs

我们的 initramfs

  • 可以只有一个 init 文件

最小的 Linux...

    • 可以是任意的 binary,包括我们自己实现的

  • (系统启动后,Linux 还会增加 /dev 和 /dev/console)

    • 需要给 stdin/stdout/stderr 一个 “地方”

实际的 initramfs (我们可以解开来看一看)

  • 基本的命令行工具

  • 基础设备驱动程序 (可能从磁盘/网络挂载文件系统)

  • 文件系统工具 (万一磁盘损坏了,还能抢救一下)

2.3. 点亮 Linux 世界

Busyboxarrow-up-right utilities

2.4. 并不是我们平时“看到”的“Linux”世界

启动的初级阶段

  • 加载剩余必要的驱动程序,例如磁盘/网卡

  • 挂载必要的文件系统

    • Linux 内核有启动选项 (类似环境变量)

      • /proc/cmdline (man 7 bootparam)

    • 读取 root filesystem 的 /etc/fstab

  • 将根文件系统和控制权移交给另一个程序,例如 systemd

启动的第二级阶段

  • 看一看系统里的 /sbin/init 是什么?

  • 计算机系统没有魔法 (一切都有合适的解释)

2.5. 构建真正应用世界的系统调用

switch_root 命令背后的系统调用

  • pivot_root() changes the root mount in the mount namespace of the calling process. More precisely, it moves the root mount to the directory put_old and makes new_root the new root mount. The calling process must have the CAP_SYS_ADMIN capability in the user namespace that owns the caller's mount namespace.

  • syscalls(2)

2.6. 自己接管一切

创建一个磁盘镜像

  • /sbin/init 指向任何一个程序

    • 同样需要加载必要的驱动

    • 例子:pivot_root 之后才加载网卡驱动、配置 IP

    • 例子:tty 字体变化

      • 这些都是 systemd 的工作

Initramfs 会被释放

  • 功成身退

2.7. That's All: 操作系统 = 对象的集合

初始状态

  • initramfs 中的对象 + /dev/console + 加载的 init

状态迁移

  • 选择一个进程 (对象) 执行一条指令

  • 系统调用指令

    • 进程管理: fork, execve, exit, waitpid, getpid, ...

    • 操作系统对象和访问: open, close, read, write, pipe, mount, mkfifo, mknod, stat, socket, ...

    • 地址空间管理: mmap, sbrk (mmap 的前身)

    • 以及一些其他的机制: pivot_root, chmod, chown, ...

3. 构建应用程序的世界

3.1. 操作系统是幕后的 MVP

仅有的机制

  • 初始状态 + 系统调用

操作系统完全 “感知不到” 应用程序

  • Shell: 系统管理的接口

  • 系统工具: grep, cat, gcc, ...

  • 应用程序: vscode, ...

  • 后台服务: sshd, httpd, ...

    • 嘿!AI 时代,操作系统也许可以 “感知” 应用了:为每一个 system call (甚至是 function call) 提供 “traceability”

3.2. 我们还是需要应用程序

前互联网时代

  • 软盘发行 (DOS) v.s. 光盘发行 (Windows 3.X/95)

    • 双击安装程序,输入 CD-Key (“破解” 简直太容易了)

  • 光驱:光盘驱动器...

今天呢?

  • 装应用哪那么麻烦;登录账号,自动管理,自动更新、……

3.3. 应用生态

应用商店模式

开源模式

  • 开发者维护代码

  • 和发行版团队共同维护应用仓库

3.4. Debian

Our Mission: Creating a Free Operating System

The Debian Project is an association of individuals, sharing a common goal: We want to create a free operating system, freely available for everyone. Now, when we use the word "free", we're not talking about money, instead, we are referring to software freedom.

  • CS 和其他任何学科都不同:开源开放

  • apt-get install firefox (1998)

    • 跨时代的 “Advanced Packaging Tool”

Debian 的包管理:“软件供应链”

3.5. Debian 软件包 deb

一个压缩包 (例子arrow-up-right)

  • control.tar.xz

    • “control” 文件: Package, Source, Version, Architecture, Maintainer, Depends, Suggests, Section, Priority, Description, ...

  • data.tar.xz

    • 实际的文件 (绝对路径)

  • dpkg 可以安装 deb 包

    • 它也是操作系统上的一个普通应用程序 (使用系统调用完成 “安装” 功能)

3.6. 生态

为什么建设我们的生态那么艰难?

  • 生态的关键是开发者

  • 但 qualify 的开发者太少了

    • 大学四年都在写高血压代码?

    • 错误的设计 = 无法维护的泥潭

      • 课程的使命是让大家 “见识” 各种设计

      • 蒋门万岁!!!

AI 时代

  • “软件生态” 会消失吗?

    • 只需要一个 “最小” 的执行环境

    • AI 随时随地按需生成代码

4. 总结

正式结束了 Virtualization 部分的课程...虚拟化...

Take-away Messages: 至此,我们终于完全展示了逐层抽象的计算机系统世界:

  • 硬件向上提供了指令集体系结构

  • 基于指令集,实现了操作系统 (对象、系统调用 API 和 initramfs 定义的初始状态)

  • 操作系统上面支撑了系统工具 (coreutils, shell, apt, gcc, ...)

  • 系统工具上面才是各式各样的应用程序

实际上,我们看到的计算机系统中的一切都是由应用程序 “完成” 的,操作系统只是提供系统调用这个非常原始的服务接口。正是系统调用 (包括操作系统中的对象) 这个稳定的、向后兼容的接口随着历史演化和积累,形成了难以逾越的技术屏障,在颠覆性的技术革新到来之前,另起炉灶都是非常困难的。

Last updated