08-Linux的分层与组装
Linux 的分层与组装——三种组装方式与启动流程 vs 注册机制
Linux 不是简单的「应用层 / service 层 / 基础设施层」三层,而是一个巨大的操作系统系统集合:内核内部是很多子系统,每个子系统内部又有大量组件。Linux 也没有一个类似
Server.cpp的「总组装文件」——它的组装分散在编译期组装、启动期初始化、运行时注册机制三种方式里。这一条线回答两个问题:① 一个超大型系统的分层与组装长什么样;② 启动流程(组装系统)与注册机制(运行时扩展)是两个完全不同的概念。
一、Linux 不是简单的三层
1 | Linux System |
Linux Kernel 不是一个简单的「基础设施层」,而是一个操作系统核心,由很多子系统组成。
Kernel 内部是很多子系统
1 | Kernel |
这正对应「复杂系统 → 子系统 → 组件」:Kernel → 多个子系统 → 每个子系统内部又有大量组件。
二、接口、库、框架、子系统在 Linux 里的位置
System Call 是核心接口
1 | Application → C Library → System Call → Kernel → VFS → 具体文件系统 → Driver → Disk |
1 | open("test.txt"); // → System Call → Kernel → VFS → 具体文件系统 → Driver → Disk |
System Call 是 Linux Kernel 对用户程序暴露的核心接口——「封装底层组件 → 对外提供接口」。
glibc 是用户态基础库
1 | Application → glibc → System Call → Linux Kernel |
Linux 的「框架」在哪里?
Kernel 内部有很多框架机制:
1 | Device Driver Framework:Kernel Framework → Driver(驱动不用从零解决设备生命周期/设备模型) |
网络是完整的内核子系统
1 | Application → Socket API → Network Stack(TCP/UDP/IP)→ Routing → Netfilter → Network Driver → NIC |
文件系统也是完整子系统
1 | VFS:File / Directory / Inode / Dentry / File Operations |
1 | open()/read()/write() → 用户态接口/系统调用接口 |
「接口、库、框架、子系统」不是互斥的目录层级,而是描述软件不同维度的概念。 比如 Linux 的 VFS 既是文件系统子系统的一部分,又提供统一接口,并且内部具有框架性质——大型系统实际上同时存在「层、子系统、组件、接口、框架」几种结构。
三、内核的组装:不是一个 Server.cpp
Linux 内核并不存在一个类似 Server.cpp 的「总组装文件」,它的组装分散在内核启动流程 + 初始化机制 + 构建系统 + 各子系统注册机制中。可以分成三种「组装」。
1. 编译期组装
1 | kernel/ mm/ fs/ net/ drivers/ ipc/ security/ |
把各个子系统的代码组件组装成一个内核程序。
2. 启动期组装(初始化)
内核启动后执行初始化函数:
1 | kernel boot → 初始化内存 → 初始化调度器 → 初始化 VFS |
Linux 有一套初始化机制(subsys_initcall / device_initcall / fs_initcall / module_init),子系统可以注册自己的初始化函数。
3. 注册机制组装(运行时扩展)
网络驱动不是 main() { NetworkDriver driver1; ... },而是:
1 | Network Core ↑ 注册 ↑ Network Driver |
Linux 大量使用 「子系统提供注册机制 → 具体组件注册进去」 来完成组装。
组装总图
1 | Linux Kernel |
「如果服务器是框架,就应该有一个 Server.cpp 把子系统组装起来」在 Linux 内核里仍然成立,只不过 Linux 太大,这个「Server.cpp」被拆成了启动框架、初始化机制、注册机制和构建系统,而不是一个文件。 Linux Kernel 本身就是一个「组装好的大型系统」;它的组装代码不是集中式的,而是分布式的。
四、启动流程 vs 注册机制(两个完全不同的概念)
1. 启动流程:组装系统
1 | start_kernel() → 初始化各个核心子系统(memory / scheduler / VFS / network / device ...)→ 进入正常运行 |
代码表现就是各种 xxx_init();——「初始化」实际上就是把已经编译进来的各个子系统建立起来,并建立它们之间运行所需要的关系。调度器(Scheduler:Task + Run Queue + Scheduler Class + Timer)就是一个典型的内核子系统,它不是简单「调用一个函数」,而是建立一个持续运行的系统机制。
2. 注册机制:运行时扩展
1 | VFS → register_filesystem() → ext4 |
它解决的是:系统运行以后,还能不能把新的组件接入已有子系统。
3. 这也解释了 Linux 模块(.ko)
1 | Linux Kernel 运行中 → 加载 xxx.ko → module_init() → driver_register() → 驱动加入 Kernel |
不是重新「组装整个 Linux」,而是:已有系统 + 新组件 → 注册 → 扩展系统。
1 | 软件系统 |
「子系统由组件组成,组装组件成框架,封装组件成接口」现在又多了一层:启动流程负责组装系统,注册机制负责扩展系统。 这已经比单纯讨论「目录怎么分层」更接近大型软件真正的组织方式。
五、这一条线的位置
1 | 拆解与组织(主题): |
本线与 04(ECS 与注册机制)的关系:ECS 的「注册机制」和 Linux 的「注册机制」是同一个概念在不同领域的实例——框架/内核把「组装权」下放,组件运行中自己注册进去。启动流程则是另一条:初始化、建立关系、进入运行。
收束
1 | Linux = 操作系统系统集合: |
Linux 的分层与组装 = 一个超大型系统的组织方式:三层不是全部,内核是子系统集合;组装不是集中式的 Server.cpp,而是编译期 + 启动期 + 运行时注册三种方式的组合;启动流程组装系统,注册机制扩展系统。
