Linux开机流程与系统服务:运行级别与systemd详解

📅 2026/7/14 1:33:09
Linux开机流程与系统服务:运行级别与systemd详解
Linux开机流程与系统服务运行级别与systemd详解按下电源键到看到登录界面中间发生了什么为什么有的程序开机自动启动有的不会systemctl命令到底在管什么搞懂开机流程和systemd你才能在嵌入式设备上做到开机即运行我的程序。一、Linux开机完整流程从按下电源到用户登录Linux经历了一个严谨的引导链┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ BIOS/UEFI │───→│ BootLoader│───→│ Kernel │───→│ systemd │ │ 硬件自检 │ │ (GRUB) │ │ 内核加载 │ │ (PID 1) │ └─────────────┘ └──────────┘ └──────────┘ └────┬────┘ │ ┌────────────────────────────────────┘ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 启动系统 │───→│ 启动用户 │───→│ 登录界面 │ │ 服务 │ │ 会话 │ │ (getty) │ └──────────┘ └──────────┘ └──────────┘1.1 BIOS/UEFI 阶段主板上固件负责硬件自检POST然后根据启动顺序设置从指定设备硬盘、U盘、网络读取引导程序。BIOS传统模式用MBR分区表16位实模式引导UEFI新模式用GPT分区表支持Secure Boot启动更快1.2 BootLoader阶段GRUBGRUBGRand Unified Bootloader是最常用的Linux引导程序。它的任务是加载Linux内核。# GRUB配置文件位置 /boot/grub/grub.cfg # 自动生成不要手动编辑 /etc/default/grub # 用户配置文件 # 修改后更新GRUB sudo update-grubGRUB界面中你可以选择内核版本、进入恢复模式、添加内核启动参数。1.3 内核加载阶段内核被加载到内存后解压内核镜像初始化硬件驱动挂载根文件系统rootfs启动第一个用户空间进程 ——systemdPID 1# 查看当前内核版本uname-r# 查看内核启动参数cat/proc/cmdline1.4 systemd阶段systemd作为PID 1进程负责读取配置启动各种系统服务挂载额外文件系统/home、/tmp等启动登录服务getty管理整个系统服务的生命周期二、运行级别Runlevel2.1 传统SysV运行级别在传统SysV init系统中Linux定义了7个运行级别运行级别含义说明0关机系统 halt1单用户模式仅root登录无网络用于维护2多用户无网络Debian系默认多用户3完整多用户服务器标准模式命令行界面4保留未定义可自定义5图形界面桌面环境6重启系统reboot2.2 systemd的target对应关系systemd用target替代了运行级别的概念但做了向后兼容传统运行级别systemd target说明0poweroff.target关机1rescue.target单用户/救援模式3multi-user.target多用户命令行5graphical.target多用户图形界面6reboot.target重启# 查看当前默认启动目标systemctl get-default# 输出graphical.target# 设置默认启动目标服务器通常设为命令行sudosystemctl set-default multi-user.target# 开机进命令行sudosystemctl set-default graphical.target# 开机进图形界面# 临时切换运行模式sudosystemctl isolate multi-user.target# 立即切到命令行sudosystemctl isolate graphical.target# 立即切到图形界面嵌入式场景开发板通常不需要图形界面设置multi-user.target可加快启动速度、节省内存。三、systemd详解3.1 systemd是什么systemd是现代LinuxUbuntu 15.04、CentOS 7的初始化系统和服务管理器。相比传统的SysV init串行启动服务systemd的核心优势是并行启动——多个服务同时初始化大幅加快开机速度。3.2 systemd的核心概念Unitsystemd管理的所有对象统称为Unit单元。常见的Unit类型Unit类型扩展名作用Service.service系统服务最常用Target.target一组Unit的集合类似运行级别Mount.mount文件系统挂载点Socket.socket进程间通信套接字Timer.timer定时任务替代cronDevice.device内核识别的设备Path.path文件路径触发器3.3 Unit文件位置/etc/systemd/system/ # 管理员自定义优先级最高 /run/systemd/system/ # 运行时创建 /usr/lib/systemd/system/ # 软件包安装的服务不要手动修改 /lib/systemd/system/ # 同上Ubuntu路径规则要修改系统自带的服务配置用systemctl edit创建覆盖文件而不是直接改原始文件。这样软件升级时不会丢失你的修改。四、systemctl命令全套详解4.1 服务管理# 启动服务sudosystemctl start nginx# 停止服务sudosystemctl stop nginx# 重启服务sudosystemctl restart nginx# 重新加载配置不中断服务sudosystemctl reload nginx# 查看服务状态systemctl status nginx# 查看服务是否在运行systemctl is-active nginx# 输出 active/inactive# 设置开机自启sudosystemctlenablenginx# 取消开机自启sudosystemctl disable nginx# 启动并设置开机自启常用组合sudosystemctlenable--nownginx# 停止并取消开机自启sudosystemctl disable--nownginx4.2 服务状态查看# 查看所有已激活的服务systemctl list-units--typeservice# 查看所有服务含未激活的systemctl list-units--typeservice--all# 查看所有开机自启的服务systemctl list-unit-files--typeservice--stateenabled# 查看服务启动失败的服务systemctl--failed4.3 日志管理systemd自带journalctl统一日志系统替代了传统的syslog# 查看所有日志journalctl# 查看本次启动的日志journalctl-b# 查看上一次启动的日志journalctl-b-1# 查看指定服务的日志journalctl-unginx# 实时追踪日志类似tail -fjournalctl-f# 查看最近1小时的日志journalctl--since1 hour ago# 查看指定优先级及以上的日志journalctl-perr# err/warning/info/debug...# 查看内核日志类似dmesgjournalctl-k五、自定义Service实战嵌入式开发中最常见的需求让我的程序开机自动运行。5.1 创建Service文件sudovim/etc/systemd/system/myapp.service[Unit] DescriptionMy Embedded Application Documentationhttps://myproject.com/docs Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userroot ExecStart/opt/myapp/bin/myapp --config /etc/myapp/config.yaml ExecStop/bin/kill -SIGTERM $MAINPID Restarton-failure RestartSec5 WorkingDirectory/opt/myapp EnvironmentAPP_HOME/opt/myapp EnvironmentLD_LIBRARY_PATH/opt/myapp/lib StandardOutputjournal StandardErrorjournal # 安全限制可选 NoNewPrivilegestrue ProtectSystemstrict ReadWritePaths/var/lib/myapp [Install] WantedBymulti-user.target5.2 各字段详解[Unit] 段字段说明Description服务描述After在哪些服务之后启动不强制等待Before在哪些服务之前启动Requires强依赖依赖服务失败本服务也失败Wants弱依赖依赖服务失败不影响本服务Conflicts冲突的服务不能同时运行[Service] 段字段说明Type服务类型见下方详解ExecStart启动命令ExecStop停止命令ExecReload重载命令Restart重启策略RestartSec重启间隔秒数User/Group运行身份WorkingDirectory工作目录Environment环境变量TimeoutStartSec启动超时时间Type详解类型说明适用场景simpleExecStart启动的进程就是主进程前台运行的程序forking进程会fork子进程然后退出子进程是主服务传统守护进程oneshot执行一次就完成初始化脚本notify服务就绪后通过sd_notify通知systemd需要精确控制就绪时机Restart策略值说明no不重启默认on-success正常退出时重启on-failure异常退出时重启on-abnormal被信号杀死或超时时重启always总是重启[Install] 段字段说明WantedBy被哪个target依赖enable时创建软链接到该targetRequiredBy被哪个target强依赖Alias服务别名5.3 启用和管理# 重新加载systemd配置每次修改service文件后必须执行sudosystemctl daemon-reload# 启动服务sudosystemctl start myapp# 设置开机自启sudosystemctlenablemyapp# 查看状态systemctl status myapp# 查看日志journalctl-umyapp-f# 修改配置后重启服务sudosystemctl restart myapp# 编辑服务文件推荐方式会创建override文件sudosystemctl edit myapp5.4 常见调试技巧# 服务启动失败查看详细错误systemctl status myapp journalctl-umyapp-n50--no-pager# 检查service文件语法systemd-analyze verify /etc/systemd/system/myapp.service# 查看启动耗时systemd-analyze# 查看各服务启动耗时找出启动慢的元凶systemd-analyze blame# 查看启动关键路径systemd-analyze critical-chain六、Timer定时任务systemd的Timer是cron的现代替代品优势在于精度更高、日志集成更好、可以依赖其他服务。6.1 创建Timer# /etc/systemd/system/backup.service [Unit] DescriptionBackup Service [Service] Typeoneshot ExecStart/opt/scripts/backup.sh# /etc/systemd/system/backup.timer [Unit] DescriptionRun backup daily [Timer] OnCalendardaily # 每天执行 # OnCalendar*-*-* 03:00:00 # 或指定时间每天凌晨3点 # OnBootSec5min # 开机5分钟后执行 # OnUnitActiveSec1h # 上次执行后1小时再执行 Persistenttrue # 错过的任务在下次启动时补执行 [Install] WantedBytimers.target# 启用timersudosystemctlenable--nowbackup.timer# 查看所有timersystemctl list-timers七、嵌入式设备开机优化在资源受限的嵌入式设备上启动速度往往很关键。# 1. 分析启动耗时systemd-analyze# Startup finished in 3.2s (kernel) 8.5s (userspace) 11.7s# 2. 找出最耗时的服务systemd-analyze blame|head-20# 3. 禁用不需要的服务示例sudosystemctl disable apt-daily.service apt-daily-upgrade.servicesudosystemctl disable motd-news.servicesudosystemctl disable fwupd.service# 4. 设置默认启动为命令行模式sudosystemctl set-default multi-user.target# 5. 跳过不必要的等待# 编辑 /etc/systemd/system.conf# DefaultTimeoutStartSec5s# DefaultTimeoutStopSec5s八、总结理解开机流程让你在系统出问题时知道从哪一步排查运行级别帮你控制系统的启动模式systemd是现代Linux服务管理的核心自定义service文件是嵌入式设备实现开机自启的标准方案。掌握systemctl和journalctl日常系统管理基本够用了。