ZNHOO Whatever you are, be a good one!

32-bit Android-x86 5.1-rc1

This post describe customzing android-x86-5.1-rc1.iso and using tips. Regarding the installation, please refer to virtualbox post.

readme

Customization

  1. Download android-x86-5.1-rc1.iso.

    virtual/cdrtools offers many tools to operates on ISO image, including mkisofs creating bootable ISO.

    ~ $ file android-x86-5.1-rc1.iso
    ~ $ isoinfo -pd -debug -i android-x86-5.1-rc1.iso
    ~ $ isoinfo -l -i android-x86-5.1-rc1.iso
    ~ $ iso-info -l -d ERROR -i android-x86-5.1-rc1.iso
    
  2. Mount ISO.

    ~ # mkdir -p /mnt/android-x86
    ~ # mount -t loop /path/to/android-x86-5.1-rc1.iso /mnt/android-x86
    

    Get system.sfs which is a Squashfs (compressed read-only for Linux) that containing the Android /system partition - our customzation target in this post.

  3. Mount Squashfs.

    ~ # mkdir -p /mnt/squashfs
    ~ # mount -t squashfs -o loop /mnt/android-x86/system.sfs /mnt/squashfs
    # or
    # Make sure *sys-fs/squashfs-tools* is installed.
    ~ # unsquashfs [-ll] -d /mnt/squashfs /mnt/android-x86/system.sfs
    

    There exists only one file system.img which is the image of original /system mountpoint of Android-x86. That is to say, the author first create Android /system partition as image and then compress it as Squashfs.

  4. Mount image.

    ~ # mkdir -p /mnt/img
    ~ # mount -t ext4 -o loop /mnt/squashfs/system.img /mnt/img
    # Either
    ~ # cp -a img /home/username/workspace/ (rsync -a img /home/username/workspace/)
    ~ # chown -R username: /home/username/workspace/img/
    ~ $ cd /home/username/workspace/img
    # or
    ~ # cd /mnt
    ~ # cp squashfs/system.img .
    ~ # make temp_img
    ~ # mount -t ext4 -o loop,rw system.img temp_img
    
    1. We cannot modify /mnt/img since it's directly mounted from read-only Squashfs.
    2. Do NOT add trailing slash to /mnt/img when rsync.

    Do customization here under /home/username/workspace/img. For example, remove LatinIME, SetupWizard etc. etc. Especially for build.prop:

    ro.product.locale.language=zh
    ro.product.locale.region=CN
    # ro.product.cpu.abilist64=x86_64, arm64-V8A,x86,armeabi-v7a, armeabi
    dalvik.vm.heapstartsize=8m
    dalvik.vm.heapgrowthlimit=150m
    dalvik.vm.heapsize=256m
    # ro.com.google.gmsversion=5.1_r2
    # ro.com.google.clientidbase=android-asus
    # ro.com.google.clientidbase.ms=android-asus
    # ro.com.google.clientidbase.am=android-asus
    # ro.com.google.clientidbase.gmm=android-asus
    # ro.com.google.clientidbase.yt=android-asus
    # ro.setupwizard.mode=OPTIONAL (DISABLED, or REQUIRED)
    dalvik.vm.execution-mode=int:fast
    ro.sf.lcd_density=130
    
    1. For 64-bit, arm64-V8A precdes x86 in abilist.
    2. DPI can be changed on-the-fly; please read the Tips part below.

    system/app:

    BasicDreams/ Bluetooth/ Browser/ Calculator/ Calendar/ Camera2/ CaptivePortalLogin/ ConfigUpdater/ DeskClock/ Email/ Exchange2/ Galaxy4/ Gallery2/ Gmail2/ GoogleC* HTMLViewer/ HoloSpiralWallpaper/ KeyChain/ LatinIME/ LiveWallpapers* Music2/ NotePad/ PhaseBeam/ PicoTts/ PrintSpooler/ QuickSearchBox/ RSSReader/ SoundRecorder/ UserDictionaryProvider/ VisualizationWallpapers/ YouTube/

    system/priv-app:

    CalendarProvider/ Contacts* FusedLocation/ GmsCore/ Google* ManagedProvisioning/ MusicFX/ Phonesky/ TSCalibration2/ WallpaperCropper/

    /fonts: all NotoSans*.ttf except NotoSansSymbols-Regular-Subsetted.ttf.

    usr/idc: refer to Double Mouse below.

    Customization finished. Then we should re-pack the ISO file.

  5. Do NOT unmount.

    If you choose to the alternative method (mounting system.img file as rw), do not umount now. Upon custiomization finished, intuitively, we should umount ~/workspace/img, which is fine but far from perfect. For example, we cannot resize (read the next step -l 700M) image although we removed bunch of built-in apks.

    What we should do is to creating a new image.

    Require furtuer verification.

  6. make_ext4fs and simg2img

    To continue the following procedures, we must manually compile make_ext4fs and/or simg2img from Android-x86-5.1-rc1 source. Binaries got from web would probably be troublesome. For example, make_ext4fs comes out of AOSP 6.0.1 source, make_ext4fs compiled from which would cause Android-x86-5.1-rc1 losing network and SuperSU.

    When creating image file, make_ext4fs sets file permissions in accord with core/include/private/android_filesystem_config.h irrepsective of that in working directory. Therefore, file permissions is fixed in make_ext4fs binary. That is the reason we must compile make_ext4fs from the correct Android source of your image.

    To compile make_ext4fs we should get source of core, extras and additionally zlib and libselinux. Android-x86 fetch the later two from official AOSP

    ~ $ mkdir tools
    # remove everything except *core/{include/private,libsparse}*
    ~ $ git clone --depth=1 -b lollipop-x86 https://git.code.sf.net/p/android-x86/system_core core
    # remove everything except *extras/ext4_utils*
    ~ $ git clone --depth=1 -b lollipop-x86 https://git.code.sf.net/p/android-x86/system_extras extras
    ~ $ git clone --depth=1 -b android-5.1.1_r30 https://android.googlesource.com/platform/external/zlib zlib
    ~ $ git clone --depth=1 -b android-5.1.1_r30 https://android.googlesource.com/platform/external/libselinux libselinux
    

    Makefile:

    
    SELIB = libselinux
    ZLLIB = zlib/src
    SPLIB = core/libsparse
    COLIB = core
    MALIB = extras/ext4_utils
    
    all:
        $(MAKE) -C $(SELIB)/src all
        $(MAKE) -C $(ZLLIB) all
        $(MAKE) -C $(SPLIB) libsparse.a
        $(MAKE) -C $(MALIB) all
        mv $(MALIB)/make_ext4fs make_ext4fs
    
    clean:
        $(MAKE) -C $(SELIB)/src clean
        $(MAKE) -C $(ZLLIB) clean
        $(MAKE) -C $(SPLIB) clean
        $(MAKE) -C $(MALIB) clean
    

    Then we get make_ext4fs binary. For simg2img, just grab one from web since it's compatibable.

    1. make_ext4fs
    2. simg2img
    3. android_img_repack_tools which is recommended.
    4. Howto: compile mkbootimg/mkbootfs/make_ext4fs on OS X
    5. UnPack / rePack android img with Ubuntu simg2img/make_ext4fs
  7. New image

    # Create *sparse* format image
    ~ $ make_ext4fs -T 0 -l 700M -s -a system system_sparse.img img
    # Convert Android sparse image to raw image.
    ~ $ simg2img system_sparse.img system_raw.img (If`-s` supplied to *make_ext4fs*)
    ~ $ file system_sparse.img system_raw.img;
    ~ $ mv system_raw.img system.img
    

    You are recommended to omit -s argument and simg2img as sparse image format is for Android but Android-x86 (Android-x86 uses Linux RAW image).

    1. 'l': new smaller image size.
    2. 's': sparse mode to compress image file.
    3. 'a': mount point at Android.
    4. Check the new image file size, it's exactly 700M.
    5. 'T': time 0 means 1970-1-1.
  8. New Squashfs

    We cannot mount Squashfs as rw. Must create new Squashfs like image above.

    ~ $ mksquashfs system.img system.sfs -force-uid 1001 -force-gid 1001
    
  9. Re-pack BootableCDsForBIOSAndUEFI

    We cannot mount ISO as rw. Though we can use Archive manager to modify ISO contents, bootable information gets lost meanwhile, resulting in ISO unbootable.

    ~ # rsync -a --exclude="system.sfs" /mnt/android-x86 /home/username/workspace/ (cp -a android-x86 temp_android-x86)
    ~ # chown -R username: /home/username/workspace/android-x86
    ~ $ cp -a system.sfs android-x86/
    ~ $ cd android-x86/
    ~ $ mkisofs -A "Android-x86-5.1-rc1" -V "Android-x86-5.1-rc1" -volset "Android-x86-5.1-rc1" -input-charset utf-8 -o ../android-x86.iso -JlrTUv -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -b boot/grub/efi.img -no-emul-boot ./
    
    1. Use -r instead of -R. -r means that we want to use Rockridge extensions. The -R command line option also achieves this but in a less satisfactory way. -R maintains the UID and GID of each file's owner. The same UID and GID will more than likely be meaningless once the files are transported over to another system, so ownership of all files in the ISO image is set to root:root if we use -r instead of -R. Also, -R preserves file permissions, including the write flags. Having any of the write flags set for a file on a read-only media doesn't make much sense, so -r resets it in the filesystem image.
    2. -U may need removed.
    3. New mkisofs version abandons -e option.
    4. Use -m and -x now works identically to exlucde leftovers.
    5. Android-x86-5.1-rc1 (32 bits) ISO file does not have efi.img.
  10. Refs

    1. must read
    2. Mount Modify Edit Repack Create UEFI ISO
    3. How to modify android-x86 asus_laptop imag
    4. Repackaging a Linux installation DVD using mkisofs
    5. Modify/Edit/Re-pack ISO Files Using Mkisofs In Linux

Tips

  1. By switching to virtual terminal (F1 - F6), we get root shell.
  2. If you are away from VB, the right menu (between the right Alt and right Ctrl keys), ESC, left, right, up and down keys wakes up Android-x86 from powersave mode.

Hostonly

  1. hostonly might not able to ping guest while the reverse direction works. Probably, check both the host and guest arp table.
    1. I previously set dhcpcd.conf with noarp, resulting outdated arp table (also try arp -d/a).
    2. Dunno why, hostonly networking is unreliable, ocassionally cannot ping.

adb

~ # adb tcpip 5555 (on android-x86)
~ # adb -e connect 192.168.56.101:5555
~ # adb root
~ # adb -e connect 192.168.56.101:5555
~ # adb shell

Shutdown

# https://sourceforge.net/p/android-x86/kernel/ci/kernel-4.4/tree/kernel/reboot.c
# Alt-F1
~ # reboot -f/p (shutdown)
~ # reboot (reboot)

Reset

# Alt-F1
~ # rm -R /data

DPI

~ $ su
~ # wm density
~ # wm density 200 && reboot

Adjust the value as you wish.

Double Mouse

To remove the duplicate mouse issue, firstly, set VM mouse device to usbtablet:

~ $ vboxmanage modifyvm Android-x86 --mouse usbtablet

You may found one of the mouse changes to draggable circle. Then, we further create an Input Device Configuration file for the usbtablet.

Get into Android terminal:

~ $ su
~ # cd /system/usr/idc
~ # dumpsys input | less

From the output of dumpsys input you can easily find the Virtualbox Usbtablet device however the devicetype is pointer instead of correct touchscreen. What we do is to create a configureation under /system/usr/idc to tell Android how to use the device correctly.

The configureation file can be grabbed from Android-x86-4.4-r5.iso system (/system/usr/idc/GenericTouch.idc). If you want to skip all that trouble, here is it:

# Copyright (C) 2011 The Android-x86 Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Basic Parameters
touch.deviceType = touchScreen
#touch.orientationAware = 1

# Touch Size
touch.touchSize.calibration = default

# Tool Size
touch.toolSize.calibration = default

# Pressure
touch.pressure.calibration = default

# Size
touch.size.calibration = default

# Orientation
touch.orientation.calibration = none

device.internal = 1

We should change the filename to Vendor_XXXX_Product_XXXX_Version_XXXX.idc as directed, where XXXX comes out of dumpsys input output.

Put the newly created file to /system/usr/idc. Attention, make sure the file has read permission.

~ # chmod 644 Vendor_XXXX_Product_XXXX_Version_XXXX.idc

Skip SetupWizard

The first time Android starts up, you might fail to bypass Google account setup even Wi-Fi setup is skipped. This was the VM NAT does connect to the Internet but Android think it's Wi-Fi, and meanwhile Google was blocked, which make Android try to connect to the fake Wi-Fi endlessly. The solution:

Click the upleft, upright, downright, and downleft corners of Android's effective launcher (not your computer screen) sequentially. That's it.

Another way is turn off NAT temporarily.

~ $ vboxmanage controlvm Android51 setlinkstate1 off

Resolution

Set a proper resolution value make Android-x86 run far more smoothly.

  1. Create temporary Grub menu

    During booting, e enters edit mode; e edits selected kernel line; append vga=ask; enter; b to boot; "ENTER" to see available resolution; scan to include self-defined value (next section below). Each resolution has hex number prefix. For example, 800x600 responds to 0x314 (decimal 788).

    Input one of the hex prefix to test. If none of the default resolution fits reuirement, define one by vboxmanage.

  2. Self-defined resolution

    ~ $ VBoxManage setextradata Android-x86 "CustomVideoMode1" "405x720x16"
    ~ $ VBoxManage setextradata Android-x86 "CustomVideoMode2" "800x600x16"
    ~ $ VBoxManage setextradata Android-x86 "CustomVideoMode2" (remove this entry)
    
    1. For Android 6.0 and above, use 32-bit color instead of 16.
    2. Add more by CustomVideoMode2, CustomVideoMode3 etc.
    3. This command will update *.vbox file.
    4. Type scan to show self-defined value and relavent hex prefix.
  3. Debug mode

    During boot, entering Grub debug mode,

    ~ # mount -o remount,rw /mnt
    ~ # cd /mnt/grub
    ~ # vi menu.lst
    

    Add a boot entry, adding vga=desired-decimal-prefix or UVESA_MODE=desired-resolution to kernel line.

    vga value in menu.lst should be decimal while in temporary boot edit mode be hex.

  4. Use wm size checks resolution.
  5. wm overscan 3,4,3,4 simulates mobile edge margins.