方案一:检查当前使用的 init 系统
1. 确认 init 系统
bash
# 查看进程树
ps aux | head -20
# 查看 init 进程
ls -l /sbin/init
file /sbin/init
# 查看系统版本
cat /etc/os-release
uname -a
2. 常见嵌入式 init 系统
-
BusyBox init :使用
/etc/inittab -
SysV init :使用
/etc/init.d/和运行级别 -
OpenRC :使用
/etc/init.d/和/etc/runlevels/ -
runit :使用
/etc/service/ -
procd:OpenWRT 使用
3. 启动顺序
内核启动 → init进程 → /etc/inittab → 执行 ::sysinit: → /etc/init.d/rcS → /etc/rcS.d/S* 脚本
方案二:使用 BusyBox init(最常见)
1. 编辑 inittab 文件
bash
# 查看当前配置
cat /etc/inittab
# 编辑 inittab
vi /etc/inittab
2. 在 inittab 中添加应用启动
bash
# 在文件末尾添加(示例格式)
# ::[action]:[process]
# 系统启动时运行一次
::sysinit:/home/root/myapp --init
# 作为守护进程运行(崩溃自动重启)
::respawn:/home/root/myapp
# 或指定控制台
ttyPS0::respawn:/home/root/myapp
# 启动后延迟运行
::wait:/bin/sleep 5 && /home/root/myapp
3. 完整的 inittab 示例
bash
# /etc/inittab
::sysinit:/etc/init.d/rcS
# 启动 getty(串口登录)
ttyPS0::respawn:/sbin/getty -L ttyPS0 115200 vt100
# 启动您的应用程序
::respawn:/home/root/myapp --daemon
::respawn:/home/root/another_app
# 关机脚本
::shutdown:/etc/init.d/rcK
4. 重新加载 inittab
bash
# 方法1:重启系统
reboot
# 方法2:重新初始化(如果支持)
init q
# 或
kill -HUP 1
方案三:使用 SysV init 脚本
1. 创建 init.d 脚本
bash
# 创建启动脚本
sudo vi /etc/init.d/myapp
2. init.d 脚本模板
bash
#!/bin/sh
### BEGIN INIT INFO
# Provides: myapp
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My Zynq Application
# Description: My custom application on Zynq
### END INIT INFO
APP_NAME="myapp"
APP_PATH="/home/root/myapp"
PID_FILE="/var/run/${APP_NAME}.pid"
LOG_FILE="/var/log/${APP_NAME}.log"
case "$1" in
start)
echo "Starting $APP_NAME..."
start-stop-daemon -S -b -m -p $PID_FILE -x $APP_PATH \
-- --daemon >> $LOG_FILE 2>&1
echo "done."
;;
stop)
echo "Stopping $APP_NAME..."
start-stop-daemon -K -p $PID_FILE
rm -f $PID_FILE
echo "done."
;;
restart)
$0 stop
sleep 2
$0 start
;;
status)
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if kill -0 $PID 2>/dev/null; then
echo "$APP_NAME is running (PID: $PID)"
else
echo "$APP_NAME PID file exists but process not found"
fi
else
echo "$APP_NAME is not running"
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
3. 设置权限和启用
bash
# 添加执行权限
chmod +x /etc/init.d/myapp
# 创建符号链接到运行级别目录
# 查看可用运行级别
ls /etc/rc.d/
ls /etc/rc?.d/
# 通常使用 rc3.d 或 rc5.d
ln -s /etc/init.d/myapp /etc/rc3.d/S99myapp
ln -s /etc/init.d/myapp /etc/rc5.d/S99myapp
# 禁用(删除符号链接)
rm /etc/rc3.d/S99myapp
方案四:使用 rc.local(最简单)
1. 编辑 rc.local
bash
# 检查是否存在
ls -l /etc/rc.local
# 创建或编辑
vi /etc/rc.local
2. 添加启动命令
bash
#!/bin/sh
# rc.local - 开机启动脚本
# 等待系统准备就绪
sleep 5
# 启动应用程序(后台运行)
/home/root/myapp > /var/log/myapp.log 2>&1 &
# 启动更多应用
/home/root/another_app --daemon &
# 必须的退出语句
exit 0
3. 设置权限
bash
chmod +x /etc/rc.local
方案五:使用 BusyBox runit(如果有)
bash
# 检查是否安装 runit
which runsvdir
# 创建服务目录
mkdir -p /etc/sv/myapp
# 创建运行脚本
cat > /etc/sv/myapp/run << 'EOF'
#!/bin/sh
exec /home/root/myapp 2>&1
EOF
chmod +x /etc/sv/myapp/run
# 创建日志脚本(可选)
cat > /etc/sv/myapp/log/run << 'EOF'
#!/bin/sh
exec svlogd -tt /var/log/myapp
EOF
chmod +x /etc/sv/myapp/log/run
# 启用服务
ln -s /etc/sv/myapp /etc/service/
方案六:创建自定义启动脚本
1. 在 /etc/init.d 创建
bash
cat > /etc/init.d/S99myapp << 'EOF'
#!/bin/sh
# /etc/init.d/S99myapp
start() {
echo "Starting my application..."
# 等待网络
while ! ping -c1 google.com &>/dev/null; do
sleep 1
done
# 启动应用
/home/root/myapp &
echo $! > /var/run/myapp.pid
echo "done."
}
stop() {
echo "Stopping my application..."
kill $(cat /var/run/myapp.pid) 2>/dev/null
rm -f /var/run/myapp.pid
echo "done."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
EOF
chmod +x /etc/init.d/S99myapp
2. 在启动序列中调用
bash
# 在启动脚本中调用
echo "/etc/init.d/S99myapp start" >> /etc/init.d/rcS
方案七:使用 crontab @reboot
bash
# 编辑 root 的 crontab
crontab -e
# 添加开机启动
@reboot /home/root/myapp > /tmp/myapp.log 2>&1
@reboot sleep 10 && /home/root/another_app --daemon
最佳方案方法
1. 检查系统结构
bash
# 查看 init 系统
ls -la /sbin/init
ls -d /etc/*init*
ls /etc/
# 查看启动脚本
find /etc -name "*rc*" -type f
find /etc -name "*init*" -type d
# 检查进程1
cat /proc/1/comm
2.检查您的 Zynq 系统是否支持 SysV init
bash
# 查看是否存在 init.d 目录
ls -la /etc/init.d/
# 查看运行级别目录
ls -la /etc/rc.d/ # 或 ls -la /etc/rc?.d/
# 查看当前运行级别
runlevel
# 输出示例: N 5 (前一个运行级别为N,当前为5)
# 查看默认运行级别
cat /etc/inittab | grep initdefault
3.对于大多数 ZYNQ系统,按优先级推荐:
-
首选:
/etc/inittab- 最稳定,崩溃自动重启 -
备选:
/etc/init.d/脚本 - 功能完整 -
备选:
/etc/rc.local- 最简单 -
最后:crontab @reboot - 通用但依赖 cron