为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 。

相关文章
相关标签/搜索