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

相关推荐
Fcy6482 小时前
Linux下 进程控制(二) —— 进程程序替换
linux·运维·服务器
浮尘笔记2 小时前
Java Snowy 框架生产环境安全部署全流程(服务器篇)
java·运维·服务器·开发语言·后端
web守墓人2 小时前
【linux】Mubuntu v1.0.10更新日志
linux·运维·服务器
不怕犯错,就怕不做2 小时前
(Hisilicon)笔试题:嵌入式Linux C语言GPIO中断与按键消抖(转载)
linux·驱动开发·嵌入式硬件
我科绝伦(Huanhuan Zhou)2 小时前
Oracle BBED 工具部署全流程:Linux 64位环境实操指南
linux·数据库·oracle
ONLYOFFICE2 小时前
11款Linux PDF编辑工具横评|开源、免费为主
linux·pdf·onlyoffice
.小小陈.2 小时前
深度拆解 Linux 进程间通信(IPC):从管道到 System V 全链路详解
linux·服务器·网络·学习
落羽的落羽2 小时前
【Linux系统】深入线程:多线程的互斥与同步原理,封装实现两种生产者消费者模型
java·linux·运维·服务器·c++·人工智能·python
l1o3v1e4ding2 小时前
排查linux CentOS7.6的mysql(5.7.27)内存泄漏因OOM被系统kill的问题
linux·mysql·adb