{"id":45,"date":"2019-09-23T03:25:00","date_gmt":"2019-09-23T03:25:00","guid":{"rendered":"http:\/\/junsun.net\/wordpress\/?p=45"},"modified":"2020-07-27T10:30:10","modified_gmt":"2020-07-27T17:30:10","slug":"how-to-build-run-cuttlefish-on-pc-arm64","status":"publish","type":"post","link":"http:\/\/junsun.net\/wordpress\/2019\/09\/how-to-build-run-cuttlefish-on-pc-arm64\/","title":{"rendered":"How to Build\/Run Android Cuttlefish Emulator on PC\/ARM64"},"content":{"rendered":"<p>Cuttlefish is new virtual-machine based Android emulator. It uses virtio devices instead of emulated devices as in original Android emulator. &nbsp; As such, it needs lighter VM support (to the extent it can run on ARM64 host), unlike Android Emulator which requires heavily modified QEMU to emulate various devices. &nbsp;The virtio architecture can potentially offer better performance as well.<\/p>\n<p>Refer to &nbsp;<a href=\"https:\/\/www.linuxplumbersconf.org\/event\/2\/contributions\/269\/attachments\/56\/63\/Kernel_Hacking_with_Cuttlefish.pdf\">a slide deck on cuttlefish<\/a>. &nbsp;Or find a local copy of it <a href=\"http:\/\/junsun.net\/wordpress\/wp-content\/uploads\/2020\/03\/Kernel_Hacking_with_Cuttlefish.pdf\" rel=\"noopener\">at here<\/a>.<\/p>\n<p>Many thanks to Alistair Delva from Google, who provided many technical guidance in going through this exercise.<\/p>\n<h2>How to Build\/Run Cuttlefish on PC (X86_64)<\/h2>\n<p>My host Ubuntu 18.04. &nbsp;Refer to <a href=\"https:\/\/source.android.com\/setup\/build\/building\">https:\/\/source.android.com\/setup\/build\/building<\/a><\/p>\n<h3>Build and install cuttlefish-common package<\/h3>\n<ul>\n<li>checkout code from <a href=\"https:\/\/github.com\/google\/android-cuttlefish\">https:\/\/github.com\/google\/android-cuttlefish<\/a><\/li>\n<\/ul>\n<div>\n<pre><code>git clone <\/code><a href=\"https:\/\/github.com\/google\/android-cuttlefish.git\"><code>https:\/\/github.com\/google\/android-cuttlefish.git<\/code><\/a> <code>\ncd android-cuttlefish\n<\/code><code>dpkg-buildpackage --no-sign<\/code><\/pre>\n<\/div>\n<ul>\n<li>Install :<\/li>\n<\/ul>\n<div>\n<pre><code>dpkg -i  ..\/cuttlefish-common_0.9.9_amd64.deb<\/code><\/pre>\n<\/div>\n<ul>\n<li>it requires dnsmasq-base and a few other packages; install them as requested<\/li>\n<li>Check status &nbsp;with &nbsp;<code>\/etc\/init.d\/cuttlefish-common status<\/code><\/li>\n<\/ul>\n<h3>Build cuttlefish<\/h3>\n<ul>\n<li>Checkout AOSP pie-gsi branch.<\/li>\n<\/ul>\n<div>\n<pre><code>repo init -u https:\/\/android.googlesource.com\/platform\/manifest -b pie-gsi<\/code> repo sync -j 8\n<code>source build\/envsetup.sh\nlunch<\/code><code>aosp_cf_x86_64_phone-userdebug\n<\/code><code>make<\/code><\/pre>\n<\/div>\n<h3>Run cuttlefish<\/h3>\n<ul>\n<li>Add user to proper groups before running; power off machine; then power on again. &nbsp;(Strange, rebooting did not seem to work somehow). &nbsp;You may need to run &#8220;sudo apt install qemu-kvm&#8221; if you get error, &#8220;group kvm doesn&#8217;t exist&#8221;.<\/li>\n<\/ul>\n<div>\n<pre><code>sudo usermod -aG kvm $USER\n<\/code><code>sudo usermod -aG cvdnetwork $USER<\/code><\/pre>\n<\/div>\n<ul>\n<li>Run: <code>launch_cvd<\/code><\/li>\n<li>Install tightvnc to view phone\n<ul>\n<li>download tightvnc viewer (jar file): <a href=\"https:\/\/www.tightvnc.com\/download.php\">https:\/\/www.tightvnc.com\/download.php<\/a><\/li>\n<li>install java if not done yet: &nbsp;<code>sudo apt install openjdk-11-jre<\/code><\/li>\n<li><code>java -jar tightvnc-jviewer.jar &nbsp;#use 127.0.0.1:6444<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Run <code>stop_cvd<\/code> to kill the cvd<\/li>\n<\/ul>\n<h2>How to Build\/Run Cuttlefish on ARM64<\/h2>\n<p>My ARM64 board is rockpro64, running ubuntu 18.04.<\/p>\n<h3>[on X86_64] Cross-build cuttlefish for ARM64<\/h3>\n<ul>\n<li>Similar as above, except build with a different target and with distribution packages<\/li>\n<\/ul>\n<div>\n<pre><code>lunch aosp_cf_arm64_phone-userdebug\n<\/code><code>make dist<\/code><\/pre>\n<\/div>\n<p>Note the following output files, which need to be copied to ARM64 host<\/p>\n<div>\n<pre><code>out\/dist\/aosp_cf_arm64_phone-img-eng.jsun.zip\n<\/code><code>out\/dist\/cvd-host_package.tar.gz<\/code><\/pre>\n<\/div>\n<h3>[on X86_64] Configure and build arm64 kernel<\/h3>\n<p>You will need CONFIG_BINFMT_MISC. &nbsp;Otherwise below step will fail. &nbsp;Check \/proc\/sys\/fs\/binfmt_misc to be sure.<\/p>\n<p>In addition, you will need a few other kernel configs, which according to Alistair are only supported in kernel after 4.9. &nbsp;Here is the set of configs I added to rockpro64 default v5.2 kernel.<\/p>\n<div>\n<pre><code>CONFIG_BINFMT_MISC=y\n<\/code><code>CONFIG_EVENTFD=y\n<\/code><code>CONFIG_VSOCKETS=y\n<\/code><code>CONFIG_VHOST_NET=m\n<\/code><code>CONFIG_VHOST_SCSI=m\n<\/code><code>CONFIG_VHOST_VSOCK=m\n<\/code><code>CONFIG_VHOST=m\n<\/code><code>CONFIG_VIRTIO_BLK_SCSI=m\n<\/code><code>CONFIG_VIRTIO_INPUT=m\n<\/code><code>CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y\n<\/code><code>CONFIG_VIRTIO_VSOCKETS_COMMON=m\n<\/code><code>CONFIG_VIRTIO_VSOCKETS=m<\/code><\/pre>\n<\/div>\n<p>In specific, here are the exact commands I used to build my rockpro64 kernel on my PC ubuntu:<\/p>\n<div>\n<pre><code>git clone https:\/\/github.com\/ayufan-rock64\/linux-mainline-kernel.git\n<\/code><code>cd linux-mainline-kernel\/\n<\/code><code>git checkout -b 5.2.0-1116-ayufan-js 5.2.0-1116-ayufan\n<\/code><code>vi arch\/arm64\/configs\/rockchip_linux_defconfig    # add the above configs to the end\n<\/code><code>vi dev.mk   # BUG? change HOSTCC=aarch64-linux-gnu-gcc to HOSTCC=gcc\n<\/code><code>.\/dev-make kernel-image-and-modules\n<\/code><code>.\/dev-make kernel-package<\/code><\/pre>\n<\/div>\n<p>Copy over the .deb package file to arm64 host and install with &#8220;dpkg -i &lt;pkg file&gt;&#8221; command. &nbsp;Reboot afterwards.<\/p>\n<h3>[on ARM64] Setup to run x86_64 binaries<\/h3>\n<p>Do following as root user:<\/p>\n<div>\n<pre><code>apt install qemu-user-static\n<\/code><code>dpkg --add-architecture amd64\n<\/code><code>[You may need to correct \/etc\/apt\/source.list file here.  See an example at <\/code><a href=\"http:\/\/junsun.net\/wordpress\/wp-content\/uploads\/2020\/03\/sources.list_.txt\"><code>this link<\/code><\/a><code>]\n<\/code><code>apt install libc6:amd64<\/code><\/pre>\n<\/div>\n<p>After this you should be able to run simple x86_64 binaries such as &#8220;cat&#8221;. &nbsp;Give it a try.<\/p>\n<h3>[on ARM64] Build and install cuttlefish-common package<\/h3>\n<p>This is similar to x86_64 case, except that you do this step on ARM64 host.<\/p>\n<p>The following packages are needed before you can install cuttlefish-common:<\/p>\n<div>\n<pre><code>apt install bridge-utils libarchive-tools libfdt1 python iptables<\/code><\/pre>\n<\/div>\n<h3>[on ARM64] Setup and run cuttlefish<\/h3>\n<ul>\n<li>copy the following &nbsp;the files from x86_64 PC host:<\/li>\n<\/ul>\n<div>\n<pre><code>out\/dist\/aosp_cf_arm64_phone-img-eng.jsun.zip\n<\/code><code>out\/dist\/cvd-host_package.tar.gz<\/code><\/pre>\n<\/div>\n<ul>\n<li>untar and unzip them into 2 directories, say \/home\/jsun\/work\/cuttlefish\/host and \/home\/jsun\/work\/cuttlefish\/image<\/li>\n<li>Add user to proper groups before running; power off machine; then power on again. &nbsp;You may need to create kvm group first and make sure &nbsp;\/dev\/kvm is read\/writable by kvm group<\/li>\n<\/ul>\n<div>\n<pre><code>sudo usermod -aG kvm $USER\n<\/code><code>sudo usermod -aG cvdnetwork $USER<\/code><\/pre>\n<\/div>\n<ul>\n<li>Run the following commands to start cuttlefish<\/li>\n<\/ul>\n<div>\n<pre><code>export ANDROID_PRODUCT_OUT=\/home\/jsun\/work\/cuttlefish\/image\/\n<\/code><code>export ANDROID_HOST_OUT=\/home\/jsun\/work\/cuttlefish\/host\/\n<\/code><code>export PATH=$PATH:$ANDROID_HOST_OUT\/bin\n<\/code><code>launch_cvd -decompress_kernel=true<\/code><\/pre>\n<\/div>\n<ul>\n<li>The rest are similar to x86_64 case<\/li>\n<\/ul>\n<h2>Appendix &#8211; Install Ubuntu Desktop on ARM64<\/h2>\n<p>Many ARM64 ubuntu distros are minimal or server, which means no desktop included. &nbsp;It is easy to install one. &nbsp;However, without a few key steps (see first a few commands below), &nbsp;you can easily get some headaches.<\/p>\n<p>Below are the commands I used to install Xubuntu on rockpro64, starting from their minimal Ubuntu 18.04 distro.<\/p>\n<ol>\n<li>Download Ubuntu 18.04 minimal img for SD card (<a href=\"https:\/\/wiki.pine64.org\/index.php\/ROCKPro64_Software_Release#Minimal_64bit_.28arm64.29_.5BmicroSD_.2F_eMMC_Boot.5D_.5B0.8.3.5D\">refer to this page<\/a>),<\/li>\n<li>Copy to SD card<\/li>\n<\/ol>\n<div>\n<pre><code>dd if=.\/bionic-minimal-rockpro64-0.8.3-1141-arm64.img of=\/dev\/sdb bs=4M<\/code><\/pre>\n<\/div>\n<ol>\n<li>Use parted or gparted to expand \/dev\/sdb7 to take over whole SD space<\/li>\n<li>Boot up rockpro64:<\/li>\n<\/ol>\n<div>\n<pre><code>sudo su\n<\/code><code>locale-gen\n<\/code><code>localectl set-locale LANG=\"en_US.UTF-8\"\n<\/code><code>apt update\n<\/code><code>apt install -y xubuntu-desktop <\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Cuttlefish is new virtual-machine based Android emulator. It uses virtio devices instead of emulated devices as in original Android emulator. &nbsp; As such, it needs lighter VM support (to the extent it can run on ARM64 host), unlike Android Emulator which requires heavily modified QEMU to emulate various devices. &nbsp;The virtio architecture can potentially offer &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/junsun.net\/wordpress\/2019\/09\/how-to-build-run-cuttlefish-on-pc-arm64\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to Build\/Run Android Cuttlefish Emulator on PC\/ARM64&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[3],"tags":[7,9,8,12,10,11],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/posts\/45"}],"collection":[{"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/comments?post=45"}],"version-history":[{"count":6,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/posts\/45\/revisions"}],"predecessor-version":[{"id":171,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/posts\/45\/revisions\/171"}],"wp:attachment":[{"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/media?parent=45"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/categories?post=45"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/junsun.net\/wordpress\/wp-json\/wp\/v2\/tags?post=45"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}