repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r38 repo sync Edit device/generic/goldfish/vendor.mk, add swiftshader and its compatible HAL: PRODUCT_PACKAGES += \ libEGL_swiftshader \ libGLESv1_CM_swiftshader \ libGLESv2_swiftshader \ android.hardware.graphics.composer@2.1-impl \ android.hardware.graphics.composer@2.1-service \ android.hardware.graphics.allocator@2.0-service \ android.hardware.graphics.allocator@2.0-impl \ android.hardware.graphics.mapper@2.0-impl Still into vendor.mk, replace the new "goldfish/ranchu audio" part because it can't give a booting system on any device appart from the emulator Before: ifneq ($(EMULATOR_VENDOR_NO_SOUND),true) PRODUCT_PACKAGES += \ android.hardware.audio.service.ranchu \ android.hardware.soundtrigger@2.2-impl.ranchu \ android.hardware.audio.effect@6.0-impl \ PRODUCT_COPY_FILES += \ device/generic/goldfish/audio/policy/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \ device/generic/goldfish/audio/policy/primary_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/primary_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \ frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \ frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \ endif After: # audio policy configuration USE_XML_AUDIO_POLICY_CONF := 1 PRODUCT_COPY_FILES += \ device/linaro/hikey/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/a2dp_in_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_in_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/usb_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \ frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml # Audio # Build default bluetooth a2dp and usb audio HALs PRODUCT_PACKAGES += audio.usb.default \ audio.r_submix.default \ tinyplay PRODUCT_PACKAGES += \ android.hardware.audio.service \ android.hardware.audio@6.0-impl \ android.hardware.audio.effect@6.0-impl \ PRODUCT_COPY_FILES += \ frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \ Into device/generic/goldfish/manifest.xml, add the following node: android.hardware.audio hwbinder 6.0 IDevicesFactory default source build/envsetup.sh lunch aosp_arm64-eng m -j $(nproc) The only usefull resulting files are: out/target/product/generic_arm64/system.img out/target/product/generic_arm64/vendor.img They are in "sparse" format. You can rename them "system-sparse.img" and "vendor-sparse.img" and use the following command to create mountable partition images: simg2img system-sparse.img system.img simg2img vendor-sparse.img vendor.img Create, and ext4 format the partition image files: qemu-img create rootfs.img 5G && qemu-img create userdata.img 1G && qemu-img create cache.img 500M losetup /dev/loop0 rootfs.img && losetup /dev/loop1 userdata.img && losetup /dev/loop2 cache.img && mkfs -t ext4 /dev/loop0 && mkfs -t ext4 /dev/loop1 && mkfs -t ext4 /dev/loop2 && losetup -d /dev/loop1 && losetup -d /dev/loop2 Mouting the rootfs partition: mount -t ext4 /dev/loop0 /where/you/want cp -a [system.img mount point] [rootfs/mount/point] The content of system.img may be copied inside a subfolder which is named like the mount point. In this case, move everything 1 folder backward. cp -a [vendor.img mount point] [rootfs/mount/point] If the name of the "vendor.img" mount point is "vendor", everything should now be inside the "/vendor" folder of the rootfs. If not, you have to move it to /vendor folder Into /vendor/etc/init/hw/init.ranchu.rc replace: setprop ro.hardware.egl emulation by setprop ro.hardware.egl swiftshader /!\ there is 2 occurences of "setprop ro.hardware.egl emulation" to replace mount_all /vendor/etc/fstab.ranchu by mount_all /vendor/etc/fstab.${ro.hardware} Or, just erase the content of init.ranchu.rc and replace it by: on fs mount_all /vendor/etc/fstab.${ro.hardware} on early-init setprop ro.hardware.egl swiftshader Save and rename init.ranchu.rc by replacing "ranchu" by another name of your choice. In my case it's init.hwexample.rc Into /vendor/etc/fstab.ranchu, the following lines should be enough: /dev/block/vdb /data ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,check,quota,reservedsize=128M,first_stage_mount /dev/block/vdc /cache ext4 noatime,nosuid,nodev,nomblk_io_submit,errors=panic wait,check,quota,reservedsize=128M,first_stage_mount But remember to rename "fstab.ranchu" by replacing "ranchu" by the hardware name of your choice. Remove the following files: /vendor/etc/init/android.hardware.authsecret@1.0-service.rc /vendor/etc/init/android.hardware.camera.provider@2.4-service.rc /vendor/etc/init/android.hardware.gatekeeper@1.0-service.software.rc /vendor/etc/init/android.hardware.gnss@2.0-service.ranchu.rc If exists - /vendor/etc/init/android.hardware.graphics.composer@2.3-service.rc /!\ remove 2.3, keep 2.1 /vendor/etc/init/android.hardware.input.classifier@1.0-service.default.rc /vendor/etc/init/android.hardware.power.stats@1.0-service.rc /vendor/etc/init/android.hardware.sensors@2.1-service-multihal.rc /vendor/etc/init/android.hardware.thermal@2.0-service.rc /vendor/etc/vintf/manifest/android.hardware.gatekeeper@1.0-service.software.xml /vendor/etc/vintf/manifest/android.hardware.gnss@2.0-service.ranchu.xml /vendor/etc/vintf/manifest/android.hardware.power.stats@1.0-service-mock.xml /vendor/etc/vintf/manifest/android.hardware.sensors@2.1-multihal.xml /vendor/etc/vintf/manifest/android.hardware.thermal@2.0-service.xml /vendor/etc/vintf/manifest/manifest_input.classifier.xml Into /vendor/etc/vintf/manifest.xml: Remove the android.hardware.authsecret hal node Remove the android.hardware.camera.provider hal node Remove the android.hardware.configstore hal node Remove the android.hardware.radio hal node Remove the android.hardware.bluetooth hal node Change android.hardware.graphics.allocator versions to 2.0 and 2.0 Change android.hardware.graphics.composer versions to 2.1 and 2.1 Change android.hardware.graphics.mapper versions to 2.0 and 2.0 ################################################################################################################################################### Manufacturing an up to date 5.10 ARM64 Android kernel: ################################################################################################################################################### git clone https://android.googlesource.com/kernel/configs /!\ From configs/android-5.10/android-recommended.config, if you want to use a mouse, remove the following line : # CONFIG_INPUT_MOUSE is not set git clone https://android.googlesource.com/kernel/common -b android12-5.10 Start from copying "arch/arm64/configs/defconfig" file to the root of the kernel tree, name it ".config", and append to it: CONFIG_NETFILTER_ADVANCED=y Content of configs/android-5.10/android-base.config Content of configs/android-5.10/android-recommended.config Content of configs/android-5.10/android-recommended-arm64.config (as always, don't forget to save) make ARCH=arm64 menuconfig, exit, save: yes. By looking with some tools, some of the things included into defconfig, android-base.config, android-recommended.config are not included into the resulting ".config". It works anyway, but it would be nice to know why theese option aren't enabling. Still missing from arm64/configs/defconfig CONFIG_SYSVIPC=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_KSM=y CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_LEGACY_PTY_COUNT=16 CONFIG_POWER_AVS=y CONFIG_BACKLIGHT_GENERIC=m CONFIG_QCOM_IOMMU=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_ROOT_NFS=y Still missing from android-base.config: CONFIG_TRACE_GPU_MEM=y Still missing from android-recommended.config: CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_REFCOUNT_FULL=y CONFIG_SDCARD_FS=y Now, some options that are still disabled, but should be enabled according to android-base-conditional.xml: CONFIG_ARMV8_DEPRECATED=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y CONFIG_SHADOW_CALL_STACK=y CONFIG_SWP_EMULATION=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_KFENCE=y CONFIG_USERFAULTFD=y CONFIG_AIO and CONFIG_ANDROID_BINDERFS options (from android-base.config) are causing early reboot without explanations. Would be nice to know why, to keep them enabled and have something running... Until so, disable them by adding at the end of .config: # CONFIG_AIO is not set # CONFIG_ANDROID_BINDERFS is not set Adding VirtIO things: CONFIG_VIRTIO=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_INPUT=y CONFIG_VIRTIO_MMIO=y CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_VIRTIO_DMA_SHARED_BUFFER=y CONFIG_BLK_MQ_VIRTIO=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_PAGE_REPORTING=y CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_DRM_VIRTIO_GPU=y (again, save) make ARCH=arm64 menuconfig, exit, save: yes. make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j $(nproc) (at questions about ARMv8.3, ARMv8.4, ARMv8.5 architectural features, I just answered "y" and it worked) make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/home/user/Desktop/ INSTALL_MOD_STRIP=1 modules_install (mind the "INSTALL_MOD_PATH=/home/user/Desktop/" parameter, you may adapt it to wherever you need) "Installing" the kernel: Place the the arch/arm64/boot/Image.gz file at the same place as the rootfs.img, userdata.img and cache.img files (ideally - the place from which qemu will be ran) Place the content of /home/user/Desktop/lib/modules/5.10.43-00322-gb007e43692c4/ into /vendor/lib/modules/ ################################################################################################################################################### Ready to go, /!\ Into the following commands, mind the "androidboot.hardware=hwexample" parameter, which is used by android's "init" process to define the ${ro.hardware} variable used in rc scripts. /!\ Unable to run with qemu-system-aarch64, zygote keep crashing in loop. => Run with kvm on an arm64 compatible device (for example, Pi4 with ubuntu 64 bits and enough GB of RAM) to work around this issue until an acceptable solution is found. from an x86_64 host: qemu-system-aarch64 -M virt -cpu cortex-a72 -accel tcg,thread=multi from an aarch64 host: kvm -M virt -cpu host -accel kvm kvm -M virt -cpu host -accel kvm -smp 4 -m 2048 -kernel Image.gz -monitor none -parallel none -append "root=/dev/vda rootfstype=ext4 ro init=/init selinux=1 checkreqprot=1 androidboot.selinux=permissive console=ttyAMA0 androidboot.hardware=hwexample loglevel=8" -serial mon:stdio -vga std -device ramfb -device nec-usb-xhci -device usb-kbd -device usb-mouse -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd -drive format=raw,file=rootfs.img -drive format=raw,file=userdata.img -drive format=raw,file=cache.img (You can add "-vnc :1" parameter and ssh tunnel to port 5901 if using a command-line only host) First run may need ~100 seconds on RPi4 before main screen is ready In case of need to debug, you may type "logcat" in the console: this give way too much informations but you may spot information on what you are looking for, or few lines above some service crashing (sometimes some messages contains usefull information to tell you why it is going to crash just after). Into the "userdata.img" partition you may also find "/tombstones" folder, containing crash logs of services. In order to cleanly poweroff your emulated system you can type "reboot -p" so that the "userdata.img" is kept as clean as possible.