爲Android添加開機啓動腳本

轉:https://blog.csdn.net/u014316462/article/details/76438611linux

本文介紹了一種在Android 4.2.2源碼中添加、修改文件或者代碼,來達到使android在啓動時,執行位於/system/etc/目錄下的shell腳本文件的方法。
  因爲平臺不一樣,可能細節上多有差別,可是大致方式應該是相同的。android

最近在作項目的過程當中,遇到了這麼一個需求,須要在Android(4.2.2)啓動時候執行如下命令,命令的具體含義再也不解釋:shell

  1. mount -t usbfs none /proc/bus/usb

最初作法是將其加入init.rc文件中,可是發現此方法行不通,緣由到如今也未查明,但願知道緣由的朋友可以留言告知,不勝感激o(∩_∩)o 。express

接着查閱相關資料,發現將命令寫入一個sh文件中,以後在開機的時候執行該sh文件,一樣可以達到效果,因而新建了一個sh文件usbfs.sh,內容以下:apache

  1. #! /system/bin/sh
  2. mount -t usbfs none /proc/bus/usb

這裏須要注意的是,操做該文件(包括新建、編輯)時儘可能在Linux環境下,不要在Windows下。我開始作這步的時候是在Win下進行內容編譯,以後將文件拷貝至Android源碼相應位置的。結果編譯完成,鏡像燒寫後發現死活都不執行,或者報錯,cat了一下發現內容裏有多餘的字符。安全

接下來的操做,目的就很明確了。app

第1、咱們須要Android在編譯的時候,將這個文件拷貝至輸出目錄相應的位置,而且最終添加到鏡像中去。less

第2、咱們須要Android在啓動的時候,執行這個sh文件。tcp

圍繞以上兩點,咱們開展下一步的工做。ui

 

1、實現編譯時執行對此文件的拷貝。

 

新增的sh文件,個人存放路徑爲device/hisilicon/bigfish/etc/usbfs.sh。不一樣平臺的話,文件路徑可能略有差別,個人是海思平臺的源碼包。具體怎麼定,按你本身的實際狀況來。

出於安全考慮,我準備將該文件拷貝至Android system分區下的etc目錄中,即目標地址爲:/system/etc/。

OK,作好以上兩點,接下來就是添加相應的拷貝動做了。這個動做須要本身添加的嗎?固然,大部分狀況下Android在編譯的時候是不會自動添加你新增的文件的。動做在哪裏添加的呢?

在這裏----device/hisilicon/Hi3716CV200/device.mk文件中,固然這個也是不一樣平臺略有差別,打開該文件,咱們就能看到如下內容了(摘抄):

  1. #
  2. # Copyright (C) 2011 The Android Open-Source Project
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. #      http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. PRODUCT_AAPT_PREF_CONFIG := xhdpi
  17. PRODUCT_CHARACTERISTICS := tablet
  18. PRODUCT_COPY_FILES := \
  19.     frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
  20.     frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml \
  21.     frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml
  22. PRODUCT_COPY_FILES += \
  23.     device/hisilicon/bigfish/etc/init.rc:root/init.rc \
  24.     device/hisilicon/bigfish/etc/init.hidolphin.rc:root/init.hidolphin.rc \
  25.     device/hisilicon/bigfish/etc/ueventd.bigfish.rc:root/ueventd.bigfish.rc \
  26.     device/hisilicon/bigfish/etc/media_codecs.xml:/system/etc/media_codecs.xml \
  27.     device/hisilicon/bigfish/etc/media_profiles.xml:/system/etc/media_profiles.xml \
  28.     device/hisilicon/bigfish/etc/tablet_core_hardware.xml:system/etc/permissions/tablet_core_hardware.xml \
  29.     device/hisilicon/Hi3716CV200/etc/init.Hi3716CV200.rc:root/init.bigfish.rc \
  30.     device/hisilicon/Hi3716CV200/etc/init.Hi3716CV200.sh:system/etc/init.bigfish.sh

咱們須要作的,就是將如下內容添加到上述文件合適的位置:

  1. PRODUCT_COPY_FILES += \
  2.         device/hisilicon/bigfish/etc/usbfs.sh:system/etc/usbfs.sh

「:」前面是文件源路徑,後面的是目的路徑。

這樣,Android在執行編譯的時候就會把新增文件拷貝至相應的目標路徑去了,拷貝動做已經實現。

 

2、添加啓動動做,使Android在啓動時候執行。

 

如何添加啓動動做?大部分人或許都知道,那就是在init.rc文件中添加上就是了,網上也有一些此類的介紹,我是這麼作的:

init.rc文件末尾處加入如下內容(再也不詳述,不懂的本身翻書或者爬網查)

  1. service mount-usbfs /system/etc/usbfs.sh
  2.     class main
  3.     user root
  4.     group root
  5.     oneshot

以後編譯系統,燒寫,啓動,觀察啓動log,發現確實執行了該sh文件,可是卻報了一個「權限不足」的提示,ll了一下usbfs.sh文件,發現權限是644,沒有執行權限。

OK,沒有執行權限,給他添加上執行權限就是了,一樣是在init.rc文件中,添加如下內容:

  1. chown root shell /system/etc/usbfs.sh
  2. chmod 0550 /system/etc/usbfs.sh

添加了執行的權限,此次應該沒有問題了吧,網上不少介紹也是這麼幹的。

以後又是編譯、燒寫、啓動...漫長的過程(┬_┬),Android系統級開發,要有耐心啊。

觀察啓動的log,竟然仍是「權限不足」!!!怎麼回事,難道沒有生效?ll了一下usbfs.sh文件,發現權限竟然仍是644,說明剛纔的賦權限是沒有效果的。

爲何?接着查,在查看init.rc的過程當中,發現瞭如下內容:

  1. mount ext4 ext4@system /system ro

原來system分區是以只讀的形式進行掛載的,忽略這點了。以只讀形式掛載,再怎麼賦權限,也是徒勞啊。

忽然又發現,與usbfs.sh在同一個目錄的init.bigfish.sh,權限是正常的,而且該文件的源文件與sh文件一樣都在一個目錄裏。那麼,這說明Android在編譯過程當中,除了拷貝之外,應該還有一個賦權限的動做。

基於以上思路,繼續進行查找。功夫不負有心人,還真被我找到了,確實存在這麼一個動做,它在哪裏呢?

在這裏:system/core/include/private/android_filesystem_config.h,其中有個結構體作以下定義:

  1. /* Rules for files.
  2. ** These rules are applied based on "first match", so they
  3. ** should start with the most specific path and work their
  4. ** way up to the root. Prefixes ending in * denotes wildcard
  5. ** and will allow partial matches.
  6. */
  7. static struct fs_path_config android_files[] = {
  8.     { 00440, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.rc" },
  9.     { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.goldfish.sh" },
  10.     { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.bigfish.sh" },
  11.     { 00440, AID_ROOT,      AID_SHELL,     "system/etc/init.trout.rc" },
  12.     { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.ril" },
  13.     { 00550, AID_ROOT,      AID_SHELL,     "system/etc/init.testmenu" },
  14.     { 00550, AID_DHCP,      AID_SHELL,     "system/etc/dhcpcd/dhcpcd-run-hooks" },
  15.     { 00550, AID_DHCP,      AID_SHELL,     "system/etc/dhclient*" },
  16.     { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/dbus.conf" },
  17.     { 00444, AID_RADIO,     AID_AUDIO,     "system/etc/AudioPara4.csv" },
  18.     { 00555, AID_ROOT,      AID_ROOT,      "system/etc/ppp/*" },
  19.     { 00555, AID_ROOT,      AID_ROOT,      "system/etc/rc.*" },
  20.     { 00644, AID_SYSTEM,    AID_SYSTEM,    "data/app/*" },
  21.     { 00644, AID_MEDIA_RW,  AID_MEDIA_RW,  "data/media/*" },
  22.     { 00644, AID_SYSTEM,    AID_SYSTEM,    "data/app-private/*" },
  23.     { 00644, AID_APP,       AID_APP,       "data/data/*" },
  24.         /* the following two files are INTENTIONALLY set-gid and not set-uid.
  25.          * Do not change. */
  26.     { 02755, AID_ROOT,      AID_NET_RAW,   "system/bin/ping" },
  27.     { 04750, AID_ROOT,      AID_INET,      "system/bin/netcfg" }, //modified by lwf 20141008,for resolve a bug when DHCP enable.
  28.                                                                   //called by BrowserEthernetClientX::submitParameters().
  29.         /* the following five files are INTENTIONALLY set-uid, but they
  30.      * are NOT included on user builds. */
  31.     { 06755, AID_ROOT,      AID_ROOT,      "system/xbin/su" },
  32.     { 06755, AID_ROOT,      AID_ROOT,      "system/xbin/librank" },
  33.     { 06755, AID_ROOT,      AID_ROOT,      "system/xbin/procrank" },
  34.     { 06755, AID_ROOT,      AID_ROOT,      "system/xbin/procmem" },
  35.     { 06755, AID_ROOT,      AID_ROOT,      "system/xbin/tcpdump" },
  36.     { 04770, AID_ROOT,      AID_RADIO,     "system/bin/pppd-ril" },
  37.         /* the following file is INTENTIONALLY set-uid, and IS included
  38.          * in user builds. */
  39.     { 06750, AID_ROOT,      AID_SHELL,     "system/bin/run-as" },
  40.     { 00755, AID_ROOT,      AID_SHELL,     "system/bin/*" },
  41.     { 00755, AID_ROOT,      AID_ROOT,      "system/lib/valgrind/*" },
  42.     { 00755, AID_ROOT,      AID_SHELL,     "system/xbin/*" },
  43.     { 00755, AID_ROOT,      AID_SHELL,     "system/vendor/bin/*" },
  44.     { 00750, AID_ROOT,      AID_SHELL,     "sbin/*" },
  45.     { 00755, AID_ROOT,      AID_ROOT,      "bin/*" },
  46.     { 00750, AID_ROOT,      AID_SHELL,     "init*" },
  47.     { 00750, AID_ROOT,      AID_SHELL,     "charger*" },
  48.     { 00750, AID_ROOT,      AID_SHELL,     "sbin/fs_mgr" },
  49.     { 00640, AID_ROOT,      AID_SHELL,     "fstab.*" },
  50.     { 00644, AID_ROOT,      AID_ROOT,       0 },
  51. };

從行9能夠看到,此處從新定義了init.bigfish.sh的權限,OK,咱們應該只須要加入如下內容,就能夠了:

  1. { 00550, AID_ROOT,      AID_SHELL,     "system/etc/usbfs.sh" },

保存,編譯,啓動。。。果真能夠了!

 

我的感受,我這種作法是比較遵循Android規則的一種方法。可能存在一些更加簡單、直接的方法,我在爬網文過程當中也看到過,好比更改system分區的掛載方式,由只讀變爲讀寫等等,可是這樣的方法,你本身感受合適嗎?

固然,若是你有更好的方法,但願可以留言分享,不勝感激o(∩_∩)o 。

相關文章
相關標籤/搜索