三、Linux 系统演进史与底层架构笔记

📅 2026/7/28 10:14:34 👁️ 阅读次数 📝 编程学习
三、Linux 系统演进史与底层架构笔记

文章目录

    • 第一章:上古开荒与神兵自举(硬件、汇编与 C 语言)
    • 第二章:Unix 分裂与 GNU 反抗军
    • 🗺️ 核心架构图:Linux 系统层级与调用关系
    • 第三章:内核、驱动与硬件的“三角关系”
      • 1. 内核的“通用接口”与硬件的“私有方言”
      • 2. 驱动厂商的“投名状”:适配内核接口 (核心重点)
      • 3. 驱动其实就在内核空间里!
      • 4. 内核去哪找这些驱动?——发行版的功劳
    • ⚙️ 实战流程:`ls` 命令的执行链路
    • 第四章:为什么只有 Linux Kernel 不算完整系统?
    • 💡 终极对比:Linux 与 Windows 的交付模式差异
    • 📝 学习建议

第一章:上古开荒与神兵自举(硬件、汇编与 C 语言)

历史背景:计算机早期没有操作系统概念。开发者必须直接面对物理硬件。

  • 肉身开荒:第一代开发者手持《芯片硬件手册》,使用汇编指令(如MOV,INT)直接操作寄存器。就像操控单片机一样,往特定地址塞值,错一个 bit 系统就会崩溃。
  • 神兵锻造:贝尔实验室的丹尼斯·里奇发明了C 语言。它既保留了高级语言的逻辑结构(if,while),又允许通过指针直接操作内存,是编写操作系统的完美工具。
  • 自举神功 (Bootstrapping):先用汇编写出最基础的编译器,再用这个编译器去编译用 C 语言写的更强大的编译器(GCC)。从此,软件开发进入自动化时代。

第二章:Unix 分裂与 GNU 反抗军

历史转折Unix曾是业界标准,但被 AT&T 商业化垄断。为了打破封闭,理查德·斯托曼发起了GNU 计划

  • GNU 的困境:到 90 年代初,GNU 已经造好了所有外围工具(Bash, GCC, Glibc),唯独缺少一个核心的“心脏”(内核)。他们自己开发的 Hurd 内核进展缓慢。
  • 少年英雄:1991 年,芬兰大学生林纳斯·托瓦兹因为买不起 Unix,自己动手写了一个类 Unix 的内核——Linux Kernel
  • 天作之合:GNU 的工具链 + Linux 的内核 =完整的自由操作系统(GNU/Linux)。配合 GPL 开源协议,全球开发者共同维护,Linux 迅速壮大。

🗺️ 核心架构图:Linux 系统层级与调用关系

这张图展示了从用户输入到硬件执行的纯粹技术链路。注意观察glibc(系统库)作为中间层的关键作用:

硬件层 Hardware

Linux Kernel 内核层

系统软件层 System Software

调用标准函数

触发汇编指令 syscall

应用软件层 Application Software

浏览器/游戏/Office

Vim/文本编辑器

用户

Shell / Bash
命令解释器

glibc / 系统库
封装系统调用

Linux 内核 vmlinuz
进程/内存/文件管理

驱动程序
直接操控硬件

CPU

内存 RAM

I/O 设备
硬盘/键盘/显卡


第三章:内核、驱动与硬件的“三角关系”

你之前提到的“只有 Kernel 很难用”,以及“驱动厂商必须适配内核”,是理解现代操作系统的关键。

1. 内核的“通用接口”与硬件的“私有方言”

  • 内核的思维是通用的:内核只负责制定“国家标准”。比如内核定义了一个通用指令:“从硬盘读取第 100 个字节的数据”。内核不关心硬盘是怎么转的,它只要结果。
  • 硬件的思维是私有的:全世界的硬件厂商(希捷、三星、Intel、Realtek)都有自己的“方言”。希捷硬盘和三星 SSD 接收的电信号指令完全不同。

2. 驱动厂商的“投名状”:适配内核接口 (核心重点)

正如你所说,驱动必须受内核控制。硬件厂商在写驱动时,不能随心所欲,必须严格遵守 Linux 内核提供的API(应用程序接口)和 ABI(应用程序二进制接口)

  • 规矩:内核规定:“如果你想让我识别你的设备,你的驱动代码必须调用我的register_device()函数来注册,必须用我的kmalloc()来申请内存,必须按我的格式处理中断。”
  • 后果:如果厂商不遵守这些规矩,驱动代码根本无法编译通过;即使强行加载,也会因为违规操作内存导致内核崩溃(Kernel Panic)。

3. 驱动其实就在内核空间里!

在 Linux(宏内核架构)中,驱动程序并不是独立的第三方软件,而是运行在“内核空间”的

  • 权限上:驱动和内核核心代码享有同等的最高特权(Ring 0)。它们都能直接操作硬件。
  • 代码上:驱动代码通常被编译成.ko模块文件,在系统启动或插入设备时动态加载进内核的内存空间,成为内核的一部分。

4. 内核去哪找这些驱动?——发行版的功劳

内核不会自动去网上下载驱动。当你安装 Ubuntu 或 CentOS 时,发行版厂商已经帮你完成了以下工作

  1. 收集与适配:从各大硬件厂商、开源社区收集了成千上万个已经适配好内核接口的驱动源码。
  2. 编译打包:把这些驱动编译成.ko模块,并打包进安装镜像(ISO)中。
  3. 自动匹配:安装系统时,安装程序会扫描你的硬件 ID,然后从预置的驱动包里找出对应的驱动,加载到内核中。

驱动适配与加载流程图:

内核空间

Linux Kernel 提供的标准接口

硬件厂商/开发者

必须严格调用

规范与约束

编译生成

被控制

动态加载进入

物理硬件设备

编写驱动代码 C/汇编

内核 API/ABI 规范
如: 注册设备/申请内存/中断处理

编译后的驱动模块 .ko


⚙️ 实战流程:ls命令的执行链路

当你在终端输入ls时,底层发生了以下严格的调用序列:

硬件(CPU/硬盘/屏幕)驱动程序Linux Kernelglibc/系统库Shell/Bash用户硬件(CPU/硬盘/屏幕)驱动程序Linux Kernelglibc/系统库Shell/Bash用户1. 输入 "ls" 并回车2. 解析命令,调用 readdir() 等系统库函数3. 封装参数,触发系统调用(syscall)4. 权限验证与安全审查5. 调度已加载的驱动程序读取硬盘目录6. 发送特定电信号,物理读取数据7. 返回文件列表数据8. 汇报读取结果9. 通过系统调用返回数据10. 解析数据为字符串11. 调用 printf() 准备显示12. 再次触发系统调用请求输出13. 调度显卡驱动输出像素14. 屏幕显示文件列表15. 用户看到结果

第四章:为什么只有 Linux Kernel 不算完整系统?

  • 只有 Kernel:相当于只有一个“光杆司令”。它拥有最高权限,制定了严格的接口规范,但没有提供人类可直接使用的交互界面(Shell/glibc),也没有预置任何硬件驱动。使用者必须手写汇编与其沟通,且插上任何新硬件都无法识别。
  • 完整 Linux 系统Linux Kernel(负责资源管理、制定规范)+GNU 系统软件(glibc/Shell/编译器,负责提供人机交互接口)+预置驱动包(遵循内核规范,负责识别硬件)+应用软件(负责具体业务)。

💡 终极对比:Linux 与 Windows 的交付模式差异

这也是为什么我们平时使用的是 Ubuntu、CentOS 等“发行版”的原因:

Linux 交付模式 - 开源拼装

林纳斯

仅提供 Linux 内核及接口规范

GNU 社区

提供系统库/Shell/编译器

硬件厂商/开源社区

遵循内核规范编写驱动源码

发行版厂商
Ubuntu/CentOS等

将内核+工具+驱动+GUI整合打包

用户安装后使用

Windows 交付模式 - 闭源精装房

微软公司

统一打包所有组件
内核+GUI+驱动+工具

用户安装后直接使用


📝 学习建议

  1. 复习时:重点看第一张架构图,牢记glibc位于应用软件和内核之间;同时记住驱动是内核的“触手”,运行在内核空间,且必须遵循内核 API。
  2. 面试时:如果问到“驱动模型”或“系统调用”,请结合时序图和第三章内容,强调Shell 通过 glibc 转换系统调用,以及驱动厂商必须适配内核接口的机制。
  3. 编程时:时刻记住你在用户空间,不要尝试直接操作硬件寄存器,一切硬件交互都应通过系统库发起系统调用来完成。