轉:https://blog.csdn.net/u014316462/article/details/76438611linux
本文介紹了一種在Android 4.2.2源碼中添加、修改文件或者代碼,來達到使android在啓動時,執行位於/system/etc/目錄下的shell腳本文件的方法。
因爲平臺不一樣,可能細節上多有差別,可是大致方式應該是相同的。android
最近在作項目的過程當中,遇到了這麼一個需求,須要在Android(4.2.2)啓動時候執行如下命令,命令的具體含義再也不解釋:shell
- mount -t usbfs none /proc/bus/usb
最初作法是將其加入init.rc文件中,可是發現此方法行不通,緣由到如今也未查明,但願知道緣由的朋友可以留言告知,不勝感激o(∩_∩)o 。express
接着查閱相關資料,發現將命令寫入一個sh文件中,以後在開機的時候執行該sh文件,一樣可以達到效果,因而新建了一個sh文件usbfs.sh,內容以下:apache
- #! /system/bin/sh
- 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文件中,固然這個也是不一樣平臺略有差別,打開該文件,咱們就能看到如下內容了(摘抄):
- #
- # Copyright (C) 2011 The Android Open-Source Project
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- PRODUCT_AAPT_PREF_CONFIG := xhdpi
- PRODUCT_CHARACTERISTICS := tablet
- PRODUCT_COPY_FILES := \
- frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
- frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml \
- frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml
- PRODUCT_COPY_FILES += \
- device/hisilicon/bigfish/etc/init.rc:root/init.rc \
- device/hisilicon/bigfish/etc/init.hidolphin.rc:root/init.hidolphin.rc \
- device/hisilicon/bigfish/etc/ueventd.bigfish.rc:root/ueventd.bigfish.rc \
- device/hisilicon/bigfish/etc/media_codecs.xml:/system/etc/media_codecs.xml \
- device/hisilicon/bigfish/etc/media_profiles.xml:/system/etc/media_profiles.xml \
- device/hisilicon/bigfish/etc/tablet_core_hardware.xml:system/etc/permissions/tablet_core_hardware.xml \
- device/hisilicon/Hi3716CV200/etc/init.Hi3716CV200.rc:root/init.bigfish.rc \
- device/hisilicon/Hi3716CV200/etc/init.Hi3716CV200.sh:system/etc/init.bigfish.sh
咱們須要作的,就是將如下內容添加到上述文件合適的位置:
- PRODUCT_COPY_FILES += \
- device/hisilicon/bigfish/etc/usbfs.sh:system/etc/usbfs.sh
「:」前面是文件源路徑,後面的是目的路徑。
這樣,Android在執行編譯的時候就會把新增文件拷貝至相應的目標路徑去了,拷貝動做已經實現。
2、添加啓動動做,使Android在啓動時候執行。
如何添加啓動動做?大部分人或許都知道,那就是在init.rc文件中添加上就是了,網上也有一些此類的介紹,我是這麼作的:
init.rc文件末尾處加入如下內容(再也不詳述,不懂的本身翻書或者爬網查)
- service mount-usbfs /system/etc/usbfs.sh
- class main
- user root
- group root
- oneshot
以後編譯系統,燒寫,啓動,觀察啓動log,發現確實執行了該sh文件,可是卻報了一個「權限不足」的提示,ll了一下usbfs.sh文件,發現權限是644,沒有執行權限。
OK,沒有執行權限,給他添加上執行權限就是了,一樣是在init.rc文件中,添加如下內容:
- chown root shell /system/etc/usbfs.sh
- chmod 0550 /system/etc/usbfs.sh
添加了執行的權限,此次應該沒有問題了吧,網上不少介紹也是這麼幹的。
以後又是編譯、燒寫、啓動...漫長的過程(┬_┬),Android系統級開發,要有耐心啊。
觀察啓動的log,竟然仍是「權限不足」!!!怎麼回事,難道沒有生效?ll了一下usbfs.sh文件,發現權限竟然仍是644,說明剛纔的賦權限是沒有效果的。
爲何?接着查,在查看init.rc的過程當中,發現瞭如下內容:
- mount ext4 ext4@system /system ro
原來system分區是以只讀的形式進行掛載的,忽略這點了。以只讀形式掛載,再怎麼賦權限,也是徒勞啊。
忽然又發現,與usbfs.sh在同一個目錄的init.bigfish.sh,權限是正常的,而且該文件的源文件與sh文件一樣都在一個目錄裏。那麼,這說明Android在編譯過程當中,除了拷貝之外,應該還有一個賦權限的動做。
基於以上思路,繼續進行查找。功夫不負有心人,還真被我找到了,確實存在這麼一個動做,它在哪裏呢?
在這裏:system/core/include/private/android_filesystem_config.h,其中有個結構體作以下定義:
- /* Rules for files.
- ** These rules are applied based on "first match", so they
- ** should start with the most specific path and work their
- ** way up to the root. Prefixes ending in * denotes wildcard
- ** and will allow partial matches.
- */
- static struct fs_path_config android_files[] = {
- { 00440, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.rc" },
- { 00550, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.sh" },
- { 00550, AID_ROOT, AID_SHELL, "system/etc/init.bigfish.sh" },
- { 00440, AID_ROOT, AID_SHELL, "system/etc/init.trout.rc" },
- { 00550, AID_ROOT, AID_SHELL, "system/etc/init.ril" },
- { 00550, AID_ROOT, AID_SHELL, "system/etc/init.testmenu" },
- { 00550, AID_DHCP, AID_SHELL, "system/etc/dhcpcd/dhcpcd-run-hooks" },
- { 00550, AID_DHCP, AID_SHELL, "system/etc/dhclient*" },
- { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/dbus.conf" },
- { 00444, AID_RADIO, AID_AUDIO, "system/etc/AudioPara4.csv" },
- { 00555, AID_ROOT, AID_ROOT, "system/etc/ppp/*" },
- { 00555, AID_ROOT, AID_ROOT, "system/etc/rc.*" },
- { 00644, AID_SYSTEM, AID_SYSTEM, "data/app/*" },
- { 00644, AID_MEDIA_RW, AID_MEDIA_RW, "data/media/*" },
- { 00644, AID_SYSTEM, AID_SYSTEM, "data/app-private/*" },
- { 00644, AID_APP, AID_APP, "data/data/*" },
- /* the following two files are INTENTIONALLY set-gid and not set-uid.
- * Do not change. */
- { 02755, AID_ROOT, AID_NET_RAW, "system/bin/ping" },
- { 04750, AID_ROOT, AID_INET, "system/bin/netcfg" }, //modified by lwf 20141008,for resolve a bug when DHCP enable.
- //called by BrowserEthernetClientX::submitParameters().
- /* the following five files are INTENTIONALLY set-uid, but they
- * are NOT included on user builds. */
- { 06755, AID_ROOT, AID_ROOT, "system/xbin/su" },
- { 06755, AID_ROOT, AID_ROOT, "system/xbin/librank" },
- { 06755, AID_ROOT, AID_ROOT, "system/xbin/procrank" },
- { 06755, AID_ROOT, AID_ROOT, "system/xbin/procmem" },
- { 06755, AID_ROOT, AID_ROOT, "system/xbin/tcpdump" },
- { 04770, AID_ROOT, AID_RADIO, "system/bin/pppd-ril" },
- /* the following file is INTENTIONALLY set-uid, and IS included
- * in user builds. */
- { 06750, AID_ROOT, AID_SHELL, "system/bin/run-as" },
- { 00755, AID_ROOT, AID_SHELL, "system/bin/*" },
- { 00755, AID_ROOT, AID_ROOT, "system/lib/valgrind/*" },
- { 00755, AID_ROOT, AID_SHELL, "system/xbin/*" },
- { 00755, AID_ROOT, AID_SHELL, "system/vendor/bin/*" },
- { 00750, AID_ROOT, AID_SHELL, "sbin/*" },
- { 00755, AID_ROOT, AID_ROOT, "bin/*" },
- { 00750, AID_ROOT, AID_SHELL, "init*" },
- { 00750, AID_ROOT, AID_SHELL, "charger*" },
- { 00750, AID_ROOT, AID_SHELL, "sbin/fs_mgr" },
- { 00640, AID_ROOT, AID_SHELL, "fstab.*" },
- { 00644, AID_ROOT, AID_ROOT, 0 },
- };
從行9能夠看到,此處從新定義了init.bigfish.sh的權限,OK,咱們應該只須要加入如下內容,就能夠了:
- { 00550, AID_ROOT, AID_SHELL, "system/etc/usbfs.sh" },
保存,編譯,啓動。。。果真能夠了!
我的感受,我這種作法是比較遵循Android規則的一種方法。可能存在一些更加簡單、直接的方法,我在爬網文過程當中也看到過,好比更改system分區的掛載方式,由只讀變爲讀寫等等,可是這樣的方法,你本身感受合適嗎?
固然,若是你有更好的方法,但願可以留言分享,不勝感激o(∩_∩)o 。