Deep inside the Android operating system, init.rc
files play a vital role, defining the services and commands to be run when the system starts. But what if you want to add your own custom init.custom.rc and then add custom services or commands to the custom file? init.custom.rc
In this article, I'll explore how to customize and dynamically modify files in Android .
Series of articles
Android system init.rc creates file node implementation and principle analysis when booting for the first time
Android system init.rc executes shell script when booting
Android system init.rc sys/class system node cannot be written into solution and principle analysis
Android system init.rc Detailed file explanation
of Android system custom dynamic modification init.custom.rc
1. Requirements assumption
My goal is init.custom.rc
to add a new service in the file that runs a script after the system startup is complete. In addition, I also want to create a new directory after the file system data is available, and be able to dynamically modify and add services and scripts without recompiling the code.
2. Initial attempts
The initial idea was init.rc
to add new services and commands directly in the file. But this method may cause the main init.rc
file to become confusing, especially when there are multiple custom services and commands. I don’t want the services and systems I added to be confusing, and then it will be inconvenient to troubleshoot the problem and then try further.
3. Traps passed through
You can see from the contents of the and files system/core/rootdir
provided in the directory that the project seems to use two build systems at the same time: the old one and the new one . In order to add in both build systems , follow these steps:Android.mk
Android.bp
Android.mk
Android.bp
custom.init.rc
Add in Android.mk:
In Android.mk
the file, find a suitable location and add the following content:
include $(CLEAR_VARS)
LOCAL_MODULE := init.custom.rc
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/init
include $(BUILD_PREBUILT)
Make sure init.custom.rc
the file is in Android.mk
the same directory as .
Add in Android.bp:
- In
Android.bp
the file, find a suitable location and add the following content:
prebuilt_etc {
name: "init.custom.rc",
src: "init.custom.rc",
sub_dir: "init",
}
Make sure init.custom.rc
the file is in Android.bp
the same directory as .
However... this change is of no use, so we have to find another way.
init.custom.rc
After adding the error, I encountered a problem when trying to add the new file to the Android build system:MODULE.TARGET.ETC.custom.init.rc
it has been defined twice. This means we are trying to define the same file in two different places build/make/core/base_rules.mk:325: error: system/core/rootdir: MODULE.TARGET.ETC.custom.init.rc already defined by system/core/rootdir.
(The reason for the error is that I added it to Android.mk and Android.bp at the same time, and finally deleting either of them did not meet the requirements)
3. Final solution
To make the code more modular, I decided to try importing a new file named inside import
the main file using the statement . This way, all custom services and commands can be placed in this new file instead of being mixed in the main file.init.rc
init.custom.rc
.rc
Use the statement in an existing file import
. This allows .rc
the contents of multiple files to be organized more modularly and init.rc
imported in the main file.
To resolve this issue, the following steps were taken:
Modify customize.mk :
In vendor/customize
the directory, edit customize.mk
the file and add the following content:
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/init.custom.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.custom.rc
Modify init.rc :
In system/core/rootdir
the directory, init.rc
make the following modifications to the file:
@@ -8,6 +8,7 @@ import /init.environ.rc
import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
+import /vendor/etc/init/hw/init.custom.rc
Added init.custom.rc :
Under vendor/customize
the directory, create init.custom.rc
a file and add the following content:
# Define a service to copy video
service copy_video2 /system/bin/sh /system/bin/copy_video.sh
class main
user root
group root
seclabel u:r:shell:s0
oneshot
# Start the service on boot completed
on property:sys.boot_completed=2
start copy_video2
# Create a directory after the file system data is available
on post-fs-data
mkdir /mnt/custom3 0755 root root
Passed PRODUCT_COPY_FILES
, init.custom.rc
will be copied to at compile time /vendor/etc/init/hw/init.custom.rc
.
Verification method :
Use ADB to gain root privileges:
adb root
Remount the system partition
adb remount
Pull init.custom.rc
files from device:
adb pull /vendor/etc/init/hw/init.custom.rc .
Modify a local init.custom.rc
file, e.g. /mnt/custom3
change to /mnt/custom4
, and then push the file back to the device
adb push .\init.custom.rc /vendor/etc/init/hw/init.custom.rc
Synchronize the file system and restart the device
adb shell sync
adb shell reboot
After restarting, verify whether the modifications have taken effect:
adb shell
cd /mnt
ls
If you see custom4
the directory, the modification has taken effect successfully.
Through the above method, we successfully customized the startup script of the Android system and verified its effectiveness. This provides Android system developers with a flexible way to customize and extend system functionality.
4 Conclusion
Through this process, we learned how to customize and dynamically modify init.rc
files in the Android system. While this requires some familiarity with the Android build system, the process is relatively simple once the basic concepts are mastered.