<dd id="xos4y"><noscript id="xos4y"></noscript></dd>

    <ol id="xos4y"><code id="xos4y"><address id="xos4y"></address></code></ol>

    加入星計劃,您可以享受以下權益:

    • 創作內容快速變現
    • 行業影響力擴散
    • 作品版權保護
    • 300W+ 專業用戶
    • 1.5W+ 優質創作者
    • 5000+ 長期合作伙伴
    立即加入
    • 正文
      • 一、如何設置開機啟動某個程序?
      • 二、init.rc詳解
    • 推薦器件
    • 相關推薦
    • 電子產業圖譜
    申請入駐 產業圖譜

    安卓如何設置開機自動啟動某個程序?ramdisk + init.rc給你搞定

    2023/09/06
    5801
    閱讀需 19 分鐘
    加入交流群
    掃碼加入
    獲取工程師必備禮包
    參與熱點資訊討論

    一、如何設置開機啟動某個程序?

    1.需求描述

    最近有個項目需要在Android開機啟動之后,自動執行一個C語言編寫的程序:pengd

    該程序運行時需要修改網絡ip地址及其他網絡操作,所以需要root權限

    根據需求描述,我們需要做一下操作:

    pengd 預置到Android中的某個路徑下,比如放在 /sbin/pengd ;

    然后修改init.rc文件,實現開機后自動運行我們的程序pengd

    本次項目用到的安卓設備的init.rc和sbin下的文件重啟后會恢復默認,主要是安卓部分目錄是基于ramdisk,因此我們需要重新制作ramdisk.img,將前面2個步驟的操作同步到到ramdisk.img,然后再重新燒錄設備對應分區

    2.移植步驟

    1)解壓縮ramdisk.img

    假定廠家提供文件名為:ramdisk_new

    peng@ubuntu:~/work/ramdisk$?mv?ramdisk_new.img?ramdisk_new.img.gz
    peng@ubuntu:~/work/ramdisk$?gunzip?ramdisk_new.img.gz?
    peng@ubuntu:~/work/ramdisk$?cpio?-i?-F?ramdisk_new.img?
    5385?blocks
    

    2)修改init.rc、

    修改init.rc文件,如下:

    service?pengd?/sbin/pengd
    ????seclabel?u:r:pengd:s0
    ????user?root
    ????group?root
    ????disable
    ????oneshot
    
    on?property:sys.boot_completed=1
    ????start?pengd
    ????
    

    注意rc文件最后一定要有空行,否則編譯報錯!

    init.rc語法見第二章
    該配置文件并不是唯一寫法,具體要參考實際廠家提供的sdk中的ramdisk

    3) 拷貝程序pengd

    直接拷貝pengd到

    ?/home/peng/work/ramdisk/sbin
    

    也可以是其他bin目錄

    4)重新壓縮ramdisk

    peng@ubuntu:~/work/ramdisk$?rm?ramdisk_new.img??第一次
    
    peng@ubuntu:~/work/ramdisk$?find?.?|?cpio?-o?-H?newc?>?../ramdisk.img.unzip
    peng@ubuntu:~/work/ramdisk$?cd?..
    peng@ubuntu:~/work$?gzip?-c?./ramdisk.img.unzip?>?./ramdisk.img.gz
    peng@ubuntu:~/work$?mv?ramdisk.img.gz?ramdisk_new.img
    peng@ubuntu:~/work$?chmod?766?ramdisk_new.img
    

    3. 運行測試

    采用廠家提供的燒錄工具燒錄ramdisk即可,不在截圖。

    可以adb shell登錄安卓設備,用以下命令查看進程是否生效:

    ps?-ef?|?grep?pengd
    

    二、init.rc詳解

    0、 什么是init.rc?

    1)init.rc基礎概念

    Adnroid系統就像是是運行在linux系統上的一個“服務進程”,并不算是一個完整的操作系統。

    這些服務進程是維持設備正常運轉的關鍵,而這些進程的鼻祖就是init進程。

    進程ID為1,源代碼位于system/core/init 目錄。

    作為Android系統的第一個進程,Init進程承擔這很多重要的初始化任務,一般Init進程的初始化可以分為兩部分,前半部分掛載文件系統,初始化屬性系統和Klog, selinux的初始化等,后半部分重要通過解析init.rc來初始化系統daemon服務進程,然后以epoll的監控屬性文件,系統信號等。

    init.rc則是init進程啟動的配置腳本,這個腳本是用一種叫Android Init Language(Android初始化語言)的語言寫的。

    2) init.rc語法

    init.rc語法官方文檔路徑:system/core/init/Readme.txt

    下圖是瑞芯微sdk的改文件路徑:

    一個完整的init.rc腳本由4種類型的聲明組成:

      Action(動作)Commands(命令)Services(服務)Options(選項)
    on?<trigger>?[&&?<trigger>]*
    ???<command>
    ???<command>
    ???<command>
    
    service?<name>?<pathname>?[?<argument>?]*
    ???<option>
    ???<option>
    ???...
    

    3)語法規則:

      注釋以 # 開頭關鍵字和參數以空格分隔,每個語句以行為單位C語言風格的 轉義字符可以用來為參數添加風格字符串使用 “ ”行尾的 用來表示和下面一行是同一行Actions(動作)和Services(服務)就是一個新語句的開始,這個兩個后面跟著Commands(命令)或Options(選項)都屬于這個新語句Actions(動作)和Services(服務)有唯一的名字,如果出現重名就會被當成錯誤忽略掉

    1、Actions(動作)

    一個動作其實就是響應某個事件的過程。

    如下圖所示:當early-init這個觸發條件產生時,依次執行下面的命令1、命令2、命令3、命令4

    【改文件位于system/core/rootdir/init.rc

    源碼實現思想:

    當相應的事件發生后,系統就會對init.rc中的各個觸發條件進行匹配,只要匹配成功就會把這個動作加到“命令執行隊列的尾部”,等待執行。如果已經存在是不會再次添加的。

    2、Commands(命令)

    命令會在條件觸發后一條一條的執行。

    1.)init.rc中常見的觸發條件:

    觸發條件 解釋 示例
    boot 這是init程序啟動后觸發的第一個事件 on boot
    <name> = <Value> 當屬性name滿足特定的value時觸發 on property:vold.decrypt=trigger_load_persist_props
    device-added-<path> device-removed-<path> 當設備節點添加/刪除時會觸發
    service-exited-<name> 當指定的服務<name>存在時觸發

    2)init.rc中常見的命令

    init.rc中常見的Commands有以下一些:

    exec <path> [ <argument> ]創建和執行程序(<path>). 這將會阻塞init,直到程序執行完成。由于它不是內置命令,應盡量避免使用exec,它可能會引起init卡死。

    export <name> <value>在全局環境變量中設在環境變量<name><value>。(這將會被所有在這命令之后運行的進程所繼承)

    ifup <interface>啟動網絡接口<interface>import <filename>解析一個init配置文件,擴展當前配置。

    hostname <name>設置主機名。

    chdir<directory>改變工作目錄。

    chmod <octal-mode> <path>更改文件訪問權限。

    chown <owner> <group> <path>更改文件的所有者和組。

    chroot <directory>改變進程的根目錄。

    class_start <serviceclass>啟動該類service所有尚未運行的服務。

    class_stop <serviceclass>停止所有該類正在運行的service。

    domainname <name>設置域名。

    enable <servicename>改變一個disable的service為enabled。一般用于service在init.rc中被標記為disabled,這樣的service是不會被啟動的,當滿足一定的觸發條件時,可以同enable命令來將他變為enabled。示例:

    ??on?property:boot_completed=1
    ??enable?my_service_name
    

    insmod <path>安裝位于<path>的模塊(PS:驅動)。

    mkdir <path> [mode] [owner] [group]<path>創建一個目錄,(可選)使用給定的模式,所有者個組。如果沒有提供,該目錄將用755權限,所有者為root用戶,組為root。

    mount <type> <device> <dir>[ <mountoption> ]*嘗試掛載<device><dir>,<device>可能有mtd@name形式,以指定名為name的mtd塊設備。

    <mountoption>包括 "ro", "rw", "remount", "noatime", ...restorecon <path> [ <path> ]*恢復名為<path>的文件在file_contexts中配置的的安全級別。自動被init標記正確,不需要用init.rc創建的目錄。

    restorecon_recursive <path> [ <path> ]*遞歸的恢復<path>指出的目錄樹中file_contexts配置指定的安全級別。path不要用shell可寫或app可寫的目錄,如/data/locla/temp,/data/data,或者有類似前綴的(目錄)。

    setcon <securitycontext>設置當前進程的security context為特定的字符串。這是典型的僅用于所有進程啟動之前的early-init設置init context

    setenforce 0|1設置SELinux系統范圍的enfoucing狀態。0 is permissive (i.e. log but do not deny), 1 is enforcing.

    setprop <name> <value>設置系統屬性<name><value>.

    setrlimit <resource> <cur> <max>為特定資源設置rlimit

    setsebool <name> <value>設置SELinux的bool類型<name><value>。<value>may be 1|true|on or 0|false|off

    start <service>啟動一個服務(如果服務尚未啟動)。

    stop <service>停止服務(如果正在運行)。

    symlink <target> <path>創建一個符號連接,at <path> with the value <target>。

    sysclktz <mins_west_of_gmt>Set the system clock base (0 if system clock ticks in GMT)

    trigger <event>觸發一個事件。一個動作將另一動作排隊。

    wait <path> [ <timeout> ]poll特定的<path>,出現后返回,或timeout到達。如果timeout沒有指定,默認為5秒。

    write <path> <string>打開一個位于<path>的文件,寫入(不是追加)字符串<string>。

    3、Services(服務)

    Services其實是可執行程序,他們在特定選項的約束下會被init程序運行或者重啟。

    一般格式:

    Service?<name>?<pathname>?<argument>
    ?<option>
    ?<option>
    ......
    

    其中標識符含義如下:

    ?<name>表示service的名稱
    ?<pathname>表示service所在的路徑
    ?<argument>表示啟動service所帶的參數
    ?<option>表示對這個service的約束選項
    

    4、Option選項

    Option用來定義Service的行為,決定了Service將在何時啟動,如何運行等。常用的Option有包括以下一些。

    critical

      • 這是十分關鍵的服務。如果在四分鐘內退出超過四次,手機將會重啟并進入recovery模式。

    disabled

      • 這種類型的服務不會自動啟動。它必須明確的使用名字啟動。

    setenv <name> <value>

      • 設置環境變量=在加載的進程中。

    socket <name> <type> <perm> [ <user> [ <group> [ <context> ] ] ]

      • 創建一個名為

    /dev/socket/<name>

      的UNIX域socket并將fd傳遞到加載的進程中。
    <type>必須是"dgram",?"stream",?"seqpacket"中的一種。
    <user>和<group>默認為0.
    <context>是?SELinux?socket?安全上下文,默認為service安全級別,
    可以指定為seclabel或根據service的可執行文件的安全級別計算。
    

    user <username>

      • 在執行該service前改變用戶名,默認為root。如果你的進程請求Linux的特殊能力,就不要用這個命令。需以進入進程仍是root->請求特權->切換到你期望的uid來替換此法。

    group <groupname> [ <groupname> ]*

      • 在執行該service前改變組名。第一個以后的附加組名用于設定進程的附加組(通過setgroups())。當前默認是root。

    seclabel <securitycontext>

      • 在執行服務之前改變安全級別。主要用于從rootfs執行服務,比如ueventd, adbd. 在system分區上可以用基于文件安全級別的策略定義的transition,如果沒有指定且沒有定義策略的transition,默認是init上下文。

    oneshot

      • 退出不重啟服務(名副其實,一次性)。

    class <name>

      • 為一service指定一個類名,所有有相同類名的service可以一同啟動或停止。如果沒有用class選項指定類名,該service屬于"default"。

    onrestart

      在service重啟的時候執行。

    這是一口君的新書,感謝大家支持!

    推薦器件

    更多器件
    器件型號 數量 器件廠商 器件描述 數據手冊 ECAD模型 風險等級 參考價格 更多信息
    IL4208-X007T 1 Infineon Technologies AG Triac Output Optocoupler, 1-Element, 5300V Isolation, DIP-6
    $3.81 查看
    AFBR-1531CZ 1 Broadcom Limited Transmitter,

    ECAD模型

    下載ECAD模型
    $159.06 查看
    HMC586LC4B 1 Analog Devices Inc Wideband VCO SMT w/Buffer Amplifier, 4 - 8 GHz
    $187.92 查看

    相關推薦

    電子產業圖譜

    公眾號『一口Linux』號主彭老師,擁有15年嵌入式開發經驗和培訓經驗。曾任職ZTE,某研究所,華清遠見教學總監。擁有多篇網絡協議相關專利和軟件著作。精通計算機網絡、Linux系統編程、ARM、Linux驅動、龍芯、物聯網。原創內容基本從實際項目出發,保持原理+實踐風格,適合Linux驅動新手入門和技術進階。

    日韩欧美日产一区,日产国产亚洲欧洲综合,欧美亚洲日产精品第一页,亚洲日产专区app