Linux 开机 + 进程创建 + fork + exec + 加载器

文章目录

  • 一、计算机上电最源头(还没操作系统)
  • 二、Linux 内核初始化阶段
  • 三、Linux 后续所有进程统一创建规则
  • 四、加载器理解
  • 五、完整全局流程串联

**一、**计算机上电最源头(还没操作系统)

1. 电脑通电,硬件固化的 BIOS/UEFI 先运行

2. BIOS/UEFI 本质就是硬件级加载器

3. 它把硬盘上的 Linux 内核镜像 读取、加载到内存

4. CPU 跳转执行内核代码,操作系统正式开始启动

二、Linux 内核初始化阶段

1. 内核自己初始化:内存管理、进程调度、驱动、文件系统、网络等

2. 内核不依靠 fork,手动在内核态创建出系统第一个用户态进程: init / systemd

3. 内核自己调用内核内部的加载器逻辑,给这个进程载入程序、环境、栈结构

4. 这个进程是所有用户进程的祖先,整个系统进程树从它开始衍生

唯一特例:第一个用户进程 是内核直接创建+加载,没有经历 fork

三、Linux 后续所有进程统一创建规则

除了第一个始祖进程,系统进程、后台服务、终端、命令、自己写的程序、子进程......

全世界所有后续进程,套路永远固定:先 fork ,再 exec

1. 第一步:调用 fork

核心作用:单纯创建一个全新的子进程

分配全新 PID

复制父进程的 PCB 进程描述符

复制/共享虚拟地址空间、页表

生成一个独立的进程结构体,操作系统调度队列里多了一个进程

⚠️ 关键:

fork 结束这一刻:

子进程只是父进程的复刻品,代码、数据、程序和父进程一模一样,还没有新程序。

只是多了一个「进程壳子」,没有换新内容。

2. 第二步:子进程立刻调用exec系列函数然后该函数内部进行execve 系统调用

(1).execve 是内核自带的一段加载器代码,它绝对不创建新进程

(2). 就在当前这个刚刚 fork 出来的子进程内部原地操作:

释放、清空自己原来从父进程复制来的:代码段、数据段、BSS、堆、共享库

从磁盘读取新的 ELF 可执行文件

解析程序头部,把代码段、数据段映射到当前进程虚拟地址空间

清零 BSS 段

重新构建用户态栈,把命令行参数、环境变量拷贝进去

找到程序入口 _start

跳转过去,开始执行新程序

fork:只负责「生孩子」,造出独立进程、PID、壳子

exec内核加载器:只负责「换脑子」,原地把这个进程里面的旧程序扔掉,重装新程序,不

生新进程

四、加载器理解

1.内核加载器(exec)负责范围

(1).销毁进程旧的整片地址空间:旧代码、数据、堆、共享库、旧ld全部清空。

(2).解析ELF文件,映射程序自身代码段、数据段、BSS段到内存。

(3). 重建全新用户栈,完成命令行参数、环境变量的拷贝与传递,完成程序代码和数据的加载

(由内核完成,和ld无关)。

(4). 区分静态、动态链接程序,动态链接场景下负责加载ld-linux.so,并把执行权转交ld。

2.动态链接:内核加载器 + ld 分工

(1). ld-linux.so 是独立用户态程序,不属于操作系统内核。

(2).ld 只负责两件事:加载所有依赖的.so动态库、完成符号解析与运行时重定位。

(3). 动态链接完整流程:

exec内核加载器布置程序主体+参数环境+拉起ld → ld完成库加载和重定位 → ld跳转至程

序 _start ,用户代码开始运行。

3.静态链接执行流程

(1). 编译阶段已将库代码和程序代码合并,无需依赖外部动态库,不需要ld参与。

(2). 内核加载器完成内存映射、栈构建、参数环境传递后,直接跳转 _start 执行用户代码。

4.程序替换的本质:

调用exec做程序替换时,会彻底清空进程原有全部内存环境,包括旧程序、数据、动态库、

旧ld,再根据新程序类型,重新搭建全新的地址空间与运行环境。

5.为什么说每个进程最开始都是加载器

(1).进程fork诞生后,在执行业务代码前,必须先走加载流程。

(2).动态链接进程:内核加载器 → ld动态链接器 → 用户代码

(3).静态链接进程:内核加载器 → 用户代码

(4).本质:进程启动最先执行的是加载逻辑,而非自身业务代码,因此概括为每个进程最开始

都是加载器。

6.三种加载器最终区别

(1).BIOS/UEFI:硬件固件级小程序,负责加载操作系统内核。

(2).内核加载器(exec内部):内核代码一部分,负责程序替换、程序主体加载、参数环境

传 递、拉起ld。

(3).ld动态链接器:独立用户态程序,只负责依赖库加载和符号重定位。

7.总结

fork负责创建新进程容器,exec内核加载器负责替换程序与搭建运行基础环境,ld只负责动

态库与重定位,所有进程启动都必先经过加载阶段。

五、完整全局流程串联

上电 → 硬件BIOS/UEFI加载器 → 加载Linux内核 →

内核初始化 → 内核直接创建第一个用户进程(无fork) →

此后所有进程:

父进程fork生成子进程容器 → 子进程exec触发内核加载器 → 原地替换为新程序运行

相关推荐
milo.qu4 小时前
RockyLinux9.7 docker部署Jisti Meet
linux·docker·容器
GanGanGanGan_4 小时前
CentOS 7.9 glibc 2.17 源码编译升级到 glibc 2.31
linux·运维·centos·glibc
charlie1145141914 小时前
嵌入式Linux驱动开发——class 和 device 模型 - 自动创建设备节点的幕后机制
linux·运维·驱动开发
杨云龙UP6 小时前
SQL Server2022部署:Windows Server 2016下安装、SSMS配置、备份还原与1433端口放通全流程_20260508
运维·服务器·数据库·sql·sqlserver·2022
枳实-叶6 小时前
【Linux驱动开发】第四天:dmesg日志全解+驱动加载失败极速排查
linux·运维·驱动开发
wdfk_prog7 小时前
正常关闭虚拟机时,不要点“关机”,而要点“关闭客户机”
linux·c语言·网络·ide·vscode
fish_xk8 小时前
Linux开方工具
linux·运维·服务器
m0_738120729 小时前
应急响应(重点)——记一次某公司流量应急溯源分析(附带下载链接)
服务器·前端·数据库·安全·web安全·网络安全
中科三方10 小时前
输入域名后无法访问?教你快速区分域名解析问题与服务器问题
运维·服务器
用户23678298016810 小时前
Linux find 命令深度解析:从递归遍历到性能优化的完整实现
linux