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.