作者:Terry Ni,AMD工程师;来源:AMD开发者社区
在petalinux系统中,System V 和 SystemD是执行初始化和管理系统服务的不同初始化系统。它们的主要区别在于其体系结构和功能:
System V Init (SysV Init)
System V Init 是传统的初始化系统,已经存在很长时间,通常以脚本的形式存在,通常位于 /etc/init.d/ 目录中。以下是一个示例 SysV 启动脚本的基本结构
#!/bin/sh
### BEGIN INIT INFO
# Provides: my_service
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My custom service
# Description: My custom service description
### END INIT INFO
# Your service startup commands here
case "$1" in
start)
echo "Starting my service"
# Add your startup command here
;;
stop)
echo "Stopping my service"
# Add your stop command here
;;
restart)
echo "Restarting my service"
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
SysV Init 使用脚本来启动和停止系统服务,每个服务都有一个启动脚本,可以在启动和关闭时执行特定的命令序列。
SysV Init 的配置相对较复杂,因为需要手动创建和管理启动脚本,以及通过运行级别(runlevel)来控制服务的启动和停止。其命令如下:
sudo service my_service start
sudo service my_service stop
sudo service my_service restart
如果要修改服务的运行级别,可以修改/etc/inittab 文件来查看可用的运行级别以及它们的描述。在文件中,你会看到类似以下的行:
id:3:initdefault:
这表示默认运行级别是 3。你可以查找其他类似行来查看其他可用的运行级别。你还可以使用 update-rc.d 命令来管理初始化脚本的启动级别。例如,要将 my_service 添加到运行级别 3 中,可以执行:
sudo update-rc.d my_service defaults
SystemD
SystemD 是一个现代的初始化系统,在2018.3版本之后,通常使用SystemD来代替原有的SystemV方式了。它引入了一种更高级的方式来管理系统服务。它以守护进程的形式运行,通常由 PID 1 启动。
SystemD 使用单元(unit)来描述和管理服务,这些单元可以是服务单元、目标单元、设备单元等。每个单元都有一个配置文件,通常位于 /etc/systemd/system/ 目录中。例如:
[Unit]
Description=Service Description
After=dependency1.target dependency2.target
Requires=dependency1.target dependency2.target
[Service]
Type=simple
ExecStart=/path/to/your/command arg1 arg2
WorkingDirectory=/path/to/working/directory
User=service_user
Group=service_group
Restart=always
RestartSec=5
Environment=VAR1=foo VAR2=bar
[Install]
WantedBy=multi-user.target
SystemD 支持并行启动和停止服务,提供更好的性能和并发性,同时还具有更丰富的功能,如自动重启、依赖关系管理等。
SystemD 管理运行级别(runlevel)的概念已被废弃,而由 "targets" 来代替,使系统的状态切换更加灵活和简单。不同的 target 表示系统的不同状态,例如多用户图形模式、单用户模式、网络服务启动等。每个 target 包含了一组单元(units)的信息,这些单元是系统服务和其他配置项。当你切换到特定的 target 时,SystemD 将启动或停止与该 target 相关的单元。例如上面例子中,这个需要执行service unit就是放在了multi-user这个target下。
SystemD targets 可以通过 "target units" 来定义,这些 units 通常存储在 /usr/lib/systemd/system/ 目录或 /etc/systemd/system/ 目录中。你可以使用 systemctl 命令切换到不同的 target。例如,要切换到多用户图形模式,可以运行:
sudo systemctl isolate graphical.target
总结&DEMO
在 PetaLinux 中,你可以选择使用 System V Init 或 SystemD 作为初始化系统,具体取决于你的项目需求和偏好。SystemD 通常被认为是更现代和功能更强大的选择,但在某些情况下,可能需要使用 System V Init,特别是当你需要与现有的脚本或遗留系统兼容时。
在petalinux tool工具中,用户可以通过以下几步轻松实现
1. 使用如下命令,创建一个应用框架
petalinux-create -t apps --template install -n myapp-init --enable
2. 然后在这个应用框架下创建一个service unit。例如:
vi
[Unit]
Description=myapp-init
[Service]
ExecStart=/usr/bin/myapp-init
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target
3. 接下来就是修改bb文件(
2022.1之后的版本如下,其中SRC_URI中必须包含service unit以及能直接运行的应用或脚本程序,在示例中即是myapp-init
#this file is the myapp-init recipe.
SUMMARY = "Simple myapp-init application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://myapp-init \
file://myapp-init.service \
"
S = "${WORKDIR}"
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
inherit update-rc.d systemd
INITSCRIPT_NAME = "myapp-init"
INITSCRIPT_PARAMS = "start 99 S ."
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE:${PN} = "myapp-init.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"
do_install() {
if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'true', 'false', d)}; then
install -d ${D}${sysconfdir}/init.d/
install -m 0755 ${WORKDIR}/myapp-init ${D}${sysconfdir}/init.d/
fi
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/myapp-init ${D}${bindir}/
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/myapp-init.service ${D}${systemd_system_unitdir}
}
FILES:${PN} += "${@bb.utils.contains('DISTRO_FEATURES','sysvinit','${sysconfdir}/*', '', d)}"
2021.2以及之前的版本如下:
#this file is the myapp-init recipe.
#
SUMMARY = "Simple myapp-init application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://myapp-init \
"
S = "${WORKDIR}"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
inherit update-rc.d
INITSCRIPT_NAME = "myapp-init"
INITSCRIPT_PARAMS = "start 99 S ."
do_install() {
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${S}/myapp-init ${D}${sysconfdir}/init.d/myapp-init
}
FILES_${PN} += "${sysconfdir}/*"
4. 执行petalinux-build