2016-11-04 24 views
1

Yoctoが構築したターゲットOSでスクリプトを実行する必要があります。Yocto-built Linuxのインストール後のスクリプト

このスクリプトはインストールの一部として実行する必要があるため、OSのインストール後または最初の起動時に一度だけ実行する必要があります。ターゲット上にのみ存在するハードウェアIOに依存するため、ホストシステム上で実行することはできません。

rootfsが読み込み専用でマウントされているという制約がありますが、スクリプトをrwとして再マウントして、実行後や何らかの行に沿って再度マウントすることで回避できます。

何か助けていただければ幸いです。

答えて

4

shibleyが書いたことをやってしまった。ここでは詳細なHOWTOです:

は、新しい層

を作成し、あなたの他の層がどこにいても所望の層を入れてください。鉱山はstuffディレクトリにあり、ビルドディレクトリの隣にあります。

次のファイル/ディレクトリを作成します。

meta_mylayer 
├── conf 
│   └── layer.conf 
└── recipes-core 
    └── mylayer-initscript 
     ├── initscript.bb 
     └── files 
      ├── initscript.service 
      └── initscript.sh 

meta_mylayerは、あなたの新しい層の名前です。

のはconf/layer.confに層を定義し、どこのレシピを検索するためにそれを教えてみましょう:

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というレシピが1つしかありません。

initscript.bbにレシピ情報が含まれています。以下のレシピはinstall -m 0644は644人の権限で指定されたファイルをコピーしますが、指定したパスに必要な任意のディレクトリを作成します/usr/sbin/

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に、私たちのinitスクリプトのサービスを追加し、実際には、スクリプト、initscript.shをインストール置きます。${D}がsystemdにサービス定義

を作成し、それは${WORKDIR}/image

のデフォルトで、先のディレクトリである私はどのようにsystemd作品についてはあまり詳細には触れませんが、むしろサービス定義を貼り付けます:

[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スクリプト自体:

#!/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" 

それはありますbitbake知っているように、私たちは、私たちの新しいレイヤーを登録する必要が層

を登録します。 編集build/conf/bblayers.confファイルとBASELAYERS変数に次の行を追加します。

${TOPDIR}/../stuff/meta-mylayer \ 

今bitbakeが私たちの層を認識していることを、我々は、画像への私たちのレシピを追加する必要があります。 build/conf/local.confを編集し、initscriptレシピをIMAGE_INSTALL_append変数に追加します。 Pythonの次に追加されたときのように見えます。

IMAGE_INSTALL_append = " python initscript" 

ビルド

実行あなたが通常行うようにビルドを実行します。例:はじめてのビルドと起動をインストールした後

bitbake angstrom-lxde-image 

は、あなたのinitscript.shが実行されます。

+0

私にとっては機能しません。ファイルは転送されますが、サービスは転送されます起動時には実行されません。私は開始オプションで手動でそれを実行することができます。 –

+0

自動起動に手動で追加することを試みてください(systemctl enable foo)。/etc/systemd/systemの下にサービスファイルを用意するだけで十分です。 – Igor

1

基本的なアプローチは、systemdサービスを作成することです。このサービスは、yoctoレシピのシステム構成で定義されているように、デフォルトで有効にすることができます。サービスによって呼び出されるスクリプトまたはアプリケーションは、スクリプト/アプリケーションが完了したときにサービスを無効にします。 systemctl disable foo。したがって、このサービスは将来の起動時には実行されません。

あなたが言及したように、rootfsはこれを動作させるにはrwとしてマウントする必要があります。

0

単純な解決策は、パッケージのpost/installスクリプトを使用して、rootfs時に実行を停止することです($ Dが設定されていると終了します)。これは最初の起動時に実行されます。はい、スクリプトはルートファイルを再マウントする必要があります。

+0

作業を取得するためにinitscript.serviceに

[Install] WantedBy=multi-user.target

を追加する必要がありました。あなたはもっと詳しく説明できますか?私はそのbbappendのdo_install_appendスクリプトを使って既存のレシピを.bbappendしてみましたが、** host **システム上で上記のスクリプトを実行しようとしましたが、これは私の必要としていません。 – Igor

+0

http://www.yoctoproject.org/docs/2.2/dev-manual/dev-manual.html#new-recipe-post-installation-scripts –

0

ありがとう、これが助けになりました。私はそれがこれは面白そう

関連する問題