manbytesgnu_site

Source files for manbytesgnu.org
git clone git://holbrook.no/manbytesgnu_site.git
Info | Log | Files | Refs

20250309_androidx86_sd.rst (8185B)


      1 android-x86 on qemu
      2 ###################
      3 
      4 :date: 2025-03-13 04:18:05
      5 :category: Offlining
      6 :author: Louis Holbrook
      7 :tags: android,qemu,nbd
      8 :slug: androidx86-sd-nbd-qemu
      9 :summary: Methods to share files from a host to an android-x86 running on qemu
     10 :lang: en
     11 :status: published
     12 
     13 
     14 I was so thrilled to find `this post`_ detailing how to create an Android app without the Android Studio or other IDE.
     15 
     16 To my absolute astonishment, the example still works to this day.
     17 
     18 But so the question remained: How to get my app onto the phone?
     19 
     20 
     21 Untethering from the phone
     22 ==========================
     23 
     24 Short of the IDE emulator, putting it on a smartphone via `adb` was the only real option I knew about. There are probably other ways. I never did much with smartphones, anyway, so I wouldn't know. In fact I absolutely can't stand smartphones, and I never use them unless I have to.
     25 
     26 That's why, in the past, I've tried some emulators to replace the need for having a smartphone at all.
     27 
     28 Unfortunately, that doesn't work for most critical things you are *forced* to use a smartphone for, like banking authentication for online purchases, that mostly can't be done with SMS 2FA anymore. 
     29 
     30 But for less picky apps, it can work. It's clunky, but it gets you off the spy device.
     31 
     32 And of course, that means we can use it for development.
     33 
     34 
     35 The Android PC
     36 ==============
     37 
     38 Now `android-x86`_ is probably not the very best benchmark for what runs on a phone. It is, after all, a open source fork of Android designed to run as a PC OS. [1]_
     39 
     40 But when using `qemu virtualization`_, having an x86 setup means one doesn't have to mess around with bootloaders and Device Tree Specifications and stuff to get everything running.
     41 
     42 As a first line test environment, it should work well enough.
     43 
     44 Getting android-x86 to run on qemu [2]_ isn't hard at all. You simply create a disk image, fire it up with that disk and the distribution ISO [3]_ as a "cdrom" and
     45 
     46 .. code-block:: bash
     47 
     48         # create disk image
     49         $ qemu-img create -f raw ax86.img 10G
     50 
     51         # start the installer with the new disk image
     52         $ qemu-system-x86_64 --enable-kvm -m 2G -cdrom /path/to/iso -hda ax86.img
     53 
     54 Once running, use whatever GUI client qemu is running (mine is VNC), and set up the OS, as follows:
     55 
     56         1. Choose the "Installation ..." option in the boot menu.
     57         2. Create a single partition (do _not_ use GPT).
     58         3. Format with ext4.
     59         4. *Yes*, install GRUB.
     60         5. Make the partition read/write.
     61         6. Run the OS
     62         7. Go through the initial setup on the phone.
     63 
     64 When done [4]_, mine looked like this: 
     65 
     66 .. image:: {static}/images/android_start.png
     67 
     68 (I chose the "taskbar" option for navigation)
     69 
     70 
     71 App transport
     72 =============
     73 
     74 Now, let's look at three ways to get your apk file onto the emulated instance.
     75 
     76 
     77 The internet
     78 ------------
     79 
     80 Smart phones are in reality mostly just remote controls to stuff happening on the internet. I guess that's why interacting with one from your computer always seems so unintuitive.
     81 
     82 Therefore, the most obvious way is to just upload the apk somewhere on the internet [5]_, and then punch in the URL  to download it.
     83 
     84 Yes, you heard right. You are *typing* the URL.
     85 
     86 With your mouse on software keyboard.
     87 
     88 With this running on qemu you don't have a camera readily available. So no QR codes for you. Fun? On a phone: Not very.
     89 
     90 
     91 Port-forwarded adb
     92 ------------------
     93 
     94 Using the `hostfwd` option, qemu lets us expose guest ports to the host. That is very practical for us, as we can use `adb` with TCP, and send the application that way. 
     95 
     96 Close down the emulator [4]_, and run it again with an edited qemu command:
     97 
     98 
     99 .. code-block:: bash
    100         
    101         # qemu but this time with host forwarding
    102         $ qemu-system-x86_64 --enable-kvm -m 2G -hda ax86.img -net user,hostfwd=tcp::5555-:5555 -net nic,model=rtl8139
    103 
    104 Once the android instance has finished booting, we can use adb to push our app to it [6]_:
    105 
    106 .. code-block:: bash
    107        
    108         # connect to the remote administration tcp socket.
    109         $ adb connect localhost:5555
    110 
    111         # push the app to the phone through the tcp socket, replacing any existing app.
    112         $ adb -s localhost:5555 install -r /path/to/apk
    113 
    114 You should be getting a message saying the installation was successful. After that, the app should be visible in the menu.
    115 
    116 
    117 A phony usb stick
    118 -----------------
    119 
    120 The last method to demonstrate is the usb solution.
    121 
    122 At the time of writing, androidx86 only supports `EHCI USB`_.
    123 
    124 Once you're powered off your instance again, adding the USB device can look like this [7]_:
    125 
    126 .. code-block:: bash
    127 
    128         # Make the usb image
    129         $ qemu-img create -f raw usb.img 2G
    130 
    131         # In order for androidx86 to make sense of the disk, it also has to be partitioned.
    132         # Just create a single partition on it (I used the Linux FS partition type, not sure if it matters).
    133         $ fdisk usb.img
    134         [...]
    135 
    136         # Start the emulator again with the USB drive.
    137         $ qemu-system-x86_64 --enable-kvm -m 2G -hda ax86.img -drive if=none,id=usbstick,format=raw,file=img/usb.img -usb -device usb-ehci,id=ehci -device usb-tablet,bus=usb-bus.0 -device usb-storage,bus=ehci.0,drive=usbstick
    138 
    139 Once powered up, a notification will appear complaining that the USB disk needs a fix.
    140 
    141 .. image:: {static}/images/android_usb_format.png
    142 
    143 Format it for "removable drive" and power down again.
    144 
    145 Now that you have a formatted USB image [8]_, you can mount it as a loop device, and copy the apk file to it:
    146 
    147 .. code-block:: bash
    148 
    149         # The loop device must mount at the offset of the first partition.
    150         # Use fdisk -l usb.img to see sector size and start sector of the partition.
    151         # Remember your offset will be (sectors * sector size)
    152         # On my setup the partition started on sector 2048, and the sector size was 512 bytes. 2048 * 512 = 1048576
    153         $ sudo mount -o loop,offset=1048576 usb.img /mnt
    154 
    155         # Copy the file
    156         $ cp /path/to/apk /mnt/
    157 
    158         # Unmount the drive
    159         $ sudo umount /mnt
    160 
    161 Now, after you start up again, the USB device should appear in the file explorer.
    162 
    163 And in the USB folder, you should see the app.
    164         
    165 .. image:: {static}/images/android_usb_apk.png
    166 
    167 .. _`this post`: https://www.hanshq.net/command-line-android.html
    168 .. _`EHCI USB`: https://g33k.holbrook.no/dc76e77870930617dc0b2c8195aff6073f652d593f7b90a47dd0f22d3329c5e1
    169 .. _`qemu virtualization`: https://www.qemu.org/
    170 .. _`android-x86`: https://www.android-x86.org/
    171 
    172 ..
    173 
    174         .. [1] After writing all this, I noticed that the last version of android-x86 was released in 2022. So perhaps it has since been abandoned, who knows. Anyway, it is based on LineageOS, which means most of what is written here still should apply, e.g. when running `qemu-system-aarch64` with that. The USB stuff might look a bit different, though. Perhaps something for a future post.
    175 
    176 ..
    177 
    178         .. [2] I used QEMU version 9.2.0.
    179 
    180 ..
    181 
    182         .. [3] I used `androidx86 version 9.0-r2 <https://www.fosshub.com/Android-x86.html#>`_.
    183 
    184 ..
    185 
    186         .. [4] As the phone setup process is painfully slow and tedious, this can be a good time to make a copy of your disk image. That way, you can always make a new copy of that one to start with just as fresh a setup as you have now. You will want to stop the emulator first: press Alt+F1 to enter console, and issue the "poweroff" command.
    187 
    188 ..
    189 
    190         .. [5] If you set up a TAP device and use that as the network interface with qemu, you can also reach a webserver on your host. Have a look at `this article <https://blog.stefan-koch.name/2020/10/25/qemu-public-ip-vm-with-tap>`_ if you are feeling adventurous enough to try.
    191 
    192 ..
    193 
    194         .. [6] If you issue `adb devices` you may notice an additional device `emulator:5554` listed. This is why you need to specify the device to install to, otherwise you get an error. On my setup, this emulator device is offline and does not work.
    195 
    196 ..
    197 
    198         .. [7] Lifted from https://qemu-project.gitlab.io/qemu/system/devices/usb.html#ehci-controller-support
    199 
    200 ..
    201 
    202         .. [8] It is probably a good idea to make a copy of this one too, so you have a fresh one available when you need it.