Linux 系统启动到用户程序执行的理论与实际总结
阶段理论机制脚本实践开机 → 内核BIOS/UEFI → Bootloader → 内核初始化硬件上电 → Bootloader → 内核启动用户空间启动init启动脚本 → 系统服务/init或自定义 shell 脚本 → 调用启动程序模块加载内核模块用户程序封装启动:检查文件、配置 →$1 &$1系统调用加载 ELF →_startShell$1调用 execve → 程序_start→ ma
Linux 系统从开机到用户程序 main()
执行,理论上和实际应用中存在一定差异。下面将两者结合分析。
一、开机到内核初始化(Boot → init)
理论:
-
BIOS/UEFI
-
硬件自检(CPU、内存、外设)。
-
加载 Bootloader(如 GRUB)。
-
-
Bootloader
-
解析内核映像,加载到内存。
-
设置启动参数(kernel command line)。
-
跳转内核入口
start_kernel()
。
-
-
内核初始化
-
start_kernel()
初始化:-
内存管理(页表、堆栈、malloc 内核空间)
-
CPU、时钟、中断
-
调度器初始化
-
-
创建第一个用户空间进程
init
(PID=1)。
-
实际映射:
-
系统上电 → Bootloader → 内核。
-
内核完成初始化后,将控制交给
init
。 -
我的系统中,这个阶段由
/sbin/init
或自定义启动脚本负责。
二、init → 启动脚本 → 模块启动
理论:
-
init
是用户空间的第一个进程。 -
根据系统配置(SysVinit:
/etc/inittab
,Systemd: unit 文件)启动用户程序。 -
启动过程中可能加载内核模块(
insmod
→init_module()
)。
实际:
-
我的脚本中
init_module()
是用户空间的 程序启动封装,作用类似 init 脚本中启动服务。 -
功能:
-
检查程序是否存在 (
/usr/bin/$1
)。 -
检查配置文件 (
bootparam.sys
) 是否禁用。 -
将启动记录写入 watchdog 文件。
-
对特定程序进行特殊处理(如
srosuinet
加 ASAN,srosdropbear
指定端口)。 -
背景启动或前台启动。
-
启动间隔 200ms 防止资源冲突。
-
三、execve → main
理论:
-
execve()
是内核系统调用,用于加载用户程序:-
解析 ELF 文件,分配内存空间。
-
初始化栈和环境变量。
-
指令指针指向
_start
。
-
-
_start
由 C 运行时(CRT)初始化:-
设置
argc/argv
、环境变量。 -
调用
main()
。
-
-
用户程序真正开始执行。
实际:
-
我的脚本中:
$1 & # 或 $1
-
$1
是程序名,shell 会通过系统调用execve()
启动程序。 -
特殊程序可以附加参数或环境变量(如 ASAN)。
-
启动后程序进入自己的
main()
,执行业务逻辑。
-
四、模块管理与 Watchdog
-
理论上,内核模块通过
init_module()
加载到内核空间。 -
实际上,我的
init_module()
更像 用户空间模块管理器:-
WATCHDOG_EXEC_FILE
记录启动列表。 -
可用于 watchdog 监控或重启。
-
提供开关控制(通过
bootparam.sys
)。
-
五、结合总结
阶段 | 理论机制 | 脚本实践 |
---|---|---|
开机 → 内核 | BIOS/UEFI → Bootloader → 内核初始化 | 硬件上电 → Bootloader → 内核启动 |
用户空间启动 | init 启动脚本 → 系统服务 |
/init 或自定义 shell 脚本 → 调用 init_module() 启动程序 |
模块加载 | 内核模块 init_module() |
用户程序封装启动:检查文件、配置 → $1 & / $1 |
execve → main | 系统调用加载 ELF → _start → CRT → main |
Shell $1 调用 execve → 程序 _start → main |
监控与控制 | 内核模块管理 | Watchdog 文件 + 配置文件控制 |
关键理解:
-
理论上每个阶段都是操作系统控制的内核/用户空间机制。
-
实际系统中,我的 shell 脚本通过封装逻辑实现了“类似 init + 模块启动 + watchdog”功能。
-
$1 &
或$1
就是用户程序最终调用execve()
并进入main()
的入口。
更多推荐
所有评论(0)