Forcing the Android emulator to store changes to /system - android

I know this is a recurrent question when working with the Android emulator, but is there a way to force the emulator to accept persistent changes to /system?
The emulator is based on QEMU, so it should be possible, in theory, to force the system image to behave the same way userdata (for instance) does, but I'm not familiar with how QEMU handles things. Any pointers?

At the moment (with Build Tools v26, if Google doesn't change things as often as they do) if you use the -writable-system directive while booting up the emulator from the command line, it will allow persistence to the /system partition through reboots. That is you will be able to write to the /system partition and if you reboot, the changes will still be maintained.
emulator -avd <AVD_NAME> -writable-system
This will also persist your changes to a qcow2 image file usually in .android/avd/<AVD_NAME>.avd/system.img.qcow2
You can even copy this system.img.qcow2 file, wipe the data off the AVD using the -wipe-data directive, place this file back into the directory, reboot and the system changes you made initially will still be persisted. (Caveat: at least for now, coz Google keeps changing things)

Update: The -nand option was apparently removed from the most recent versions of QEMU, so the following may not work anymore.
Update: See the accepted answer for the current way of doing things.
Yury's answer is the common one, but if you want to be able to script things (which is what I want in the end), you need to be able to find the emulator image in the /tmp directory.
I discovered that you can override QEMU's behavior. This is a bit hackish, but it works, so I ended up doing this :
Copy system.img from the platform directory to your AVD directory.
Convert the amount of space you need to hex. For instance, if you need 500M, this is 0x1f400000.
Run the emulator in read-write mode :
emulator -avd Galaxy_Nexus -qemu -nand system,size=0x1f400000,file=/home/fx/.android/avd/Galaxy_Nexus/system.img
(If you put the emulator in verbose mode, you'll notice that it will, by default, use initfile= instead of just file=)
Make your changes, they are immediately saved to the local system.img
Now you can just start the emulator with emulator -avd Galaxy_Nexus, and it'll use your changes
Update: If scripting, QEMU does not sync changes immediately to the image, so if you're rebooting immediately after changing something, chances are you will lose data. I'm looking for a way around this...
Next update: Use adb -e emu kill to stop the emulator. reboot will just do bad things.

It's actually a very good question. I had the same troubles. Here are my findings. Actually, I use Ubuntu and I'll describe the steps for Ubuntu. If you use Windows, you should just change the paths.
Create new AVD, for instance example.avd
Copy system.img from android-sdk-linux/platforms/android-10/images
to ~/.android/avd/example.avd
Make system.img as writable and readable (either in the properties
or simply using terminal)
Run your AVD using command emulator -avd example
Remount your system as rw using adb shell mount -o rw,remount -t
yaffs2 /dev/block/mtd0 /system (to discover the partition use
command cat /proc/mtd)
Make your changes...
Now during the run of emulator find tmp emulator in
/tmp/android-<your_computer_name> with strange name like:
emulator-PQ7LgE and copy it in ~/.android/avd/example.avd
Delete system.img and rename copied tmp emulator into system.img
Close emulator
Delete cache.img, userdata.img and userdata-qemu.img from
~/.android/avd/example.avd
Run your emulator once again
Good luck!

The solution #2 is amazing.
Here are some hints if you are using MS Win as host
AVD directories are located as below, but the "short" path names should be used
as file= path parameter. The quoted path variant doesn't work for some reason.
Win XP: C:\Documents and Settings\ (username) \ .android\avd\ ...
Short C:\DOCUME~1\ (username) \ANDROI~1\avd\ ...
Win 7 C:\Users\ (username) \ .android\avd\ ...
You can create an own bat file, say "startrw.bat" as per following example:
#echo off
C:\<ADTFOLDER>\sdk\tools\emulator -avd <AVDNAME> -qemu -nand system,size=0x1f400000,file=C:\DOCUME~1\<USERNAME>\ANDROI~1\avd\<AVDNAME>.AVD\system.img
cd C:\<ADTFOLDER>\sdk\platform-tools
echo .
echo Wait ...
echo .
echo When emulator is FULLY loaded press any key to connect adb shell to it
echo To make /system writeable type in adb shell:
echo .
echo -----------------------------
echo mount -o rw,remount /system
echo -----------------------------
echo .
echo You can use the Eclipse ADT DDMS File Browser to browse or push-pull files now.
echo .
echo Closing this window closes the emulator !
echo .
echo Wait emulator to load Android. When done
pause
C:\<ADTFOLDER>\sdk\platform-tools\adb shell
This way you can load in one click.
Once finished modifying, just close the current command window to kill the emulator.
It takes long time for most of things to load like Emulator, the ADT editor, Hooking DDMS file browser (you need to click on the emulator line left side to see the files tree on right window) and so on.

I had trouble finding the system.img file and AVD directory that F.X. posted about. On Mac you can find them here:
system.img: ~/Library/Android/sdk/system-images/android-19/default/
AVD Directory: ~/.android/avd/Nexus.avd/
I don't have enough reputation to add it as a comment, so I had to post it like this. Sorry.

use this command in terminal
cd /Users/NAME_USER/Library/Android/sdk/emulator # Move to emulator folder
sudo ./emulator -writable-system -avd NAME_AVD -partition-size 280 # Run avd by writable system
sudo adb root # Change to root
sudo adb remount # remount again
sudo adb shell
su
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
change NAME_USER and NAME_AVD

F.X.'s answer does not work for me with Android API 19 and 21 on Windows as it stands. With the given parameters
emulator -avd <AVD> -qemu -nand system,size=0x<SIZE IN HEX>,file=<PATH/TO/system.img>
the system fails to mount the image. By looking at the kernel output I found out that it uses suspicious page size (2048) and two nonzero parameter values: extra size and "erase". These parameters are not documented anywhere, but you can see them in qemu's source code. What ended up working for me was
emulator -avd <AVD> -qemu -nand system,size=0x<SIZE IN HEX>,file=<PATH/TO/system.img>,pagesize=512,extrasize=0
With those parameters specified, "erase" gets set to 0 as well.
I was also surprised to find out that with these parameters the system is unable to boot to the graphical environment, but adb works.

The best way to do this is to use the following command:
<path-to-emulator-executable> -avd <AVD> -partition-size 512

As said here at https://justus.berlin/2015/02/make-persistent-changes-to-system-in-android-emulator/
Copying system.img into avd folder will work.

New year new solutions.
Just copy the system.img to your avd folder and rename the system.img to system-qemu.img
For me, copying C:\Android\sdk\system-images\android-22\android-tv\armeabi-v7a\system.img
to C:\Users\Neil Agarwal\.android\avd\Android_TV_1080p_API_22.avd\
and renaming it to system-qemu.img did the trick.
Please restart your avd after this.

Related

How to make system partition in AVD in emulator writable

This is fairly a very old question but I am surprised that none of the solutions are working for me. I need to run an android app as system app in an AVD (in emulator) created for Android version 7.0. For this, I want to push apk file to system partition but I keep getting error saying it is read only file system. I found many similar questions on stackoverflow but nothing is working for me. I restarted adb in root, executed it with remount as suggested in answers to similar questions, but system partition file system permissions do not change. Here is a sample session:
mvsagar#mvslt:~/sw/android_sdk/platform-tools$ ./adb root
restarting adbd as root
mvsagar#mvslt:~/sw/android_sdk/platform-tools$ ./adb remount
remount succeeded
mvsagar#mvslt:~/sw/android_sdk/platform-tools$ ./adb push /home/mvsagar/projects/AndroidStudioProjects/LcnApps/app/LCNUE.apk /system/app/LCNUE.apk
adb: error: failed to copy '/home/mvsagar/projects/AndroidStudioProjects/LcnApps/app/LCNUE.apk' to '/system/app/LCNUE.apk': couldn't create file: Read-only file system
I have tried manually remounting with read/write(rw) options using adb shell, but the remounting fails.
Is there any way to have read/write permission on system partition?
My dev env is Android Studio on Ubuntu.
In my case, I use a avd( Based on: Android 8.0 (Oreo) Tag/ABI: google_apis/x86_64 ).
$ emulator -avd Nexus_5X_API_26_APIs -writable-system
$ adb root
$ adb remount
Then, /system is writeable.
$ adb push somefile /system/bin/ is work.
When working with Q, this is the only solution that worked for me: https://stackoverflow.com/a/64397712/1898527
Adding here the steps for completion (kudos to the original author):
> emulator -avd Pixel_3a_XL_API_29 -writable-system
> adb shell avbctl disable-verification
> adb disable-verity
Now reboot your emulator so that the changes take effect.
> adb root
> adb remount
> adb shell "su 0 mount -o rw,remount /system"
Note: you will need an emulator without Google Play, otherwise this won't work. You can get it by following the steps described here: https://stackoverflow.com/a/45668555/1898527
use genymotion emulator, which is faster, light weight and pre rooted. (which means you can access system directory)
For the benefit of others, answer to the question was answered a long ago by #Ishamael in another stackoverflow question Read only file system on Android

Android bootanimation doesn't work (permissions error)

Recently I designed my own android bootanimation.zip file. I'm very proud of it and would like to make it my boot animation (the graphic that shows up when you start up your phone). However, I ran into a complication that I can't seem to solve or find any solutions to online.
Info: I'm running Cyanogen 12 on a Motorola Nexus 6. I placed my bootanimation.zip in the /system/media folder (and /data/local, but that didn't work).
The issue (read carefully please!):
I have confirmed that my bootanimation.zip file IS formatted correctly and DOES display properly. When I enter my phone's shell as root I can properly execute the /system/bin/bootanimation command. This command simply previews bootanimation. However, I can't execute the binary as non-root (which I should be able to do). I even went as far as changing the ownership of bootanimation to the shell (non-root account). Basically, I see something like this.
shell> bootanimation #/system/bin/bootanimation should by in my $PATH
/system/bin/sh: bootanimation: not found
shell> cd /system/bin
shell:/system/bin> ls bootanimation
bootanimation: Permission denied
shell:system/bin> ./bootanimation
/system/bin/sh: ./bootanimation: not found
shell:system/bin> su #log in as root
root> cd /system/bin
root:/system/bin> ls -l bootanimation
-rwxr-xr-x shell shell 34252 2015-11-03 11:07 bootanimation
Finally, the device is clearly unable to execute this on startup because the boot animation is never displayed, instead a silver 'google' is displayed.
I appreciate any input, thanks.

Copy full disk image from Android to computer

I have a smartphone without the possibility to insert an SD-card.
I would like to make a dump of the biggest partition (cause I lost files and I'd like to use a dump to recover them).
The partition is 10GB.
I was looking for an ADB command to pull using dd but nothing...
I tried to use Carliv touch recovery with a 32GB usb key by OTG but the USB key didn't mount ... Then I couldn't use "dd" directly on the phone using Aroma file manager and a terminal emulation.
Thank you!
I don't understand why they closed a question that has already an accepted answer by linking a completely different question. Copying a file and copying a partition are 2 different things.
As said in comment, adb pull /dev/block/mmcblk0 mmcblk0.img worked for me. A "DD image" is only a binary image file of the device.
You want to copy a disk from your android device to your computer (preferably on your fastest drive) for faster and lossless analysis/recovery.
This is short step-by-step guide in windows (linux: scroll down) to achieve it using the linux tool dd intended for precise, bit-wise copies of data. Credits go to scandium on xda for the code, see his post for more details.
Prerequisites
make sure your device is rooted and busybox is installed
Windows:
install cygwin. During install, add netcat (under Net) and pv (under util-linux) packages; the standard install is located in C:\ so make sure you have enough disk space beforehand;
install adb e.g. through Android Studio. Make sure to add adb.exe executable file to the path variable to access it properly (guide).
Open two cygwin consoles/terminals (one sending data, one receiving data) and enter in one of the terminals to enter the device:
# terminal 1
adb forward tcp:5555 tcp:5555 # forward data over tcp connection
adb shell # open a connection
su # gain root access
BUSYBOX=/system/xbin/busybox # default location for most bb installers
# note: adapt the variable `BUSYBOX` to point to your install directory
# the TWRP default is `BUSYBOX=/sbin/busybox` (in case of bricked device)
Decide what partition to copy, the /dev/block/mmcblk0 partition is usually the one containing the data you typically would want.
In the following code, adapt the partition name according to 4. and quickly one after another type in terminal 1 and terminal 2:
# terminal 1
$BUSYBOX nc -l -p 5555 -e $BUSYBOX dd if=/dev/block/mmcblk0
# terminal 2
nc 127.0.0.1 5555 | pv -i 0.5 > $HOME/mmcblk0.raw
This saves the partition in the cygwin home directory (in a nutshell: it sends/receives output of dd over a tcp connection)
Look at the files / analysis
To mount the partition in Windows you can use (OSFmount).
To analyze the files I recommend Active# Undelete but there are tons of alternatives. With that program you can also directly load all partitions from the file (without mounting it, so step 5 is redundant in this case).
Guide for GNU/Linux users: install netcat and pv (step 1), use the Disks utility to analyze
Run as root:
adb root
Use dd to output content into stdout and write file on your computer:
adb shell 'dd if=/dev/block/platform/msm_sdcc.1/by-name/XXXXXX 2>/dev/null' > XXXXXX.img
Or all (see cat /proc/partitions)
adb shell 'dd if=/dev/block/mmcblk0 2>/dev/null' > mmcblk0.img

How can I get a working adb shell on android when /system/bin/sh is missing?

I'm trying to build Android Jellybean from source for the Measy U2C HDMI stick. I've managed to build and install all the partitions (boot, kernel, misc, recovery, system...). The problem I'm having is that the system partition doesn't seem to be mounting. When I run
adb ls /system
I get the following output:
000041ed 00000400 51301410 .
000041c0 00000800 00000003 lost+found
000041ed 00000000 00000001 ..
I'd like to adb shell into the device and try to debug why the system partition is not mounting but adb wants there to be a working shell in /system/bin/sh.
$ adb shell
- exec '/system/bin/sh' failed: No such file or directory (2) -
My question is, how can I get adb to look elsewhere for the shell command so i can get this working? Or is there an alternate way to remote into the device and debug this? There is a busybox install at /sbin/busybox so if I can just invoke that somehow, I can figure this out.
"SHELL_COMMAND" appears to be hardcoded in adb/services.c an unofficial copy of which is browsable at
https://github.com/android/platform_system_core/blob/master/adb/services.c
Given that you are building from source you should be able to change this. But since you want to point it to a shorter path, you could also probably edit the binary and move up the terminating null.
Another approach to investigating your problem could be to see if you can get a working adb shell after booting to the recovery partition, and try manually mounting the problematic system partition there to see what errors result.
Still another idea would be to put something in the startup scripts which launches an alternate shell listening on something which you could forward a socket to using adb - I'm not thinking of an obvious reason why setting up adb forwards would depend on the device side shell, but I haven't verified that by experiment or examining the code.
If you wanted to get really clever, I believe that you could create a /system/bin containing a copy of sh on the root filesystem. My recollection is that you can mount a filesystem over a non-empty directory - not sure if there would be an issue with open file descriptors to that directory, such as for the running sh itself, but your mount is failing anyway, and you could try doing a manual mount elsewhere in order to debug that issue.

redirect adb logcat to android avd

i want to redirect the Android developer tools logcat output to a file into the virtual device from a shell command, before than running the android app test.
The command i usually use to redirect the output to a file is:
adb shell logcat -v time - f log.txt packageName:F *:E > /folder/log.txt
but it puts the log file into a computer directory (/folder/ in this case).
I want to change it with a directory in the virtual device but like above, it says the folder does not exist.
There is way to do it via shell command?
You can simply do
adb shell "logcat -v time -f /mnt/sdcard/log.txt packageName:F *:E"
to accomplish it all in one command from the host shell. You do not need the redirect when you use the -f flag, in fact the redirect would not capture anything if you have directed the output of logcat to a file rather than to stdout.
If that is not working, it is either because you are using a version of Android which mounts the external storage at some other path, or you do not have an emulated sdcard attached to your virtual device.
You can investigate either of these problems by examining the output of
adb shell mount
If you do not have an sdcard at all on your AVD, follow the emulator documentation instructions for creating and attaching one.
For testing purposes only there may be other paths than the sdcard at which you can write, particularly on an emulator where the adb shell runs as root, for example on some versions /data/local or similar.
You can try this one adb shell then #logcat>/sdcard/log.txt now i am sure about the results.you just need a command prompt window to be opened for adb shell,that's not so bad i guess.

Categories

Resources