How to Build and Run Android L 64-bit ARM in QEMU

本文介绍了如何在 ARM64 架构上编译并运行 Android L 预览版。通过使用 Linaro 团队提供的内核版本和 QEMU 模型,作者成功地在模拟器上启动了 Android L 预览版,并分享了详细的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

As many others, I can't wait to put my hands on Android running on aarch64 (arm-v8) and as many other, it's difficult to afford such an expensive Juno board (the only development board arm-v8 available which I am aware of) If you Google a bit you'll bump into this cool article: 

http://www.cnx-software.com/2014/08/23/how-to-build-and-run-android-l-64-bit-arm-in-qemu/


The Linaro team put together ahead of time, around may 2014, a version of the Kernel for aarch64 called ranchu (forked from 3.10) and patched/worked together with the qemu team to create a machine model ranchu capable of emulating aarch64. Everything is well explained in the article above. 


However, by compiling the latest Android L preview 2 AOSP, I ended up with serious issues during the zygote startup. It looks there is something seriously different in how boot.art is made, thus passing it to patchoat (at first time boot) something goes very wrong. Not going into details of the hell issue.


Sometimes, when things goes wrong, better to restart from scratch. It's the old rule learned since the old Windows 95 time, hit ctrl-alt-delete. 


While compiling the AOSP, I noticed that into the prebuilt folder you have something called emultator64-arm64 which sounds pretty much what I wanted; who said that Google is not providing amr64 emulation yet? :) Yes, it's not official, emulator images are not provided with the latest SDKv19 but I happily found another piece of gold. In the folder qemu-kernel/arm64/kernel-qemu this file sounds very much like the kernel prebuilt for the arm64 emulator. Why not trying compiling AOSP for generic arm64 support? in the end the device reference is there in the AOSP without any patching... and voila...




Here are the steps to follow:

1) get Android L developer preview AOSP

cd /data/src
mkdir AOSP 
repo init -u https://android.googlesource.com/platform/manifest -b android-l-preview_r2
repo sync

wait a considerable amount of time to sync, almost 2 hours, prepare almost 100GB on your drive
note: you need repo command from google configured on your system.

2) have fun and compile (takes almost 1h on a decent machine)

source build/ envsetup.sh
lunch aosp_arm64-eng
m -j8
here is the lunch output
============================================
PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=4.4.3.43.43.43
TARGET_PRODUCT=aosp_arm64
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a15
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.13.0-37-generic-x86_64-with-Ubuntu-14.04-trusty
HOST_BUILD_TYPE=release
BUILD_ID=AOSP
OUT_DIR=out
============================================

3) move to the prebuilt emulator folder, in my case I am under linux-x64, chose your arch


cd /data/src/AOSP/prebuilts/android-emulator/linux-x86_64

4) to run the emulator you need anyhow an AVD configuration or start it manually from the qemu binary without using the google emulator wrapper. I prefer to use the wrapper here as the command is cleaner.

create an AVD using your ANDROID SDK, launch 

./android avd

(from platform tools, you can create one via command line ./android create)

or if you have already defined AVDs, just use one of them, settings will be overwritten by the command, so whatever you have in your AVD you are just using the config.ini file (stored in the .android folder). Preferably, set your AVD with more then 1024 MB ram. 


5) now you are ready to launch the emulator, here is the command (all one line). 

testL is the name of the AVD prepared. Wait, wait wait for android to finish booting, remember you are on a slow emulation, it takes time. If you are curios to see what's going on, just run "logcat" at the prompt to see all the mess in real time. 


./emulator64-arm64 -kernel ../../qemu-kernel/arm64/kernel-qemu -data /data/src/AOSP/out/target/product/generic_arm64/system.img -system /data/src/AOSP/out/target/product/generic_arm64/system.img -cache /data/src/AOSP/out/target/product/generic_arm64/cache.img -ramdisk /data/src/AOSP/out/target/product/generic_arm64/ramdisk.img -avd testL

Output, kernel boot and android prompt:


console on port 5554, ADB on port 5555
Initializing cgroup subsys cpu
Linux version 3.10.0+ (digit@tyrion.par.corp.google.com) (gcc version 4.8 (GCC) ) #12 SMP Tue Sep 16 22:36:19 CEST 2014
CPU: AArch64 Processor [411fd070] revision 0
Machine: ranchu
debug: skip boot console de-registration.
Unknown earlyprintk arguments: ttyAMA0
PERCPU: Embedded 10 pages/cpu @ffffffc07ffdf000 s11456 r8192 d21312 u40960
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 517120
Kernel command line: console=ttyAMA0,38400 keep_bootcon earlyprintk=ttyAMA0
PID hash table entries: 4096 (order: 3, 32768 bytes)
Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
Memory: 2048MB = 2048MB total
Memory: 2058560k/2058560k available, 38592k reserved
Virtual kernel memory layout:
    vmalloc : 0xffffff8000000000 - 0xffffffbbffff0000   (245759 MB)
    vmemmap : 0xffffffbc00e00000 - 0xffffffbc02a00000   (    28 MB)
    modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
    memory  : 0xffffffc000000000 - 0xffffffc080000000   (  2048 MB)
      .init : 0xffffffc00057a000 - 0xffffffc0005a8cc0   (   188 kB)
      .text : 0xffffffc000080000 - 0xffffffc000579364   (  5093 kB)
      .data : 0xffffffc0005a9000 - 0xffffffc0005e7200   (   249 kB)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
 RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=1.
NR_IRQS:64 nr_irqs:64 0
GIC CPU mask not found - kernel will fail to boot.
GIC CPU mask not found - kernel will fail to boot.
Architected local timer running at 62.50MHz (virt).
Console: colour dummy device 80x25
Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=625000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 256
/cpus/cpu@0: Unknown CPU type
hw perfevents: no hardware support available
Brought up 1 CPUs
SMP: Total of 1 processors activated (125.00 BogoMIPS).
atomic64 test passed
NET: Registered protocol family 16
vdso: 2 pages (1 code, 1 data) at base ffffffc0005b1000
hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
software IO TLB [mem 0xbd400000-0xbd800000] (4MB) mapped at [ffffffc07d400000-ffffffc07d7fffff]
Serial: AMBA PL011 UART driver
9000000.pl011: ttyAMA0 at MMIO 0x9000000 (irq = 33) is a PL011 rev1
console [ttyAMA0] enabled
bio: create slab  at 0
SCSI subsystem initialized
Switching to clocksource arch_sys_counter
NET: Registered protocol family 2
TCP established hash table entries: 16384 (order: 6, 262144 bytes)
TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP: reno registered
UDP hash table entries: 1024 (order: 3, 32768 bytes)
UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
Unpacking initramfs...
Freeing initrd memory: 816K (ffffffc008000000 - ffffffc0080cc000)
fuse init (API version 7.22)
msgmni has been set to 4022
io scheduler noop registered
io scheduler cfq registered (default)
loop: module loaded
 vda: unknown partition table
 vdb: unknown partition table
 vdc: unknown partition table
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky 
mousedev: PS/2 mouse device common for all mice
input: qwerty2 as /devices/9040000.goldfish-events/input/input0
ashmem: initialized
logger: created 256K log 'log_main'
logger: created 256K log 'log_events'
logger: created 256K log 'log_radio'
logger: created 256K log 'log_system'
ip_tables: (C) 2000-2006 Netfilter Core Team
arp_tables: (C) 2002 David S. Miller
TCP: cubic registered
NET: Registered protocol family 10
ip6_tables: (C) 2000-2006 Netfilter Core Team
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
Bridge firewalling registered
Registering SWP/SWPB emulation handler
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
Freeing unused kernel memory: 184K (ffffffc00057a000 - ffffffc0005a8000)
init (1): /proc/1/oom_adj is deprecated, please use /proc/1/oom_score_adj instead.
init: /dev/hw_random not found
init: /dev/hw_random not found
EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null)
EXT4-fs (vdb): Ignoring removed nomblk_io_submit option
EXT4-fs (vdb): mounted filesystem with ordered data mode. Opts: nomblk_io_submit,errors=panic
EXT4-fs (vdc): Ignoring removed nomblk_io_submit option
EXT4-fs (vdc): mounted filesystem with ordered data mode. Opts: nomblk_io_submit,errors=panic
init: cannot find '/system/etc/install-recovery.sh', disabling 'flash_recovery'
healthd: BatteryVoltagePath not found
healthd: BatteryTemperaturePath not found
binder: 774:774 transaction failed 29189, size 0-0
logd.auditd: start
shell@generic_arm64:/ $ 

<think>用户现在的问题是询问如何在x86虚拟机或Windows系统上使用Docker来编译和运行ARM64二进制文件。我需要先理解用户的需求,然后给出具体的解决方案。首先,用户可能是在开发跨平台应用,需要在x86架构的环境下处理ARM64的编译和运行。Docker在这里的作用是提供一个隔离的环境,利用多阶段构建和QEMU的仿真能力来实现跨架构的支持。接下来,我需要分步骤解释如何配置Docker,安装必要的工具,比如QEMU和binfmt_misc,这些是支持不同架构的关键。然后,用户可能需要使用多阶段构建来优化镜像大小,避免不必要的依赖。另外,用户可能在Windows上使用Docker,所以需要提到WindowsSubsystemforLinux2(WSL2)的配置,因为DockerDesktop在Windows上依赖WSL2来运行Linux容器。同时,需要确保用户已经启用了虚拟化支持,比如IntelVT-x或AMD-V,这在VM或物理机上都是必要的。还要考虑用户可能遇到的常见问题,比如性能问题,因为QEMU仿真会比原生运行慢,这时候可以建议使用buildx的缓存功能,或者推荐使用远程构建器来分担编译负载。最后,需要确保回答清晰,步骤明确,并且提供示例命令,让用户能够直接复制使用。同时,根据用户的问题,生成相关的后续问题,比如如何优化构建速度,或者处理依赖项等,帮助用户进一步深入解决问题。</think>是的,可以通过Docker结合QEMU和`binfmt_misc`在x86虚拟机或Windows上编译和运行ARM64二进制文件。以下是具体实现方法: ### **1. 配置Docker支持多架构** #### **(1)安装QEMU静态二进制文件** Docker需要QEMU来仿真ARM64指令集。在Docker主机(Linux或WSL2)中运行: ```bash # 安装qemu-user-static(Debian/Ubuntu示例) sudo apt-get install qemu-user-static # 注册binfmt_misc格式(自动处理多架构执行) docker run --rm --privileged multiarch/qemu-user-static --reset -p yes ``` #### **(2)启用Docker Buildx(多架构构建)** Docker Buildx是扩展的构建工具,支持跨架构编译: ```bash # 启用Buildx并创建构建器实例 docker buildx create --use --name mybuilder docker buildx inspect --bootstrap ``` ### **2. 编译ARM64二进制文件** #### **(1)使用多阶段构建(以Go语言为例)** ```dockerfile # 阶段1:编译ARM64二进制 FROM --platform=linux/arm64 golang:1.20 AS builder WORKDIR /app COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /arm64-app # 阶段2:复制二进制到轻量级镜像 FROM --platform=linux/arm64 alpine:latest COPY --from=builder /arm64-app / CMD ["/arm64-app"] ``` #### **(2)构建并指定目标架构** ```bash docker buildx build --platform linux/arm64 -t my-arm64-app:latest . ``` ### **3. 运行ARM64二进制文件** #### **(1)直接运行(通过QEMU仿真)** ```bash # 在x86主机上运行ARM64容器 docker run --rm -it my-arm64-app:latest ``` #### **(2)Windows特殊配置** - **启用WSL2后端**:在Docker Desktop设置中启用“Use the WSL 2 based engine”。 - **手动安装QEMU(Windows主机)**: ```powershell # 下载QEMU静态二进制文件 Invoke-WebRequest -Uri https://github.com/multiarch/qemu-user-static/releases/download/v7.2.0-7/qemu-aarch64-static.exe -OutFile C:\qemu-aarch64-static.exe # 注册binfmt_misc(需管理员权限) docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes ``` ### **4. 验证架构兼容性** ```bash # 检查容器运行架构 docker run --rm my-arm64-app:latest uname -m # 输出应为:aarch64 ``` ### **5. 性能优化技巧** - **使用缓存加速构建**: ```bash docker buildx build --platform linux/arm64 --cache-from=type=local,dest=/tmp/cache -t my-app . ``` - **远程构建器**:将编译任务分发到远程ARM服务器(如AWS Graviton)以避免QEMU仿真性能损失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值