Note that this thread is directed to ROM cookers, but can be used by anyone that knows how to edit ramdisk's.
So there are several problems with the regular init.d methods. First of all there are two different ways of executing the scripts and it differs from ROM to ROM which method has been implemented. We have the "exec /system/bin/sysinit" which will execute all of the scripts before continuing with the normal boot and we have the service sysinit which will execute all scripts while the normal boot is running. Both are useful for different things but no ROM has both.
Also init.d will just start executing the scripts before/during the normal boot, depended on the method, but what if we need it to execute something at a specific time during boot. Before folder structures and such are created in /data? Or when the phone has completely booted into the GUI. Or before the phone is turned off and so on.
This method will implement different states where different parts of a script can be executed depended on where in the boot process we are. All it requires is a more extended sysinit file and a couple of extra lines in the init.rc file.
on early-init ## # Whatever goes here ## on init ## # Whatever goes here ## on fs ## # Mount /system ## # Make sure that we have the synlinks we need to use sysinit symlink /system/bin/sysinit /system/bin/sysinit.onstart symlink /system/bin/sysinit /system/bin/sysinit.onfs symlink /system/bin/sysinit /system/bin/sysinit.onpostfs symlink /system/bin/sysinit /system/bin/sysinit.onpostfsdata symlink /system/bin/sysinit /system/bin/sysinit.onboot symlink /system/bin/sysinit /system/bin/sysinit.onsysinit symlink /system/bin/sysinit /system/bin/sysinit.onfinalize symlink /system/bin/sysinit /system/bin/sysinit.oncomplete symlink /system/bin/sysinit /system/bin/sysinit.onshutdown exec /system/bin/sysinit.onstart ## # Mount the rest of the partitions and remount /system without write permissions ## exec /system/bin/sysinit.onfs on post-fs ## # Whatever goes here ## exec /system/bin/sysinit.onpostfs on post-fs-data ## # Whatever goes here ## exec /system/bin/sysinit.onpostfsdata ## # If you want to include an additional *.rc file, do it here at the end of post-fs-data ## on boot ## # Whatever goes here ## exec /system/bin/sysinit.onboot start sysinit ## # Start any other services ## on property:init.svc.bootanim=stopped start syscomplete on property:sys.boot_completed=1 exec /system/bin/sysinit.onfinalize on property:sys.shutdown.requested=1 exec /system/bin/sysinit.onshutdown service sysinit /system/bin/sysinit.onsysinit disabled oneshot service syscomplete /system/bin/sysinit.oncomplete disabled oneshot ## # The rest of the file ##
#!/system/bin/sh export PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin if [ -d /system/etc/init.d ]; then case $(basename $0) in "sysinit") INIT_STATE="$1" ;; *) INIT_STATE="`basename $0 | cut -d '.' -f2`" ;; esac while : do if [ ! -f /sysinit.stage.prop ]; then mount -o remount,rw / touch /sysinit.stages.prop mount -o remount,ro / fi if ( [ "$INIT_STATE" != "onfinalize" ] && [ "$INIT_STATE" != "oncomplete" ] ) || ( [ "$INIT_STATE" = "onfinalize" ] && [ ! -z "`grep onpostsysinit /sysinit.stages.prop`" ] ) || ( [ "$INIT_STATE" = "oncomplete" ] && [ ! -z "`grep onfinalize /sysinit.stages.prop`" ] ); then if [ "$INIT_STATE" = "onsysinit" ]; then RUN_STATES="onsysinit onpostsysinit"; sleep 1 elif [ "$INIT_STATE" = "oncomplete" ]; then RUN_STATES="onservice oncomplete" else RUN_STATES="$INIT_STATE" fi for x in $RUN_STATES; do log -p v -t sysinit "Switching to state '$x'..." case $x in # Make it compatible with old init scripts onboot|"") FILES="`find /system/etc/init.d -type f | sort`" ;; *) FILES="`find /system/etc/init.d -type f -iname '*.rc' | sort`" ;; esac for i in $FILES; do if [ ! -d $i ] && [ -x $i ]; then log -p v -t sysinit "Executing $i..." if [ "$x" = "onservice" ]; then logwrapper $i $x > /dev/null & else logwrapper $i $x fi else log -p w -t sysinit "Skipping $i. Not an executable!" fi done mount -o remount,rw / echo $x >> /sysinit.stages.prop mount -o remount,ro / done break fi sleep 1 done fi
This will allow you to build init.d scripts like this
#!/system/bin/sh case $1 in onstart) # Do something right after the system partition has been mounted RW (No other partitions at this time) ;; onfs) # Do something right after the rest of partitions has been mounted and system has been remounted RO, before any of them are used or changed in any way. ;; onpostfs) # This is almost the same as onfs, only minor changes has normally been made here ;; onpostfsdata) # Do something after the /data partition has been rebuild with folders, permission, ownership and so on ;; onboot) # Do something right before Android starts booting and it's services are triggered ;; onsysinit) # Do something while Android is booting. This will NOT stall the boot process but run along side it ;; onpostsysinit) # Do something as soon as onsysinit has finished ;; onfinalize) # Do something when the system is almost booted, this also includes the sysinit parts above ;; onservice) # Do some constant work in the background (Service/Daemon) ;; oncomplete) # Do something when the phone is fully booted and the boot animation is gone ;; onshutdown) # Do something before the phone is turned off or rebooted ;; esac
- Added 'onfinalize' which is actually the old oncomplete. The new oncomplete runs as a service like onsysinit and onpostsysinit to ensure that you are able to use things like "sleep" without stalling the system.
- Rewrote sysinit, much cleaner now
- Added 'onservice' which can be used to run a constant task in the background after the phone has booted