
第3课自己写 systemd Service —— 掌握开机服务摘要本教程详细介绍了如何在 Raspberry Pi 上创建自定义 systemd 服务实现开机自动运行程序。内容包括systemd 基本概念、service 文件结构解析、Yocto 集成方法、recipe 编写要点以及完整的构建、部署和验证流程。通过 hello.service 示例展示了从编写服务文件到系统集成的完整实践过程。自己写一个 service让 Raspberry Pi 开机自动运行自己的程序。学习完成后你就会理解什么是 systemd什么是 serviceservice 文件长什么样Yocto 如何安装 serviceYocto 如何自动 enable service最终效果Pi 开机 ↓ systemd ↓ 启动 hello.service ↓ 执行 /usr/bin/hello这就是现代 Linux 的标准启动方式。所以要做两件事1.增加systemd serice 服务2.增加hello-systemd 服务一、什么是 systemd以前 Linux 使用init后来使用SysV init现在几乎所有 Linux 都使用systemd可以理解成systemd 所有程序几乎都是它启动。例如- network -ssh- dbus - bluetooth - nginx -docker- 自己的程序全部都是 systemd 管理。二、什么是 service例如SSH 服务 sshd.service网络 NetworkManager.service时间同步 systemd-timesyncd.service我们也可以写hello.service开机执行/usr/bin/hello三、service 文件在哪里一般放/lib/systemd/system/或者 /usr/lib/systemd/system/Yocto 使用变量${systemd_system_unitdir}例如${systemd_system_unitdir}/hello.service四、service 文件格式建立 hello.service内容[Unit]DescriptionHello Demo ServiceAfternetwork.target[Service]TypesimpleExecStart/usr/bin/helloRestartalways[Install]WantedBymulti-user.target这是最经典的 service。五、逐行解释[Unit]DescriptionHello Demo Service # 描述这个服务。AfterAfternetwork.target # 网络启动完成以后 再启动 hello 不是依赖只是启动顺序。[Service]真正运行程序。Typesimple最常见。simple意思ExecStart 启动以后 程序一直运行ExecStart真正执行ExecStart/usr/bin/hello # systemd 会执行/usr/bin/helloRestartRestartalways程序退出重新启动 非常适合 daemon。[Install]WantedBymulti-user.target意思进入正常多用户模式时启动。可以理解成开机以后自动启动六、把 service 放进 recipe目录hello-systemd/ ├── hello-systemd.bb ├── hello └── hello.servicehello.service[Unit]DescriptionHello Demo ServiceAfternetwork.target[Service]TypesimpleExecStart/usr/bin/helloRestartalways[Install]WantedBymulti-user.targethello脚本#!/bin/shwhiletruedoechoHello Systemdsleep5done七、Recipe – hello-systemd.bbSUMMARYHello systemd demoLICENSEMITLIC_FILES_CHKSUMfile://LICENSE;md5f4fa7fd56aac72279ad21a112915ca87inherit systemd SRC_URI\ file://hello \ file://hello.service \ file://LICENSES${WORKDIR}do_install(){install-d${D}${bindir}install-m0755${WORKDIR}/hello${D}${bindir}/helloinstall-d${D}${systemd_system_unitdir}install-m0644${WORKDIR}/hello.service\${D}${systemd_system_unitdir}/hello.service}SYSTEMD_SERVICE:${PN}hello.serviceSYSTEMD_AUTO_ENABLEenableFILES:${PN}\${bindir}/hello \${systemd_system_unitdir}/hello.service \ 八、重点解释 Recipeinherit systemd告诉 BitBake我要安装 systemd service。 它会引入处理 systemd 服务所需的类和打包逻辑。SYSTEMD_SERVICE:${PN}告诉 Yocto这个 package 的 service 是hello.service如果一个包有多个服务也可以写SYSTEMD_SERVICE:${PN} “hello.servicemonitor.service”SYSTEMD_AUTO_ENABLE “enable”构建镜像时systemctl enable hello.service会自动完成实际上是在 rootfs 中创建相应的符号链接因此系统首次启动时服务就是启用状态。如果改成SYSTEMD_AUTO_ENABLE “disable”则安装了 service 文件但不会自动启用。九、添加systemd usrmerge 特性推荐在 local.conf 中同时添加 usrmergevi ~/yocto/build-rpi2/conf/local.confbash修改为bitbake# # 切换到 systemd 作为 init 管理器# DISTRO_FEATURES:append systemd usrmergeVIRTUAL-RUNTIME_init_managersystemdVIRTUAL-RUNTIME_initscriptssystemd-compat-unitsDISTRO_FEATURES_BACKFILL_CONSIDEREDsysvinitVIRTUAL-RUNTIME_syslogsystemd-journaldbitbake core-image-minimal-ccleansstate# seemd clean tmp, so need long time to rebuildbitbake core-image-minimal十构建并加入镜像编译bitbake hello-systemd加入镜像IMAGE_INSTALL:append hello-systemd位置1core-image-minimal.bbappend最佳实践 ✅IMAGE_INSTALL:append network-config hello-script mypackage mypackage-config hello-systemd位置2local.conf快速测试位置3自定义 Image Recipe最灵活重新生成镜像bitbake core-image-minimal写入 SD 卡并启动 Raspberry Pi。十一、验证服务查看是否已启用systemctl is-enabled hello.service期望输出enabled查看状态systemctl status hello.service可能看到● hello.service Loaded: loaded Active: active(running)查看日志journalctl-uhello.service如果脚本每 5 秒输出一次 Hello Systemd日志中就会看到相应内容。May2918:48:29 raspberrypi2 systemd[1]: Started Hello Demo Service. May2918:48:29 raspberrypi2 hello[219]: Hello Systemd ├── hello-systemd │ ├── files │ │ ├── hello │ │ ├── hello.service │ │ └── LICENSE │ └── hello-systemd.bb十二、常见问题本课实验推荐为了真正掌握 systemd建议按下面顺序完成三个小实验1.基础服务编写 hello.service每 5 秒打印一条日志确认开机自动启动。2.故障恢复将脚本改为运行 10 秒后退出观察 Restartalways 是否自动拉起服务。3.启动顺序修改 After如 network.target结合 systemctl list-dependencies 和日志观察服务启动顺序。完成这三步后你不仅会知道如何在 Yocto 中安装和启用一个 systemd 服务还会理解 Linux 开机服务管理的基本工作方式。这也是后续开发网络服务、守护进程daemon和后台应用的基础。