• 正文
    • 一、如何設(shè)置開機(jī)啟動(dòng)某個(gè)程序?
    • 二、init.rc詳解
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

安卓如何設(shè)置開機(jī)自動(dòng)啟動(dòng)某個(gè)程序?ramdisk + init.rc給你搞定

2023/09/06
4054
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一、如何設(shè)置開機(jī)啟動(dòng)某個(gè)程序?

1.需求描述

最近有個(gè)項(xiàng)目需要在Android開機(jī)啟動(dòng)之后,自動(dòng)執(zhí)行一個(gè)C語(yǔ)言編寫的程序:pengd

該程序運(yùn)行時(shí)需要修改網(wǎng)絡(luò)ip地址及其他網(wǎng)絡(luò)操作,所以需要root權(quán)限

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

pengd 預(yù)置到Android中的某個(gè)路徑下,比如放在 /sbin/pengd ;

然后修改init.rc文件,實(shí)現(xiàn)開機(jī)后自動(dòng)運(yùn)行我們的程序pengd

本次項(xiàng)目用到的安卓設(shè)備的init.rc和sbin下的文件重啟后會(huì)恢復(fù)默認(rèn),主要是安卓部分目錄是基于ramdisk,因此我們需要重新制作ramdisk.img,將前面2個(gè)步驟的操作同步到到ramdisk.img,然后再重新燒錄設(shè)備對(duì)應(yīng)分區(qū)

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文件最后一定要有空行,否則編譯報(bào)錯(cuò)!

init.rc語(yǔ)法見第二章
該配置文件并不是唯一寫法,具體要參考實(shí)際廠家提供的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. 運(yùn)行測(cè)試

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

可以adb shell登錄安卓設(shè)備,用以下命令查看進(jìn)程是否生效:

ps?-ef?|?grep?pengd

二、init.rc詳解

0、 什么是init.rc?

1)init.rc基礎(chǔ)概念

Adnroid系統(tǒng)就像是是運(yùn)行在linux系統(tǒng)上的一個(gè)“服務(wù)進(jìn)程”,并不算是一個(gè)完整的操作系統(tǒng)。

這些服務(wù)進(jìn)程是維持設(shè)備正常運(yùn)轉(zhuǎn)的關(guān)鍵,而這些進(jìn)程的鼻祖就是init進(jìn)程。

進(jìn)程ID為1,源代碼位于system/core/init 目錄。

作為Android系統(tǒng)的第一個(gè)進(jìn)程,Init進(jìn)程承擔(dān)這很多重要的初始化任務(wù),一般Init進(jìn)程的初始化可以分為兩部分,前半部分掛載文件系統(tǒng),初始化屬性系統(tǒng)和Klog, selinux的初始化等,后半部分重要通過解析init.rc來初始化系統(tǒng)daemon服務(wù)進(jìn)程,然后以epoll的監(jiān)控屬性文件,系統(tǒng)信號(hào)等。

init.rc則是init進(jìn)程啟動(dòng)的配置腳本,這個(gè)腳本是用一種叫Android Init Language(Android初始化語(yǔ)言)的語(yǔ)言寫的。

2) init.rc語(yǔ)法

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

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

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

    Action(動(dòng)作)Commands(命令)Services(服務(wù))Options(選項(xiàng))
on?<trigger>?[&&?<trigger>]*
???<command>
???<command>
???<command>

service?<name>?<pathname>?[?<argument>?]*
???<option>
???<option>
???...

3)語(yǔ)法規(guī)則:

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

1、Actions(動(dòng)作)

一個(gè)動(dòng)作其實(shí)就是響應(yīng)某個(gè)事件的過程。

如下圖所示:當(dāng)early-init這個(gè)觸發(fā)條件產(chǎn)生時(shí),依次執(zhí)行下面的命令1、命令2、命令3、命令4

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

源碼實(shí)現(xiàn)思想:

當(dāng)相應(yīng)的事件發(fā)生后,系統(tǒng)就會(huì)對(duì)init.rc中的各個(gè)觸發(fā)條件進(jìn)行匹配,只要匹配成功就會(huì)把這個(gè)動(dòng)作加到“命令執(zhí)行隊(duì)列的尾部”,等待執(zhí)行。如果已經(jīng)存在是不會(huì)再次添加的。

2、Commands(命令)

命令會(huì)在條件觸發(fā)后一條一條的執(zhí)行。

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

觸發(fā)條件 解釋 示例
boot 這是init程序啟動(dòng)后觸發(fā)的第一個(gè)事件 on boot
<name> = <Value> 當(dāng)屬性name滿足特定的value時(shí)觸發(fā) on property:vold.decrypt=trigger_load_persist_props
device-added-<path> device-removed-<path> 當(dāng)設(shè)備節(jié)點(diǎn)添加/刪除時(shí)會(huì)觸發(fā)
service-exited-<name> 當(dāng)指定的服務(wù)<name>存在時(shí)觸發(fā)

2)init.rc中常見的命令

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

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

export <name> <value>在全局環(huán)境變量中設(shè)在環(huán)境變量<name><value>。(這將會(huì)被所有在這命令之后運(yùn)行的進(jìn)程所繼承)

ifup <interface>啟動(dòng)網(wǎng)絡(luò)接口<interface>import <filename>解析一個(gè)init配置文件,擴(kuò)展當(dāng)前配置。

hostname <name>設(shè)置主機(jī)名。

chdir<directory>改變工作目錄。

chmod <octal-mode> <path>更改文件訪問權(quán)限。

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

chroot <directory>改變進(jìn)程的根目錄。

class_start <serviceclass>啟動(dòng)該類service所有尚未運(yùn)行的服務(wù)。

class_stop <serviceclass>停止所有該類正在運(yùn)行的service。

domainname <name>設(shè)置域名。

enable <servicename>改變一個(gè)disable的service為enabled。一般用于service在init.rc中被標(biāo)記為disabled,這樣的service是不會(huì)被啟動(dòng)的,當(dāng)滿足一定的觸發(fā)條件時(shí),可以同enable命令來將他變?yōu)閑nabled。示例:

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

insmod <path>安裝位于<path>的模塊(PS:驅(qū)動(dòng))。

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

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

<mountoption>包括 "ro", "rw", "remount", "noatime", ...restorecon <path> [ <path> ]*恢復(fù)名為<path>的文件在file_contexts中配置的的安全級(jí)別。自動(dòng)被init標(biāo)記正確,不需要用init.rc創(chuàng)建的目錄。

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

setcon <securitycontext>設(shè)置當(dāng)前進(jìn)程的security context為特定的字符串。這是典型的僅用于所有進(jìn)程啟動(dòng)之前的early-init設(shè)置init context

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

setprop <name> <value>設(shè)置系統(tǒng)屬性<name><value>.

setrlimit <resource> <cur> <max>為特定資源設(shè)置rlimit

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

start <service>啟動(dòng)一個(gè)服務(wù)(如果服務(wù)尚未啟動(dòng))。

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

symlink <target> <path>創(chuàng)建一個(gè)符號(hào)連接,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>觸發(fā)一個(gè)事件。一個(gè)動(dòng)作將另一動(dòng)作排隊(duì)。

wait <path> [ <timeout> ]poll特定的<path>,出現(xiàn)后返回,或timeout到達(dá)。如果timeout沒有指定,默認(rèn)為5秒。

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

3、Services(服務(wù))

Services其實(shí)是可執(zhí)行程序,他們?cè)谔囟ㄟx項(xiàng)的約束下會(huì)被init程序運(yùn)行或者重啟。

一般格式:

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

其中標(biāo)識(shí)符含義如下:

?<name>表示service的名稱
?<pathname>表示service所在的路徑
?<argument>表示啟動(dòng)service所帶的參數(shù)
?<option>表示對(duì)這個(gè)service的約束選項(xiàng)

4、Option選項(xiàng)

Option用來定義Service的行為,決定了Service將在何時(shí)啟動(dòng),如何運(yùn)行等。常用的Option有包括以下一些。

critical

    • 這是十分關(guān)鍵的服務(wù)。如果在四分鐘內(nèi)退出超過四次,手機(jī)將會(huì)重啟并進(jìn)入recovery模式。

disabled

    • 這種類型的服務(wù)不會(huì)自動(dòng)啟動(dòng)。它必須明確的使用名字啟動(dòng)。

setenv <name> <value>

    • 設(shè)置環(huán)境變量=在加載的進(jìn)程中。

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

    • 創(chuàng)建一個(gè)名為

/dev/socket/<name>

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

user <username>

    • 在執(zhí)行該service前改變用戶名,默認(rèn)為root。如果你的進(jìn)程請(qǐng)求Linux的特殊能力,就不要用這個(gè)命令。需以進(jìn)入進(jìn)程仍是root->請(qǐng)求特權(quán)->切換到你期望的uid來替換此法。

group <groupname> [ <groupname> ]*

    • 在執(zhí)行該service前改變組名。第一個(gè)以后的附加組名用于設(shè)定進(jìn)程的附加組(通過setgroups())。當(dāng)前默認(rèn)是root。

seclabel <securitycontext>

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

oneshot

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

class <name>

    • 為一service指定一個(gè)類名,所有有相同類名的service可以一同啟動(dòng)或停止。如果沒有用class選項(xiàng)指定類名,該service屬于"default"。

onrestart

    在service重啟的時(shí)候執(zhí)行。

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

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
ABM3-18.432MHZ-D2Y-T 1 Abracon Corporation CRYSTAL 18.4320MHZ 18PF SMD
$0.75 查看
KSZ9567RTXI 1 Microchip Technology Inc IC ETHERNET SWITCH 7PORT 128TQFP

ECAD模型

下載ECAD模型
$15.08 查看
X1G004171004700 1 Seiko Epson Corporation CMOS Output Clock Oscillator,
$2.94 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

公眾號(hào)『一口Linux』號(hào)主彭老師,擁有15年嵌入式開發(fā)經(jīng)驗(yàn)和培訓(xùn)經(jīng)驗(yàn)。曾任職ZTE,某研究所,華清遠(yuǎn)見教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專利和軟件著作。精通計(jì)算機(jī)網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動(dòng)、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實(shí)際項(xiàng)目出發(fā),保持原理+實(shí)踐風(fēng)格,適合Linux驅(qū)動(dòng)新手入門和技術(shù)進(jìn)階。