FORUMS
Remove All Ads from XDA

[DEV][SCRIPT] Enhanced init.d support

3,526 posts
Thanks Meter: 5,039
 
By dk_zero-cool, Recognized Contributor on 24th May 2012, 10:57 PM
Post Reply Email Thread
Okay, I worked a bit on something to add a little more options to init.d scripts for my ROM's. I came up with the below solution and thought I should share it with whomever would like a bit more options in their own ROM's. This is a first draft so some of things can properly be done in other ways, but it works and it does add a lot more options when building startup scripts while it is compatible with regular init.d scripts as well. But fell free to pitch in with ideas if you like.

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.

File: /init.rc
Code:
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
##
File: /system/bin/sysinit
Code:
#!/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
To use this you need to end the names of your init script with .rc like "55<name>.rc" instead of just "55<name>". This is to keep it compatible with regular init.d scripts.

This will allow you to build init.d scripts like this
Code:
#!/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

EDIT 1
  • 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

EDIT 2
  • Added 'onservice' which can be used to run a constant task in the background after the phone has booted
The Following 28 Users Say Thank You to dk_zero-cool For This Useful Post: [ View ] Gift dk_zero-cool Ad-Free
 
 
25th May 2012, 07:04 AM |#2  
tommytomatoe's Avatar
Inactive Recognized Developer
Flag Knoxville USA
Thanks Meter: 6,839
 
Donate to Me
More
Great concept and great work :)

I can see how this would be very handy!

Sent from my PG86100 using Tapatalk 2
25th May 2012, 05:55 PM |#3  
c_shekhar's Avatar
Inactive Recognized Developer
Thanks Meter: 39
 
More
looks intresting..Hmmmmm
27th May 2012, 12:47 AM |#4  
Member
Flag Kansas City
Thanks Meter: 15
 
More
Genius man. Awesome stuff.

Sent from my SCH-I500 using Tapatalk 2
28th May 2012, 04:34 AM |#5  
jayallen1980's Avatar
Senior Member
Thanks Meter: 11
 
More
Awesome great work. The last line say do comething before the phone is turned off or rebooted. is it suppose to say something.

Sent from my HTC Desire CDMA using Tapatalk 2
28th May 2012, 08:50 AM |#6  
dk_zero-cool's Avatar
OP Recognized Contributor
Flag Horsens
Thanks Meter: 5,039
 
More
Quote:
Originally Posted by jayallen1980

Awesome great work. The last line say do comething before the phone is turned off or rebooted. is it suppose to say something.

Sent from my HTC Desire CDMA using Tapatalk 2

'something' is correct, have been changed
30th May 2012, 03:39 PM |#7  
varun.chitre15's Avatar
Recognized Developer
Flag Sangli
Thanks Meter: 15,621
 
Donate to Me
More
Some examples would be good
Can you please? (Example of Executing Juwe's RAM script will be nice in all cases)
What if I want to keep init.d folder empty and integrate my scripts inside boot.img? and then execute them inside it?
30th May 2012, 03:50 PM |#8  
dk_zero-cool's Avatar
OP Recognized Contributor
Flag Horsens
Thanks Meter: 5,039
 
More
Quote:
Originally Posted by varun.chitre15

Some examples would be good
Can you please? (Example of Executing Juwe's RAM script will be nice in all cases)
What if I want to keep init.d folder empty and integrate my scripts inside boot.img? and then execute them inside it?

Why would you integrate scripts into the boot.img? The point of init.d is to be able to add things to boot without changing the boot.img. If you want to execute things from within the boot.img, then just place your scripts in it (sbin would be a good place) and execute it the same way my example executes /system/bin/sysinit.

And as for examples, it's easy. Just place your code in that section (onboot, onfs etc) where you want the code to be executed. The onboot is the default in process in most ROM's and also where regular init.d scripts is executed in this example.
The Following User Says Thank You to dk_zero-cool For This Useful Post: [ View ] Gift dk_zero-cool Ad-Free
29th June 2012, 05:07 PM |#9  
eugene373's Avatar
Retired Recognized Developer
Thanks Meter: 7,490
 
Donate to Me
More
Quote:
Originally Posted by dk_zero-cool

Why would you integrate scripts into the boot.img? The point of init.d is to be able to add things to boot without changing the boot.img. If you want to execute things from within the boot.img, then just place your scripts in it (sbin would be a good place) and execute it the same way my example executes /system/bin/sysinit.

And as for examples, it's easy. Just place your code in that section (onboot, onfs etc) where you want the code to be executed. The onboot is the default in process in most ROM's and also where regular init.d scripts is executed in this example.

because the point of this is to start scripts when you want.. there is a few scripts I have that can't be ran until os is loaded, there for making this a great setup for me.

init.d & boot.img runs everything at boot... not after boot.
29th June 2012, 05:53 PM |#10  
dk_zero-cool's Avatar
OP Recognized Contributor
Flag Horsens
Thanks Meter: 5,039
 
More
Quote:
Originally Posted by eugene373

because the point of this is to start scripts when you want.. there is a few scripts I have that can't be ran until os is loaded, there for making this a great setup for me.

init.d & boot.img runs everything at boot... not after boot.

The 'oncomplete' runs everything when the system is fully loaded, that's the point of this init.d system, to be able to run scripts in different ways during different stages.
The Following User Says Thank You to dk_zero-cool For This Useful Post: [ View ] Gift dk_zero-cool Ad-Free
29th June 2012, 06:58 PM |#11  
eugene373's Avatar
Retired Recognized Developer
Thanks Meter: 7,490
 
Donate to Me
More
Quote:
Originally Posted by dk_zero-cool

The 'oncomplete' runs everything when the system is fully loaded, that's the point of this init.d system, to be able to run scripts in different ways during different stages.

yeah I got it..... I've been having one hell of a time starting script until I cam across this...

If it starts like a normal init.d file it hangs the boot process... with this edit I can trigger it to run on bootcomplete with out hanging the service

sorry, I just noticed I quoted you and not the other guy
Post Reply Subscribe to Thread
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes