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触发内核加载器 → 原地替换为新程序运行

相关推荐
2301_809051142 小时前
Linux 网络编程 学习笔记
linux·网络·学习
wanhengidc2 小时前
服务器租用有何优点
运维·服务器·安全·web安全
坤昱2 小时前
cfs调度类深入解刨——最新内核细节分析2
linux·服务器·cfs·cfs调度·eevdf调度·eevdf·kernel 7.1
艾莉丝努力练剑2 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
海市公约2 小时前
Linux核心基础命令与权限管理实战指南
linux·运维·服务器·vim·权限管理·系统监控·命令行
eggcode3 小时前
【Qt学习】Linux(ARM架构)在线安装Qt6.x
linux·qt·学习·arm
wkd_0073 小时前
Ubuntu 22.04 Samba 连接故障排查记:从“用户名或密码错误”到 NTLM 版本不兼容
linux·运维·ubuntu
mixboot4 小时前
Linux 进程工作目录查看利器:pwdx 命令详解
linux·运维·服务器
旺仔来了5 小时前
不联网的Linux下部署python环境
linux·开发语言·python
之歆5 小时前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化