首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Yocto构建的linux上的后置脚本

在Yocto构建的linux上的后置脚本
EN

Stack Overflow用户
提问于 2016-11-04 21:04:26
回答 5查看 11.4K关注 0票数 5

我需要在Yocto构建的目标操作系统上运行一个脚本。

此脚本需要作为安装的一部分运行,因此必须只运行一次(无论是在整个OS安装之后还是在第一次启动时)。它不能在主机系统上运行,因为它依赖于仅存在于目标上的硬件IO。

另一个次要的约束是,rootfs是以只读方式挂载的,但我想可以避免这种情况,方法是让脚本重新装入rw,在执行之后再重新装入r或者类似于这些代码的内容。

任何帮助都是非常感谢的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-11-14 21:02:42

最后,我做了shibley写的东西。下面是一个详细的方法:

创建一个新层

将所需的图层放在您的其他层所在的位置。我的在stuff目录中,在build目录旁边。

创建以下文件/目录:

代码语言:javascript
复制
meta_mylayer
├── conf
│   └── layer.conf
└── recipes-core
    └── mylayer-initscript
        ├── initscript.bb
        └── files
            ├── initscript.service
            └── initscript.sh

meta_mylayer是新层的名称。

让我们在conf/layer.conf中定义层,并告诉它在哪里搜索菜谱:

代码语言:javascript
复制
BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "meta-mylayer"
BBFILE_PATTERN_meta-mylayer := "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-mylayer = "99"

菜谱由.bb文件的名称定义。该层只有一个菜谱,名为initscript。

initscript.bb包含食谱信息。下面的菜谱将添加initscript服务,并将实际安装脚本initscript.sh放到/usr/sbin/

代码语言:javascript
复制
SUMMARY = "Initial boot script"
DESCRIPTION = "Script to do any first boot init, started as a systemd service which removes itself once finished"
LICENSE = "CLOSED"
PR = "r3"

SRC_URI =  " \
    file://initscript.sh \
    file://initscript.service \
"

do_compile () {
}

do_install () {
    install -d ${D}/${sbindir}
    install -m 0755 ${WORKDIR}/initscript.sh ${D}/${sbindir}

    install -d ${D}${systemd_unitdir}/system/
    install -m 0644 ${WORKDIR}/initscript.service ${D}${systemd_unitdir}/system
}

NATIVE_SYSTEMD_SUPPORT = "1"
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE_${PN} = "initscript.service"

inherit allarch systemd

install -d将创建指定路径所需的任何目录,而install -m 0644将复制具有644权限的指定文件。${D}是目标目录,默认情况下它是${WORKDIR}/image

创建systemd服务定义

我将不详细介绍systemd的工作方式,而是粘贴服务定义:

代码语言:javascript
复制
[Unit]
Description=start initscript upon first boot

[Service]
Type=simple
ExecStart=/bin/sh -c 'sleep 5 ; /usr/sbin/initscript.sh'

请注意/usr/sbin/上的脚本位置--上面的do_install函数的最后一行将在那里复制脚本。

最后,我们的initscript.sh脚本本身:

代码语言:javascript
复制
#!/bin/sh

logger "starting initscript"

# do some work here. Mount rootfs as rw if needed.

logger "initscript work done"

#job done, remove it from systemd services
systemctl disable initscript.service

logger "initscript disabled"

注册层

我们需要注册我们的新层,这样才能让比特人知道它在那里。编辑build/conf/bblayers.conf文件并将以下行添加到BASELAYERS变量中:

代码语言:javascript
复制
  ${TOPDIR}/../stuff/meta-mylayer \

现在,比特面包识别了我们的图层,我们需要将我们的食谱添加到图像中。编辑build/conf/local.conf并将initscript配方添加到IMAGE_INSTALL_append变量中。下面是添加到python旁边时的样子。

代码语言:javascript
复制
IMAGE_INSTALL_append = " python initscript"

运行构建

像往常一样运行构建。例如:

代码语言:javascript
复制
bitbake angstrom-lxde-image

在您第一次安装构建和引导之后,您的initscript.sh将被执行。

票数 13
EN

Stack Overflow用户

发布于 2016-11-04 23:10:03

基本的方法是编写一个systemd服务。默认情况下,可以像yocto食谱系统配置中定义的那样启用该服务。当脚本/应用程序完成时,服务引发的脚本或应用程序将禁用服务--即。systemctl disable foo。因此,该服务将不会在以后的启动中运行。

正如您所提到的,rootfs需要安装为rw才能工作。

票数 2
EN

Stack Overflow用户

发布于 2017-12-22 00:34:58

谢谢这个帮了忙。我需要补充一下

[Install] WantedBy=multi-user.target

到initscript.service以使其正常工作

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40431674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档