I've determined the full list of requirements for init.d support in Android. I'll list them here:
Remember: Your phone is your responsibility. I am providing you information via cited documentation, but not support. Be careful and take the time to understand what you are doing before you do it.
Mount /system as RW:
This is a temporary change, needed to make changes to any other properties related to init.d. First, check your mounts by running mount from a terminal. You'll need to look for the /system mount for all the parameters needed to remount it. I recommend using grep to parse the output.
Code:
mount | grep "/system"
As an example, I wrote the command below for a Samsung Galaxy Nexus running 4.0.4 (ICS), or 4.1.1 (JB), but it may work on other devices.
Code:
mount -o remount,rw /dev/block/platform/omap/omap_hsmmc.0/by-name/system /system
Permissions
Check permissions using ls -l
If you need to change permissions or owners, read up on chmod and chown
/etc/init.d/ should look like this:
Code:
drwxr-xr-x root shell 2012-04-06 13:41 init.d
If your /etc/init.d doesn't look like the above, then run the following commands:
Code:
chown root.shell /etc/init.d
chmod 755 /etc/init.d
Scripts should look like this:
Code:
-rwxr-xr-x root shell 757 2012-04-06 13:41 99hostname
If your script permissions don't match the above (-rwxr-xr-x), then run the following command:
Code:
chown root.shell /etc/init.d/*
chmod 755 /etc/init.d/*
BusyBox
BusyBox provides several stripped-down Unix tools in a single executable.[1] Many ROMs include BusyBox, and it can be installed on a rooted stock ROM too. Stericson's BusyBox Installer can verify that you have it, and install it if you don't (requires root).
The applet we need is run-parts, which parses a folder for scripts, and executes each one in alpha-numeric order.
Path to BusyBox binary:
Code:
/sbin/bb/busybox
Path to all BusyBox symbolic links:
Code:
/system/xbin/
/init.rc:
Code:
service run_parts /sbin/bb/busybox run-parts /system/etc/init.d
class main
oneshot
CleanUp
Don't forget to remount your /system as RO once you've finished modifying files there. This can protect you from accidental (unintentional, unexpected) changes. The command below assumes, once again, that you are using a Samsung Galaxy Nexus running 4.0 (ICS) or 4.1 (JB):
Code:
mount -o remount,ro /dev/block/platform/omap/omap_hsmmc.0/by-name/system /system
Uses for init.d:
Using init.d, you can:
Enable SWAP / ZRAM (if your Kernel supports it)
Change network properties (hostname, netcfg, ifconfig)
Mount filesystems automatically
???
Pandages said:
I've determined the full list of requirements for init.d support in Android. I'll list them here:
Click to expand...
Click to collapse
thanks man, very informative. should be quite useful for the ones looking for this. should either be sticked or linked to in this thread's first post. this is the kind of howto we need, not some copy/paste from official information.
regards,
bk201
bk201doesntexist said:
thanks man, very informative. should be quite useful for the ones looking for this. should either be sticked or linked to in this thread's first post. this is the kind of howto we need, not some copy/paste from official information.
Click to expand...
Click to collapse
I'm happy to help. I'm an engineer by trade, so I'm used to sharing any information I find when researching a specific problem. I hope this post is of assistance to someone. Please link to it if it helps you!
So I do all that on a stock rom and init.d should work?
Edit: Nevermind, just found EZ InitD answering my stock rom questions.
Thanks for the info regardless!
[JB] JellyBean Update
Regarding Android 4.1 (JellyBean):
All the rules I've documented above still apply:
/etc/init.d needs to exist
/etc/init.d needs to be owned by root.shell (chown root.shell /etc/init.d)
/etc/init.d needs to have the correct permissions (chmod 755 /etc/init.d)
scripts need to be in .sh format, but with the extension removed (i.e. 99hostname)
scripts need to have the correct permissions (chmod 755 /etc/init.d/*)
busybox needs to be installed
init.rc needs to register the run-parts service (/sbin/bb/busybox run-parts /system/etc/init.d)
If you follow these rules. init.d will work as intended! :victory:
Update on MMuzzy's AOSP 4.2.1:
Stock kernel does not support init.d. I recommend imoseyon's leankernel, which does support it. init.rc also does not include the run-parts service. Busybox is not included. However, once all these issues are handled, as described in the OP, init.d works as intended.
franco.Kernel also includes init.d in its ramdisk making it work for stock ROM (and others) where no init.d support is included.
init.d can have owner/group of root.root with no issues, and the easy way to set the permissions is chmod -R 755 /system/etc/init.d
The Android Shell
A "shell" is a program that listens to keyboard input from a user and performs actions as directed by the user. Android devices come with a simple shell program. This shell program is mostly undocumented. Since many people are curious about it I thought I'd write up some documentation for it.
Currently this documentation is incomplete, sorry!
Common problems
The built-in shell has very limited error handling. When you type a command name incorrectly it will say "permission denied", even though the real problem is that it couldn't find the command:
$ dir
dir: permission denied <---- this is a misleading error message, should say 'dir: not found'
$ ls
... listing of current directory
The PATH variable
The Android shell will run any program it finds in its PATH. The PATH is a colon (':') seperated list of directories. You can find out what your shell's PATH is set to by using the built-in echo command:
$ echo $PATH
/data/local/bin:/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
Depending upon your shell, you may see a different result.
Built in Commands
Every shell has a few built-in commands. Some common built-in commands are:
echo -- prints text to stdout.
set -- sets shell variables
export -- makes shell variables available to command-line programs
cd -- change the current directory.
pwd -- print name of the current directory.
Commands
To find out what commands you have available to you, use the "ls" command on each of the directories in the PATH variable.
Finding documentation for the Android commands.
Many of the Android commands are based on standard Linux (or bsd) commands. If you're curious about a command, you can sometimes learn how it works by using the "man" command on a desktop Linux or OSX (Apple Macintosh) computer. The Linux or OSX version of the command may be different in details, but much of the documentation will still apply to the Android version of the command.
Another source of documentation for people without a Linux or OSX machine handy is to use a web browser and use a web search engine to search for the text: "man Linux command-name".
List of commands
The following is a list of the commands that are present on a Nexus S phone running an Android 2.3.3 "user-debug" build. Many of these commands are not present on a "user" phone. (They are missing from a "user" phone because they are specific to developing or debugging the Android operating system.)
$ ls /data/local/bin
/data/local/bin: No such file or directory
Notice that by default there is no /data/local/bin directory. You can create this directory using the "mkdir" command if you like.
$ ls /sbin
opendir failed, Permission denied
The /sbin directory exists, but you don't have permission to access it. You need root access. If you have a developer phone, or otherwise have root access to your phone you can see what's in this directory.
$ su
# ls /sbin
ueventd
adbd
# exit
$
Notice that the shell prompt changes from a '$' to a '#' to indicate that you have root access.
Notice also that neither of the /sbin commands are useful to the shell -- the adb and ueventd files are 'daemon' programs used to implement the Android Debugger "adb" program that is used by developers.
$ ls /vendor/bin
gpsd
pvrsrvinit
Vendor/bin is where device vendors can put device-specific executables. These files are from a Nexus S.
$ ls /system/sbin
/system/sbin: No such file or directory
This directory does not exist on a Nexus S.
$ ls /system/bin
am
am is the Android Activity Manager. It's used to start and stop Android activities (e.g. applications) from the command line. Type am by itself to get a list of options.
amix
aplay
Command line audio file player.
app_process
applypatch
Used to apply patches to android files.
arec
Command line audio recorder.
audioloop
bluetoothd
BlueTooth daemon
bmgr
Backup manager - type command by itself to get documentation.
bootanimation
Draws the boot animation. You may have to reset your phone to get out of this.
brcm_patchram_plus
bugreport
cat
Copy the contents of a file to standard output.
chmod
Change the mode of a file (e.g. whether it can be read or written.)
chown
Change the owner of a file.
cmp
Compare two files byte-by-byte
dalvikvm
The dalvik virtual machine. (Used to run Android applications.)
date
Prints the current date and time
dbus-daemon
dd
Convert and copy a file. By default copies standard in to standard out.
debuggerd
dexopt
df
Shows how much space is free on different file systems on your device.
dhcpcd
dmesg
dnsmasq
dumpstate
dumpsys
dvz
fsck_msdos
gdbserver
getevent
getprop
gzip
hciattach
hd
id
ifconfig
Shows the current configuration of network interfaces (IP, MAC address etc)
iftop
Shows the current processes using the network interfaces (top, but for networks)
ime
input
insmod
installd
ioctl
ionice
iptables
Manage the firewall
keystore
keystore_cli
kill
Send signals to processes.
linker
ln
Used to set up a file system link.
log
logcat
Prints the Android runtime log.
logwrapper
ls
Lists files.
lsmod
lsof
make_ext4fs
mediaserver
mkdir
Make a directory.
monkey
A program that sends random events, used to test applications. (Like having a monkey playing with the device.)
mount
mtpd
mv
Move a file from one directory to another. (Only on the same file system. Use "cat a > b" to copy a file between file systems.
nandread
ndc
netcfg
netd
netstat
newfs_msdos
notify
omx_tests
pand
ping
pm
pppd
printenv
ps
List active processes.
qemu-props
qemud
racoon
radiooptions
reboot
Reboot the device.
record
renice
rild
rm
Remove a file.
rmdir
Remove a directory.
rmmod
route
rtp_test
run-as
schedtest
schedtop
sdcard
sdptool
sendevent
service
servicemanager
setconsole
setprop
setup_fs
sh
showlease
sleep
smd
stagefright
start
Starts the Android runtime.
stop
Stops the Android runtime.
surfaceflinger
svc
sync
system_server
tc
testid3
toolbox
top
Shows which processes are currently using the most CPU time.
umount
uptime
Prints how long your device has been running since it was last booted.
vdc
vmstat
vold
watchprops
wipe
wpa_cli
wpa_supplicant
$ ls /system/xbin
add-property-tag
btool
check-lost+found
dexdump
dhdutil
hcidump
latencytop
librank
opcontrol
oprofiled
procmem
procrank
rawbu
scp
Secure copy program. (Used to copy files over the network.)
showmap
showslab
sqlite3
Used to administer SQLite databases.
strace
System trace command - use to see what system calls a program makes.
su
Start a shell with root privileges.
Versions of the Android Shell
Android 1.0 used a shell that had no tab completion or history editing.
Android 2.3 added history editing. You can for example use the up/down arrows to edit previous commands.
I have a very simple script to mount my NAS to a specific path that I want executed every time my FireTV boots.
I have read about pointing to it in the install-recovery-2.sh, however that is not available on my FireTV. I have also read about placing the script in system/etc/init.d/ however that path doesn't exist on the fireTV either.
Would prefer to do this at the system level and not rely on a manager (Tasker, Script Manager, etc).
Anyone have any experience?
Update w/ solution:
I was able to get this working by placing a script called install-recovery.sh in /system/etc/ . Make sure that permissions are set appropriately (at least 755). If creating the script on a Windows machine, make sure there aren't any hidden whitespace characters (I personally verified the script using SManager on my Fire TV).
Code:
[B]sleep 15[/B]
mkdir /mnt/obb/nas
chmod 777 /mnt/obb/nas
[B]sleep 20[/B]
mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
The sleep command is necessary as the script may run before the network is initialized.
Thanks rbox and ECEXCURSION!
patrickorr said:
I have a very simple script to mount my NAS to a specific path that I want executed every time my FireTV boots.
I have read about pointing to it in the install-recovery-2.sh, however that is not available on my FireTV. I have also read about placing the script in system/etc/init.d/ however that path doesn't exist on the fireTV either.
Would prefer to do this at the system level and not rely on a manager (Tasker, Script Manager, etc).
Anyone have any experience?
Click to expand...
Click to collapse
/system/etc/install-recovery.sh
rbox said:
/system/etc/install-recovery.sh
Click to expand...
Click to collapse
That file does not exist in /system/etc/ on my FireTV
patrickorr said:
That file does not exist in /system/etc/ on my FireTV
Click to expand...
Click to collapse
Yes... you have to create it...
rbox said:
Yes... you have to create it...
Click to expand...
Click to collapse
Ahh, sorry a little dense
Will give that a shot and report back on the results
Ok, I have placed install-recovery.sh (which houses my mounting script) in /system/etc/
I reboot and it doesn't appear that the script has run. Is there anything else I would need to do in order to get it to run on boot?
If it matters here are the details on my FireTV
Custom Recovery 6.0.5.1.4a
Pre-rooted 51.1.4.1_514013920
patrickorr said:
Ok, I have placed install-recovery.sh (which houses my mounting script) in /system/etc/
I reboot and it doesn't appear that the script has run. Is there anything else I would need to do in order to get it to run on boot?
If it matters here are the details on my FireTV
Custom Recovery 6.0.5.1.4a
Pre-rooted 51.1.4.1_514013920
Click to expand...
Click to collapse
And you're sure the script works?
rbox said:
And you're sure the script works?
Click to expand...
Click to collapse
That is a very good question How can I test that my script is functioning?
From adb shell or Terminal emulator I type the following commands to mount my NAS:
Code:
su
cd /mnt/obb/
mkdir nas
chmod 777 nas
mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
To turn this into a script I just dumped it into notepad and added #!/system/bin/sh to the top and saved it as install-recovery.sh.
patrickorr said:
That is a very good question How can I test that my script is functioning?
From adb shell or Terminal emulator I type the following commands to mount my NAS:
Code:
su
cd /mnt/obb/
mkdir nas
chmod 777 nas
mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
To turn this into a script I just dumped it into notepad and added #!/system/bin/sh to the top and saved it as install-recovery.sh.
Click to expand...
Click to collapse
Run it from adb, but right off the bat, I can tell you you need to chmod 755 it atleast before that will work.
rbox said:
Run it from adb, but right off the bat, I can tell you you need to chmod 755 it atleast before that will work.
Click to expand...
Click to collapse
Ok, was able to run the script, but got the following error(s):
Code:
127|[email protected]:/system/etc # sh ./install-recovery.sh
sh ./install-recovery.sh
: not foundecovery.sh[2]:
: not foundecovery.sh[3]: su
: No such file or directoryd: /mnt/obb/
, Read-only file system
: No such file or directory
mount: No such file or directory
patrickorr said:
Ok, was able to run the script, but got the following error(s):
Code:
127|[email protected]:/system/etc # sh ./install-recovery.sh
sh ./install-recovery.sh
: not foundecovery.sh[2]:
: not foundecovery.sh[3]: su
: No such file or directoryd: /mnt/obb/
, Read-only file system
: No such file or directory
mount: No such file or directory
Click to expand...
Click to collapse
Well first of all, don't run it with sh... it needs to have #!/system/bin/sh at the top, and you need to run it directly. Second, don't put su in it because it's already running in the root context.
rbox said:
Well first of all, don't run it with sh... it needs to have #!/system/bin/sh at the top, and you need to run it directly. Second, don't put su in it because it's already running in the root context.
Click to expand...
Click to collapse
How would I run it directly?
Here is my current script (with su removed):
Code:
#!/system/bin/sh
cd /mnt/obb/
mkdir nas
chmod 777 nas
mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
patrickorr said:
How would I run it directly?
Here is my current script (with su removed):
Code:
#!/system/bin/sh
cd /mnt/obb/
mkdir nas
chmod 777 nas
mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
Click to expand...
Click to collapse
Just type:
/system/etc/install-recovery.sh
rbox said:
Just type:
/system/etc/install-recovery.sh
Click to expand...
Click to collapse
I am attempting to run that in adb shell, but am getting the following errors:
Code:
[email protected]:/ $ cd /system/etc/
cd /system/etc/
[email protected]:/system/etc $ stat -c "%a %n" install-recovery.sh
stat -c "%a %n" install-recovery.sh
777 install-recovery.sh
[email protected]:/system/etc $ /system/etc/install-recovery.sh
/system/etc/install-recovery.sh
/system/bin/sh: /system/etc/install-recovery.sh: No such file or directory
1|[email protected]:/system/etc $ ./system/etc/install-recovery.sh
./system/etc/install-recovery.sh
/system/bin/sh: ./system/etc/install-recovery.sh: not found
127|[email protected]:/system/etc $
It seems like the permissions are correct on the file, and I also tried adding ./ before the path to see if that made any differences.
I made a slight "upgrade" to my script to see if it would help (but as you can probably already see, I am not exactly sure what I am doing!):
Code:
#!/system/bin/sh
mkdir /mnt/obb/nas
chmod 777 /mnt/obb/nas
busybox mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
patrickorr said:
I am attempting to run that in adb shell, but am getting the following errors:
Code:
[email protected]:/ $ cd /system/etc/
cd /system/etc/
[email protected]:/system/etc $ stat -c "%a %n" install-recovery.sh
stat -c "%a %n" install-recovery.sh
777 install-recovery.sh
[email protected]:/system/etc $ /system/etc/install-recovery.sh
/system/etc/install-recovery.sh
/system/bin/sh: /system/etc/install-recovery.sh: No such file or directory
1|[email protected]:/system/etc $ ./system/etc/install-recovery.sh
./system/etc/install-recovery.sh
/system/bin/sh: ./system/etc/install-recovery.sh: not found
127|[email protected]:/system/etc $
It seems like the permissions are correct on the file, and I also tried adding ./ before the path to see if that made any differences.
I made a slight "upgrade" to my script to see if it would help (but as you can probably already see, I am not exactly sure what I am doing!):
Code:
#!/system/bin/sh
mkdir /mnt/obb/nas
chmod 777 /mnt/obb/nas
busybox mount -o noperm,unc=\\\\192.168.1.147\\Public,username=xxxxxx,password=xxxxxx -t cifs none /mnt/obb/nas
Click to expand...
Click to collapse
That sounds strange... but you'll need to run su before running it, because it needs root. It could be that its not in UNIX file format. If you edited it on Windows you need to use an advanced editor that has the ability to save as UNIX format.
rbox said:
That sounds strange... but you'll need to run su before running it, because it needs root. It could be that its not in UNIX file format. If you edited it on Windows you need to use an advanced editor that has the ability to save as UNIX format.
Click to expand...
Click to collapse
Unix file format appears to have been the issue. When I opened it with SManager I saw some nasty whitespace characters. Removed those and the script works as expected:
Code:
[email protected]:/data/media/0 # ./install-recovery.sh
./install-recovery.sh
[email protected]:/data/media/0 # cd /mnt/obb/nas
cd /mnt/obb/nas
[email protected]:/mnt/obb/nas # ls
ls
Games
Photos
Shared Music
Shared Videos
eBooks
key.txt
[email protected]:/mnt/obb/nas #
After confirming the script worked as expected, I moved it to /system/etc/ and verified permissions were acceptable (777). Upon reboot I see that the /mnt/obb/nas is created, however the NAS is not mapped.
Can you comment, when is the install-recovery.sh called in the boot up process? Is it possible that the CIFS module isn't fully loaded when this is called? Alternatively, is there a log that I could reference to see if any error occurred while running the script at startup?
patrickorr said:
Unix file format appears to have been the issue. When I opened it with SManager I saw some nasty whitespace characters. Removed those and the script works as expected:
Code:
[email protected]:/data/media/0 # ./install-recovery.sh
./install-recovery.sh
[email protected]:/data/media/0 # cd /mnt/obb/nas
cd /mnt/obb/nas
[email protected]:/mnt/obb/nas # ls
ls
Games
Photos
Shared Music
Shared Videos
eBooks
key.txt
[email protected]:/mnt/obb/nas #
After confirming the script worked as expected, I moved it to /system/etc/ and verified permissions were acceptable (777). Upon reboot I see that the /mnt/obb/nas is created, however the NAS is not mapped.
Can you comment, when is the install-recovery.sh called in the boot up process? Is it possible that the CIFS module isn't fully loaded when this is called? Alternatively, is there a log that I could reference to see if any error occurred while running the script at startup?
Click to expand...
Click to collapse
It's probably running before the network comes up. There might be maybe some kind of regular android apk that will run a script when the network comes up. There might be a way to just stick a loop in your current script waiting for something, not sure.
You could probably just add "sleep 30" to the beginning of the script.
rbox said:
It's probably running before the network comes up. There might be maybe some kind of regular android apk that will run a script when the network comes up. There might be a way to just stick a loop in your current script waiting for something, not sure.
Click to expand...
Click to collapse
ECEXCURSION said:
You could probably just add "sleep 30" to the beginning of the script.
Click to expand...
Click to collapse
Thanks, will give that a try when I get back home.
Edit: It worked! Thanks to the both you for your input.
Just wondering since I'm a newbie when it comes to this one. Does mounted folder have to be in /mnt/obb or can I choose any directory I want?