TLPI 第1章 读书笔记:History and Standards

张开发
2026/4/16 23:02:18 15 分钟阅读

分享文章

TLPI 第1章 读书笔记:History and Standards
笔记和练习博客总目录见开始读TLPI。UNIX 系统的开发并非由单一厂商或组织控制好处是带来很多创新弊端则是众多分支导致编写能在所有 UNIX 实现上运行的应用程序非常困难可移植性。UNIX商标的持有者是Open Group其官方标准为SUSSingle UNIX Specification。通过SUS认证的UNIX系统包括MacOSHP-UXIBM AIX等。Linux虽不在认证列表中但被认为是类UNIX系统。UNIX标准介绍参见这里。此网页还有UNIX发展简史图UNIX Overview是配合上图的文字介绍。1.1 A Brief History of UNIX and CUNIX诞生于1969年Linus Torvalds出生最初用汇编语言编写后来用C重写。C语言的目标就是用于实现 UNIX 内核及相关软件的高级语言。UNIX的C语言基因使得后来系统编程大多使用C语言。1974 年 7 月Dennis M. Ritchie 和 Ken Thompson在ACM上发表了论文The UNIX Time-Sharing System。在1969年至1979年期间UNIX经历了多个版本这些版本被称为editions。其中第7版非常重要不仅因为这一版提供了增强的文件系统awk、sed、tar、bash等工具而且从此版开始形成了BSD和System V 两个分支在上图中有体现其中重点提了可移植性。BSD即Berkeley Software Distribution起步于1975/1976学年Ken Thompson 作为访问教授在加利福尼亚大学伯克利分校任教时这所大学也是他毕业的学校。其中一个参与项目的学生Bill Joy后来成为Sun的联合创始人。所以SunOS实际带有BSD的基因。4.2BSD是一个重要的版本因其包含了完整的TCP/IP实现包括socket API。美国的反垄断立法迫使 ATT 解体后UNIX被允许销售这导致了1981年 System III系统三的发布继而到1983年的System V。1989年发布了最终版本SVR4System V Release 4此时的System V也从BSD借鉴了很多特性。简单来说BSD和System V分别走的是学术和商业路线。一些路由器、存储、游戏机多使用BSD其中macOS是目前最大的 BSD 商业应用。而HP-UXAIXSolarisSCO OpenServer 等则源于System V。而Linux是独立内核兼容 BSD System V但不直接源于两者。总的来说UNIX系统的可移植性及廉价单用户 UNIX 工作站的出现使得 UNIX 系统从商业角度来看越来越具有吸引力。 可移植性兼容性互操作性有何区别可移植性关注Can I move it?兼容性关注Can it co-exist?互操作性关注Can it communicate?。对于应用软件而言数据库从11g升级到19c主要影响的是 兼容性其次是互操作性。操作系统由AIX换为Linux主要影响的是可移植性其次是兼容性。而一些协议和API的变更OAuth 1.0 → 2.0、TLS 版本升级则主要影响互操作性。1.2 A Brief History of Linux1.2.1 The GNU Project1984年Richard Stallman一位曾在麻省理工学院MIT工作的极有才华的程序员开始着手创建一个“自由”的UNIX实现目的是希望像操作系统这样的软件将以免费或极低的成本提供。Free Software中的Free并非免费之意正如在What is Free Software?的声明所说“自由软件”指的是尊重用户自由和社区的软件。大致来说这意味着用户有权运行、复制、分发、研究、修改和改进软件。因此“自由软件”关乎的是自由而不是价格。要理解这个概念你应该把“自由”理解为“言论自由”中的自由而不是“免费啤酒”中的免费。我们有时称之为“libre 软件”借用法语或西班牙语中表示自由的词以表明我们并不是指软件是免费的。你可能为获得自由软件的副本支付过费用也可能免费获得过副本。但无论你是如何获得这些副本的你始终拥有复制和修改软件的自由甚至可以出售副本。Stallman 反对计算机供应商对专有操作系统施加的法律限制。这些限制意味着计算机软件的购买者通常无法看到他们所购买软件的源代码更不用说复制、修改或重新分发它了。他指出这样的体系鼓励程序员相互竞争并囤积自己的工作而不是合作和分享。为此Stallman 启动了GNU项目GNU表示“GNU’s not UNIX”。也就是说接口、用法和 UNIX 完全一样但代码完全重新写、完全自由开源。GNU 项目的一个重要成果是 GNU 通用公共许可证 (GPL) 的制定这是斯托曼自由软件理念的法律体现。Linux 发行版中的许多软件包括内核都是根据 GPL 或其他类似许可证发布的。根据 GPL 授权的软件必须以源代码形式提供并且必须可以在 GPL 条款下自由再分发。对 GPL 授权的软件进行修改是完全允许的但任何对这些修改后的软件的分发也必须遵守 GPL 条款。如果修改后的软件以可执行形式分发作者还必须允许任何接收者选择以不超过分发成本的价钱获得修改后的源代码源码不能卖钱只能收 “分发成本”即光盘、U 盘、邮寄、带宽这类物理 / 传输成本。到1990年代初GNU项目已经开发出了一个几乎完整的系统一些知名的项目包括Emacs文本编辑器、GCC、bash shell和glibc。唯一缺少的重要组件是一个可用的UNIX内核。1.2.2 The Linux Kernel1991年芬兰赫尔辛基大学的学生林纳斯·托瓦尔兹Linus Torvalds受启发为他的Intel 80386电脑编写一个操作系统。因此托瓦尔兹开始着手创建一个高效、功能齐全的UNIX内核以运行在386上。然后在1991年10月5日托瓦尔兹请求其他程序员的帮助并在comp.os.minix Usenet新闻组中发布了现在广为引用的关于他内核0.02版本的公告。对支持的呼吁证明是有效的。其他程序员加入了托瓦兹Torvalds的Linux开发工作添加了各种功能例如改进的文件系统、网络支持、设备驱动程序和多处理器支持。到1994年3月开发者们能够发布版本1.0。Linux 1.2于1995年3月发布Linux 2.0于1996年6月发布Linux 2.2于1999年1月发布Linux 2.4于2001年1月发布。2.5开发内核的工作于2001年11月开始并导致了Linux 2.6在2003年12月发布。Linux 内核版本号在 Linux 1.0 发布之后内核开发人员采用了内核版本编号方案每个版本编号为 x.y.zx 表示主版本y 表示该主版本中的次要版本z 表示次要版本的修订次要改进和错误修复。Linux 发行版严格来说术语 Linux 仅指由 Linus Torvalds 和其他人开发的内核。然而Linux 这个术语通常被用来指内核以及其他各种软件工具和库这些软件共同构成了一个完整的操作系统。在Linux的早期阶段用户需要自己组装所有软件创建文件系统并将所有软件正确地放置和配置在该文件系统上。这需要相当多的时间和专业知识。因此出现了Linux发行商的市场他们创建了软件包发行版来自动化大部分安装过程创建文件系统并安装内核和其他所需的软件。然后就有了SUSE、Red Hat、Ubuntu等。1.3 Standardization到20世纪80年代后期可用的UNIX实现种类繁多但这也带来了弊端。一些UNIX实现基于BSD另一些基于System V还有一些则融合了两者的特性。此外每个商业供应商都在其实现中添加了额外的功能。结果是将软件和人员从一种UNIX实现迁移到另一种变得越来越困难。这种情况对C编程语言和UNIX系统的标准化形成了强烈压力应用程序需要更容易地从一个系统移植到另一个系统。1.3.1 The C Programming Language到1980年代早期C语言已经存在了十年并且在各种UNIX系统以及其他操作系统上得到了实现。由于C语言的某些功能在现有事实上的标准——Kernighan和Ritchie于1978年出版的《C程序设计语言》中——没有详细说明因此各个实现之间产生了一些小的差异。书中描述的较旧的C语法有时被称为传统C或KR C。此外1985年C语言的出现突显了可以在不破坏现有程序的前提下对C进行的一些改进和扩展尤其是函数原型、结构赋值、类型限定符const和volatile、枚举类型以及void关键字。这些因素促使了对 C 语言标准化的推动最终形成了C89 1989年或ISO C901990年不太常见并在 Kernighan 和 Ritchie 的《C 程序设计语言》第二版1988 年中有完整描述。接下来的标准有C991999年C112011年等。1.3.2 The First POSIX StandardsPOSIX可移植操作系统接口的缩写一词指的是在电气和电子工程师协会IEEE的主持下开发的一组标准特别是其可移植应用标准委员会PASChttp://www.pasc.org/。PASC 标准的目标是在源代码级别促进应用程序的可移植性。POSIX 这一名称由理查德·斯托曼Richard Stallman提出。最后的 X 出现是因为大多数 UNIX 变体的名称都以 X 结尾。对于我们的目的来说最有趣的 POSIX 标准是第一个 POSIX 标准称为 POSIX.1或更完整地称为 POSIX 1003.1以及随后发布的 POSIX.2 标准。对原始 POSIX.1 标准的一些扩展也很重要。IEEE POSIX 1003.1b 于 1993 年批准其中包含对基础 POSIX 标准的一系列实时扩展。IEEE POSIX 1003.1c 于 1995 年批准是 POSIX 线程的定义。1996 年发布了修订版 POSIX.1 标准核心文本保持不变但纳入了实时和线程扩展。IEEE POSIX 1003.1g定义了网络 API包括套接字。IEEE POSIX 1003.1d于 1999 年批准而 POSIX.1j 于 2000 年批准定义了对 POSIX 基础标准的其他实时扩展。POSIX.1b 实时扩展包括文件同步异步 I/O进程调度高精度时钟和定时器以及使用信号量、共享内存和消息队列进行的进程间通信。POSIX 前缀通常应用于这三种进程间通信方法以将它们与类似但较旧的 System V 信号量、共享内存和消息队列区分开来。FIPS 151-1 and FIPS 151-2FIPS 是联邦信息处理标准Federal Information Processing Standard的缩写是美国政府为其计算机系统采购指定的一套标准的名称。1989 年FIPS 151-1 发布。该标准基于 1988 年的 IEEE POSIX.1 标准和 ANSI C 标准草案。FIPS 151-1 与 POSIX.11988的主要区别在于FIPS 标准要求一些 POSIX.1 留作可选的功能。由于美国政府是计算机系统的主要采购方大多数计算机供应商都确保其 UNIX 系统符合 FIPS 151-1 版本的 POSIX.1 标准。1.3.3 X/Open Company and The Open GroupX/Open公司是由一组国际计算机供应商组成的一个联盟目的是采用和改编现有标准以制定一套全面、一致的开放系统标准。它发布了X/Open可移植性指南这是一系列基于POSIX标准的可移植性指南。1996年X/Open与开放软件基金会OSF合并成立了开放集团The Open Group。几乎所有参与UNIX系统的公司或组织现在都是开放集团的成员该集团继续开发API标准。OSF是20世纪80年代末UNIX之战期间成立的两个厂商联盟之一。OSF的成员包括Digital、IBM、HP、Apollo、Bull、Nixdorf和Siemens等公司。OSF的成立主要是为了应对ATTUNIX的发源公司与SunUNIX工作站市场最强大的玩家之间的商业联盟所带来的威胁。因此ATT、Sun以及其他公司成立了竞争的UNIX International联盟。1.3.4 SUSv3 and POSIX.1-2001自1999年起IEEE、开放组The Open Group和ISO/IEC联合技术委员会1在奥斯汀公共标准修订组CSRGhttp://www.opengroup.org/austin/进行了合作旨在修订和整合POSIX标准和单一UNIX规范。这导致POSIX 1003.1-2001的批准有时仅称为POSIX.1-2001于2001年12月正式批准随后被作为ISO标准批准ISO/IEC 9945:2002。POSIX 1003.1-2001取代了SUSv2、POSIX.1、POSIX.2以及许多其他早期的POSIX标准。该标准也被称为单一UNIX规范第3版我们通常将其称为SUSv3。总的来说SUSv3 中指定了 1742 个接口。相比之下POSIX.1-1990附 FIPS 151-2指定了 199 个接口而 POSIX.2-1992 指定了 130 个实用程序。SUSv3 可以通过 http://www.unix.org/version3/online.html 在线获取。经过 SUSv3 认证的 UNIX 实现可以称自己为 UNIX 03。POSIX conformance, XSI conformance, and the XSI extension从历史上看SUS以及XPG标准遵循相应的POSIX标准并被构建为POSIX的功能超集。除了规定额外的接口外SUS标准还强制实现许多在POSIX中被视为可选的接口和行为。这种区别在POSIX 1003.1-2001中以更微妙的方式得以保留该版本既是IEEE标准也是开放组技术标准即如前所述它是早期POSIX和SUS标准的整合。该文档定义了两个符合性级别POSIX 一致性这定义了符合标准的实现必须提供的接口基线。它允许实现提供其他可选接口。X/Open 系统接口 (XSI) 一致性要符合 XSI 标准一个实现必须满足 POSIX 一致性的所有要求并且必须提供一些对于 POSIX 一致性来说只是可选的接口和行为。一个实现必须达到这一一致性级别才能从开放组 (The Open Group) 获得 UNIX 03 品牌认证。为了符合 XSI 标准所需的额外接口和行为统称为 XSI 扩展。它们包括对线程、mmap() 和 munmap()、dlopen API、资源限制、伪终端、System V IPC、syslog API、poll() 和登录帐户等功能的支持。在后面的章节中当我们谈论 SUSv3 一致性时我们指的是 XSI 一致性。Unspecified and weakly specified在 SUSv3 中我们有时将接口称为“未指定”或“弱指定”。未指定接口是指在正式标准中根本没有定义的接口尽管在少数情况下会有背景说明或理由文本提到该接口。称接口为弱指定是简化的说法意思是尽管该接口包含在标准中但重要细节未被规定通常是因为委员会成员由于现有实现的差异未能达成一致。在使用未指定或弱指定的接口时将应用程序移植到其他 UNIX 实现时我们几乎无法获得保障。然而在少数情况下这样的接口在各个实现之间相当一致而当存在这种情况时我们通常会注明。LEGACY features有时我们注意到 SUSv3 将某个指定功能标记为遗留LEGACY。这个术语表示该功能是为了兼容旧应用程序而保留的但其局限性意味着在新应用程序中应避免使用。在许多情况下存在其他 API 可以提供同等的功能。1.3.5 SUSv4 and POSIX.1-20082008年奥斯汀小组完成了对合并的POSIX.1和单一UNIX规范的修订。与上一版本的标准一样它由基础规范和XSI扩展组成。我们将这次修订称为SUSv4。SUSv4的变化不如SUSv3那么广泛。1.3.6 UNIX Standards Timeline图 1-1 总结了前面各节中描述的各种标准之间的关系并按时间顺序排列这些标准。在该图中实线表示标准之间的直接衍生关系虚线箭头表示一种标准对另一标准产生影响、被纳入另一标准的一部分或只是参照另一标准的情况。图1-1略。简化为以下关系层级标准作用包含关系最底层ISO CC 语言本身 标准库stdio、stdlib、string…所有上层标准都必须兼容 C 标准中间层POSIX.1类 UNIX 系统调用接口fork、open、read、pipe、signal、pthread…POSIX ⊃ ISO C上层SUS (Single UNIX Specification)UNIX 官方完整规范比 POSIX 更多接口SUS ⊃ POSIX.1 SUS属于Open GroupPOSIX属于IEEE。POSIX 是基础接口标准SUS 是 POSIX 的超集与官方 UNIX 认证标准现代两者已高度融合SUS POSIX XSI 扩展。1.3.7 Implementation Standards除了由独立或多方团体制定的标准之外有时还会参考最终 BSD 版本4.4BSD和 ATT 的 System V Release 4SVR4定义的两种实现标准。后者的实现标准通过 ATT 发布的《System V 接口定义》SVID而正式确立。1989 年ATT 发布了 SVID 的第三版该版本定义了 UNIX 实现必须提供的接口以便能够称自己为 System V Release 4。SVID 可在线获取网址为 http://www.sco.com/developers/devspecs/由于某些系统调用和库函数的行为在 SVR4 和 BSD 之间有所不同许多 UNIX 实现提供兼容性库和条件编译功能以模拟在该特定实现中未作为基础使用的 UNIX 类型的行为见第 3.6.1 节。这减轻了将应用程序从另一个 UNIX 实现移植的负担。1.3.8 Linux, Standards, and the Linux Standard Base总体目标上Linux即内核、glibc 和工具的开发旨在符合各种 UNIX 标准尤其是 POSIX 和单一 UNIX 规范。然而在撰写本文时没有任何 Linux 发行版被开放组The Open Group正式标注为“UNIX”。问题在于时间和成本。每个厂商的发行版都需要经过一致性测试才能获得该标识并且每次新发行版发布时都需要重复此测试。尽管如此正是对各种标准的事实上的近似符合使得 Linux 在 UNIX 市场上取得了如此的成功。在大多数商业UNIX实现中同一家公司既开发又分发操作系统。而在Linux中情况不同实施与分发是分开的多个组织——包括商业和非商业机构——负责Linux的分发。由于存在多个 Linux 发行版并且内核开发者并不控制发行版的内容所以不存在所谓的“标准”商业 Linux。每个 Linux 发行版的内核通常基于某一特定时间点的主线即 Torvalds 内核快照并应用了若干补丁。这些补丁通常提供某些功能这些功能在不同程度上被认为具有商业价值因此能够在市场上提供竞争差异。在某些情况下这些补丁后来会被接受并合并到主线内核中。前面几点的结论是不同的 Linux 发行公司提供的系统之间存在大多是轻微的差异。Linux 标准基础LSB是一个旨在确保各种 Linux 发行版之间兼容性的努力。为此LSB (http://www.linux-foundation.org/en/LSB) 制定并推广一套 Linux 系统标准目的是确保二进制应用程序即编译后的程序可以在任何符合 LSB 的系统上运行。LSB 提倡的二进制可移植性与 POSIX 提倡的源代码可移植性形成对比。源代码可移植性意味着我们可以编写一个 C 程序然后在任何符合 POSIX 的系统上成功编译和运行它。二进制兼容性要求更高并且在不同的硬件平台之间通常不可行。它允许我们为特定硬件平台编译程序一次然后在该硬件平台上运行任何符合规范的实现。对于为 Linux 构建的独立软件供应商ISV应用程序来说二进制可移植性是商业可行性的一个基本要求。1.4 SummaryUNIX 系统最初于 1969 年由 Ken Thompson 在贝尔实验室ATT 的一部分在一台 Digital PDP-7 小型计算机上实现。该操作系统从早期的 MULTICS 系统中借鉴了许多思想也借用了其双关式的名字。到 1973 年UNIX 已迁移到 PDP-11 小型计算机上并用 C 语言重写C 语言是由 Dennis Ritchie 在贝尔实验室设计和实现的。由于法律限制不能出售 UNIXATT 改为以象征性费用将完整系统分发给各大学。这一分发包含了源代码并在大学中非常受欢迎因为它提供了一个廉价的操作系统其代码可以被计算机科学的学者和学生研究和修改。加利福尼亚大学伯克利分校在 UNIX 系统的发展中扮演了关键角色。在那里Ken Thompson 和一些研究生扩展了该操作系统。到 1979 年该大学已经制作出了自己的 UNIX 发行版 BSD。该发行版在学术界广泛应用并成为多个商业实现的基础。与此同时ATT 垄断的解体使公司能够销售 UNIX 系统。这导致了 UNIX 的另一个主要变体——System V 的出现它也成为了几种商业实现的基础。两条不同的路线促成了 (GNU/) Linux 的发展。其中一条是由理查德·斯托曼创建的 GNU 项目。到 1980 年代末GNU 项目已经产生了几乎完整的、可自由分发的 UNIX 实现。唯一缺少的部分是一个可运行的内核。1991 年受安德鲁·坦能鲍姆编写的 Minix 内核的启发林纳斯·托瓦兹为 Intel x86-32 架构开发了一个可运行的 UNIX 内核。托瓦兹邀请其他程序员加入他共同改进内核。许多程序员响应了这一邀请随着时间的推移Linux 得到了扩展并被移植到各种硬件架构上。到1980年代末由于UNIX和C实现的差异引发的可移植性问题造成了对标准化的强烈压力。C语言在1989年被标准化C89并在1999年发布了修订标准C99。首次尝试标准化操作系统接口产生了POSIX.1该标准在1988年被批准为IEEE标准并在1990年被批准为ISO标准。1990年代进一步的标准草案被制定包括各种版本的单一UNIX规范。2001年合并的POSIX 1003.1-2001和SUSv3标准被批准。该标准整合并扩展了早期的各种POSIX标准和单一UNIX规范的早期版本。2008年完成了一个范围较小的标准修订产生了合并的POSIX 1003.1-2008和SUSv4标准。与大多数商业 UNIX 实现不同Linux 将实现与发行分开。因此没有单一的“官方” Linux 发行版。每个 Linux 发行商提供的都是当前稳定内核的快照并应用了各种补丁。LSB 开发并推广一套 Linux 系统标准旨在确保二进制应用程序在不同 Linux 发行版之间的兼容性使得编译后的应用程序能够在运行相同硬件的任何符合 LSB 的系统上运行。1.5 Exercises本章并无练习这是我自己的问题。1-1. 如何判断我的Linux符合哪个标准运行以下程序#includestdio.h#includeunistd.hintmain(){printf(_POSIX_VERSION %ld\n,_POSIX_VERSION);printf(_XOPEN_VERSION %ld\n,_XOPEN_VERSION);return0;}输出为_POSIX_VERSION200809_XOPEN_VERSION700从这里可知SUS最新正式版是 SUSv4, 2018 EditionUNIX V7技术上对应 POSIX.1‑2017。这两个宏对应的正是最新版。之所以宏是 200809L而非2018是因为2017 不是全新标准只是 2008 的 “最终修正版”。_POSIX_VERSION 只在基础标准大改版时才更新后续的勘误、修正、整合版都不会改这个数字。解读1_POSIX_VERSION → POSIX 标准199009L → POSIX.1-1990老199506L → POSIX.1-1995200112L → POSIX.1-2001SUSv3200809L → POSIX.1-2008 / 2017SUSv4现代 Linux 默认2_XOPEN_VERSION → SUSUNIX 标准600 → SUSv3 (UNIX 03)700 → SUSv4 (UNIX V7)现代 Linux 几乎都是POSIX.1-2008 / 2017SUSv4。虽然没有任何Linux 做了 Open Group 的 SUS 官方认证但glibc 的设计目标是尽可能兼容SUSv4POSIX.1-2008。以上输出表明glibcGNU C 库在编译时默认暴露了 SUSv4UNIX V7级别的接口。也即做到了开发层面的接口兼容尽管不是系统层面的官方认证。2026年3月2日读完3月31日重读并修改

更多文章