Android Wear
Android Accessory Development Kit 2014 runs on Arduino, so not a production quality platform.
To view all AOSP branches:
$ git clone https://android.googlesource.com/platform/manifest.git
$ cd manifest
$ git branch -r | grep w_
origin/android-4.4w_r1
origin/android-l-preview_r2
To get what I need, run in the source code folder:
$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.4w_r1
$ repo sync #Takes 2 hours even on a fast connection
I enabled ccache:
$ export USE_CCACHE=1
$ /mnt/work/android/anroid-4.4w_r1/prebuilts/misc/linux-x86/ccache/ccache -M 50G
Choosing my build:
$ source build/envsetup.sh
$ lunch
But I don't see either the Samsung Gear Live or the LG G Watch in the list of lunch menus. Is this even the right branch?
On the other hand, there is the aosp/lollipop-wear-release branch in the framework/native repository. And there is the android-wear-5.1.1_r1 branch in the manifest repo. So I switch my repository to it, like this:
$ repo init -b android-wear-5.1.1_r1
On the other hand, there is the aosp/lollipop-wear-release branch in the framework/native repository. And there is the android-wear-5.1.1_r1 branch in the manifest repo. So I switch my repository to it, like this:
$ repo init -b android-wear-5.1.1_r1
$ repo sync #Takes 30 hour even on a fast connection
After this, the Eclipse git view shows that my frameworks/native repo is on android-wear-5.1.1_r1 (00afb81), but the lunch menu STILL does not show the Samsung Gear device:
henry@w540:~/band/android$ . build/envsetup.sh
including device/asus/deb/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/asus/grouper/vendorsetup.sh
including device/asus/tilapia/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including device/lge/mako/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including device/samsung/manta/vendorsetup.sh
including sdk/bash_completion/adb.bash
Building the Linux kernel
I downloaded the latest ADI kernel. This might be too new for Android Wear branch of the AOSP (android-4.4w_r1 above), but we will see.
/mnt/work/android$ git clone https://github.com/analogdevicesinc/linux.git
/mnt/work/android$ cd kernel
I copied the NFS enabled kernel defconfig from my previous work on running a bare metal code, into the kernel's arch/arm/config folder, and then generated the .config file like this:
/mnt/work/android/kernel$ make ARCH=arm zynq_xcomm_adv7511_nfs_defconfig
Then I compiled the kernel, knowing that I would change the kernel config and possibly even patch the kernel for Android.
/mnt/work/android/kernel$ export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
/mnt/work/android/kernel$ make ARCH=arm uImage LOADADDR=0x8000
History of HDMI Android
Can boot Android 5.0.2_r1 from sdcard and get the home screen, but the launcher crashes, as you can see below (note the Lollipop menu icons at the bottom)
When booting from NFS I get a shell over serial, but as soon as I type something (like ls), I don't get the prompt back. BUT, the Android icon above does update VERY SLOWLY, so the kernel IS alive. I am trying to debug the Android startup--which is taxing my debugging skill.
Update 2015 Feb 8
"nfs server not responding, still trying" is a red herring. With wireshark, I verified that the server IS responding.
To see if I get a usable Android system, I switched over to sdcard boot, but the launcher crashed:
java.lang.RuntimeException: Unable to get provider com.android.launcher2.LauncherProvider: java.lang.NullPointerException: Attempt to invoke interface method 'void com.android.internal.appwidget.IAppWidgetService.deleteHost(java.lang.String, int)' on a null object reference
Logcat shows that I am dropping hundreds of frames. This system is unusable without a GPU...
Update 2015 Feb 1
Tried putting /system and /data on the SD card, meaning I kept the original mount entries in the fstab. Still have the "nfs: server not responding, still trying" error, the same binder error. Now, I don't even get the initial Android splash screen. I CAN get back the Android splash screen (above) when I use a sandisk SD card, but all the problems I saw when running with /system and /data over NFS. What's common between the 2 configurations are that the root is still over NFS. Now I realize that this may be where Sven got stuck, but the difference is that I am not getting "untracked pid" problem. The problems on my radar at this point are:
- "nfs: server 192.168.1.2 not responding, still trying"
- Shell is responsive at first ("ls" and "logcat" works) but does not return when I type any command after seeing the above error
- Cannot discover ADB device
- Screen does not get past the splash screen
Here are the problems found in the logcat output:
- init: /dev/hw_random not found: you got me; I do NOT have a HW random generator
- failed open /proc/sys/net/ipv6/conf: did NOT go away even after I rebuilt the kernel with CONFIG_IPV6 AND confirmed with the Buildroot rootfs that the said file DOES exist!
- failed to create DRM screen and then:
- "will fall back to other EGL drivers if any"
- "using SW screen"
- gralloc finds the /dev/fd, and uses 1280x1024
- E/SurfaceFlinger( 977): hwcomposer module not found
- W/SurfaceFlinger( 977): no suitable EGLConfig found, trying a simpler query
- simpler query must have succeeded, because I see VMware OpenGL ES information
- W/EGL-GALLIUM( 977): native window format 0x43 != config format 0x1
- "Error opening trace file"
- E/CameraService( 987): Could not load camera HAL module
- E/AudioFlinger( 987): int android::load_audio_interface(const char*, audio_hw_device_t**) couldn't load audio hw module audio.primary (No such file or directory)
- W/EGL-GALLIUM( 1102): cache full: buf 0xb3bfb308, width 1280, height 1024, format 2, usage 0x933
Prep my 64-bit Ubuntu 14.04 desktop for the build
While playing around with Buildroot Linux, I've already accumulated almost all of the required utilities, so the following command is more than enough to get to what Google recommends for Ubuntu 14.04:
sudo apt-get install bison g++-multilib git gperf libxml2-utils
lib32z1 curl
I added the following line to my ~/.bashrc to use ccache:
export USE_CCACHE=1
I skipped the udev rules for adb over USB cable because I can already talk to the Zedboard over Cypress USB2Serial port and can JTAG to the target over FTDI device driver (see this Google doc if you want to see how I did it), and highly doubt that I will get to the point of needing adb any time soon.
Anroid kernel
I have a Buildroot kernel I've been using, but I've told that have to patch the kernel, so I downloaded the Digilent kernel to refer to:
/mnt/work/zed$ git clone https://github.com/Digilent/linux-digilent.git digker
/mnt/work/zed$ git clone https://github.com/Digilent/linux-digilent.git digker
How is the Android 2.3 kernel different than the stock Zedboard kernel? Let's first compare the device tree.
Device tree differences
In the ADI kernel for HDMI design, DTS are divided into 3 files: zynq.dtsi (common to Zynq CPU), which is included by zynq-zed.dtsi (Zedboard specialization), which is finally included by zynq-zed-adv7511.dts (Specialization for the HDMI HW). But the Android 2.3 version of Digilent kernel (what I cloned above) has just 1 DTS file: arch/arm/boot/dts/digilent-zed.dts. This DTS is the same as the DTS that comes with the Digilent HW design, except for the bootargs specifying RAM rootfs.
Difference | Digilent DTS | ADI DTS | Implication |
---|---|---|---|
root compatible | xlnx,zynq-zed | xlnx,zynq-7000 | arch/arm/mach-zynq/ different |
axi bus compatible | "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus" | "simple-bus" | ? |
cpus/compatible | xlnx,ps7-cortexa9-1.00.a | arm,cortex-a9 | arch/arm/mach-zynq/ |
cpus property | cache size specified. clock, timebase frequencyspecified | clocks points to clkc_3. operating-points specified | power management? |
pmu | none | arm,cortex-a9-pmu | ? |
axi VDMA | Broken axi-dma@40420000: compatible = "xlnx,axi-dma-6.03.a", "xlnx,axi-dma-1.00.a" | Proven working axivdma@43000000: compatible = "xlnx,axi-vdma" | |
axi_i2s_0 | clock frequency specified | DMA controller handles specified clock handles specified | ? |
i2c@41640000 | On PS AXI bus xlnx,axi-iic-1.02.a IRQ: 53. Base address 0x41640000 | On FPGA AXI bus xlnx,axi-iic-1.01.b. IRQ: 58. Base address 0x41600000 | ? |
ps7_afi | 4 instances of "xlnx,ps7-afi-1.00.a" | none | What is AFI? |
ddrc | compatible = "xlnx,ps7-ddrc-1.00.a" | compatible = "xlnx,ps7-ddrc-1.00.a", "xlnx,ps7-ddrc", "xlnx,zynq-ddrc-1.0" | ? |
ps7_dev_cfg | clock handles specified | ? | |
ps7_dma | compatible = "xlnx,ps7-dma-1.00.a", "arm,pl330" | compatible = "arm,primecell", "arm,pl330". cells, channels, requests specified | ? |
Ethernet | xlnx,enet-clk-freq-hz = <0x7735940> xlnx,enet-reset = <0xffffffff>; | xlnx,enet-clk-freq-hz = <0x17d7840> xlnx,enet-reset = "MIO 11" | ? |
gpio | emio-gpio-width = <60> gpio-mask-high = <0xc0000> gpio-mask-low = <0xfe81> | ? | |
ps7_iop_bus_config | "xlnx,ps7-iop-bus-config-1.00.a" | none | What is IOP? |
qspi | Child primary_flash "st,m25p80" specified | ADI Can boot off QSPI? | |
gic | #address-cells = < 2 > compatible = "xlnx,ps7-scugic-1.00.a", "arm,cortex-a9-gic", "arm,gic" | compatible = "arm,cortex-a9-gic" | ? |
watchdog? | swdt@f8005000. IRQ 9 | ? | |
watchdog | "xlnx,ps7-scuwdt-1.00.a" | "arm,mpcore_wdt" | ? |
slcr (system controller) | "xlnx,ps7-slcr-1.00.a" | compatible = "xlnx,zynq-slcr", "syscon" clkc enumerated | ? |
timer | compatible = "xlnx,ps7-ttc-1.00.a" 2 clocks | compatible = "cdns,ttc" 1 clock <clkc 6> | ? |
sdio | xlnx,has-power = <0x0> xlnx,has-wp = <0x1> | clocks explicitly specified | ? |
ps7_uart | compatible = "xlnx,ps7-uart-1.00.a", "xlnx,xuartps" | compatible = "xlnx,xuartps" | ? |
ps7_usb | xlnx,usb-reset = <0xffffffff> | ? | |
leds | 8 LED GPIO ports explicitly specified | ||
oled | "dglnt,pmodoled-gpio" | No use for small OLED | |
ocmc | reg = <0xf800c000 0x1000> | I recently fixed this. | |
adv7511 | Proven working | Saw penguin on an HDMI monitor | |
spi1 | I recently proved this HW | Android for industrial control? :-) |
Kernel defconfig
A kernel defconfig file captures (ideally) in a concise way a kernel's configuration. Before building the kernel proper, you run a make command at the root of a kernel with the name of the defconfig file, to generate a .config file that has the directives from the specified defconfig. Ever since I got both the HDMI and NFS rootfs working on the Zedboard, I have been using the defconfig that has only a few modifications from what was in the ADI's kernel git repository. So I start by copying the known working defconfig:
/mnt/work/zed/kernel/arch/arm/configs$ cp zynq_xcomm_adv7511_nfs_defconfig zynq_xcomm_adv7511_nfs_android_defconfig
When I open this file to add Android related configs as directed here, I noticed that the kernel defconfig I've been using already has CONFIG_STAGING and many of the configs listed in the link above. So I simply added the following at the end of the copied file:
CONFIG_EXPERIMENTAL=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_PREEMPT=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_INET_ESP=y
# CONFIG_INET_LRO is not set
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_FB=y
CONFIG_SYNC=y
Since I have been building the kernel and the rootfs with Buildroot, it would be interesting to see if these config additions still work. All I have to change is the Buildroot config's kernel --> defconfig name property, to point to the copied defconfig (zynq_xcomm_adv7511_nfs_android), rebuild, and boot the Zedboard with the new kernel. The board still boots, and I can verify that the intended configs were pulled in with this command:
# zcat /proc/config.gz | grep ANDROID
The kernel log shows some new entries for the configs I just defined:
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'
But I still do NOT know if I have all the code that the above configs are supposed to pull in are in the kernel.
/mnt/work/zed/kernel/arch/arm/configs$ cp zynq_xcomm_adv7511_nfs_defconfig zynq_xcomm_adv7511_nfs_android_defconfig
When I open this file to add Android related configs as directed here, I noticed that the kernel defconfig I've been using already has CONFIG_STAGING and many of the configs listed in the link above. So I simply added the following at the end of the copied file:
CONFIG_EXPERIMENTAL=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_PREEMPT=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_INET_ESP=y
# CONFIG_INET_LRO is not set
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_FB=y
CONFIG_SYNC=y
CONFIG_USB_G_ANDROID=y
CONFIG_USB_OTG_WAKELOCK=y
CONFIG_RTC_CLASS=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ASHMEM=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ANDROID_INTF_ALARM_DEV=y
# zcat /proc/config.gz | grep ANDROID
The kernel log shows some new entries for the configs I just defined:
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'
But I still do NOT know if I have all the code that the above configs are supposed to pull in are in the kernel.
Kernel source for Android
Thanks to the Eclipse kernel project I setup previously, it's easy to search for any symbols in the Linux kernel. Comprehensively, above #defines fall into 4 categories: I already have the code for it, or I do not, multiplied against Digilent kernel has the code for it, or does not. But as far as I can see, there is no difference between my existing kernel and the Digilent kernel, which is a bit strange. Deflatingly, all that seems to have happened is that I picked up a few minor features related to Android (like the alarm and wakelock), but nothing major (e.g. there wasn't even a code code the vaunted low memory killer)?
Oddly, I see 2 additional Android related defconfigs in the cambridge hacker's version (below): CONFIG_HAS_WAKELOCK and CONFIG_ANDROID_PARANOID_NETWORK, with actual code behind the #defines. But since I do not have such code in my kernel, I just move onto Android itself for now.
Build Android
Get AOSP
Get repo and the Android Lollipop (5.0.2) source code as packaged by siprop:
$ wget https://storage.googleapis.com/git-repo-downloads/repo
$ chmod a+x repo
$ PATH=~/work:$PATH
$ cd ~/work/zed/android/
$ git config --global user.name "Henry Choi"
$ git config --global user.email "henry.omd@gmail.com"
$ repo init -u https://android.googlesource.com/platform/manifest -b android-5.0.2_r1
$ repo sync
$ repo sync
$ repo init -b android-5.0.2_r1
$ repo sync
After letting the download finish in a couple of hours ("shutdown -h 120"), I found that it ate up 30 GB of my disk--even BEFORE building!
Get siprop's Android files
This was supposed to be easy: "repo init -u https://github.com/noritsuna/zedroid_manifests -b zedroid-5.0.2_r1" then "repo sync". But repo init complained about invalid markup, so I just did the repo sync process manually:
$ mkdir siprop; cd siprop
Ah, so mesa IS used for software OpenGL after all:
~/work/zed/siprop$ git clone https://github.com/noritsuna/zedroid_external_mesa3d
~/work/zed/siprop$ mv ../android/external/mesa3d .mesa3d.ORIG
~/work/zed/siprop$ mv zedroid_external_mesa3d ../android/external/mesa3d
siprop's product definition:
~/work/zed/siprop$ git clone https://github.com/noritsuna/zedroid_device_xilinx_zedboard
~/work/zed/siprop$ mv zedroid_device_xilinx_zedboard ../android/device/xilinx/zedboard
~/work/zed/siprop$ git clone https://github.com/noritsuna/zedroid_frameworks_native
~/work/zed/siprop$ git clone https://github.com/noritsuna/zedroid_frameworks_base
~/work/zed/siprop$ git clone https://github.com/noritsuna/zedroid_system_core
Changing the siprop's zedboard build configuration for NFS rootfs
In the zedboard folder, there are a few files that describe a build target "zedboard" which will be presented to the lunch build menu.
~/work/zed/android/device/xilinx/zedboard$ ls
AndroidProducts.mk fstab.xilinxzynqplatform README.md zedboard_GLES20.mk
BoardConfig.mk init.xilinxzynqplatform.rc swapinit.sh zedboard.mk
device.mk mixer_paths.xml vendorsetup.sh
egl.cfg overlay zedboard_GLES12.mk
AndroidProducts.mk fstab.xilinxzynqplatform README.md zedboard_GLES20.mk
BoardConfig.mk init.xilinxzynqplatform.rc swapinit.sh zedboard.mk
device.mk mixer_paths.xml vendorsetup.sh
egl.cfg overlay zedboard_GLES12.mk
All vendorsetup.sh in <AOSP>/device/ folder get pulled into the lunch menu. I can add more lunch combo for each board type, but I'll live with the options presented by cambridgehacker: zedmini-userdebug and zedboard-userdebug:
~/work/zed/android$ tail device/xilinx/zedmini/vendorsetup.sh
add_lunch_combo zedboard-userdebug
add_lunch_combo zedboard_GLES12-userdebug
add_lunch_combo zedboard_GLES20-userdebug
add_lunch_combo zedboard-userdebug
add_lunch_combo zedboard_GLES12-userdebug
add_lunch_combo zedboard_GLES20-userdebug
siprop apparently mounts the SD card, and the system.img and userdata.img on the SD card, as you can see in fstab.xilinxzynqplatform:
~/work/zed/android/device/xilinx/zedboard$ cat fstab.xilinxzynqplatform
/dev/block/mmcblk0p1 /storage/sdcard vfat rw wait
#/dev/block/mmcblk0p2 /system ext4 ro wait
#/dev/block/mmcblk0p3 /data ext4 rw,noatime,nosuid,nodev wait
Any mounts specified above are mounted during init by init.xilinxzynqplatform.rc which has "on fs" event handler that tries to mount_all, and then mkdir folders like /data (I assume it's OK if the folder already exists). I think the init script knows to look for a file /init.$systemname.rc. Karim Yagmor said that this name comes from /proc/cpuinfo, and I know that my systemname is xilinxzynqplatform (apparently).
The init.rc also calls swapinit.sh, which tries to mount swap on the 4th partition of the SD card, so I know I should have 4 partitions on this SD card; the 1st partition will be the boot partition, but can also be used for general storage, and the 4th partition will be the Linux Swap filesystem as big as the Zedboard's RAM (512 MB)--the 2nd and the 3rd partitions can old the system.img and the data partitions, but I will not use them. In GPartEd, I kept things simple: 1 GB each for the first 3 partitions, and the rest to the swap. 1 GB boot partition is unnecessarily large for my 4 MB boot.bin, but what the hell: this is the smallest SD card I have.
Of course, the question is whether the 4th partition will actually be mounted to /dev/block/mmcblk0p4 on the zedboard.
if [ -b /dev/block/mmcblk0p4 ] ; then
swapon /dev/block/mmcblk0p4
echo 30 > /proc/sys/vm/swappiness
sysctl -w vm.swappiness=30
break
fi
PRODUCT_COPY_FILES += \
device/xilinx/zedboard/init.xilinxzynqplatform.rc:root/init.xilinxzynqplatform.rc \
device/xilinx/zedboard/fstab.xilinxzynqplatform:root/fstab.xilinxzynqplatform \
device/xilinx/zedboard/swapinit.sh:root/sbin/swapinit.sh
#PRODUCT_COPY_FILES += $(LOCAL_KERNEL):uImage
~/work/zed/android/device/xilinx/zedboard$ cat fstab.xilinxzynqplatform
/dev/block/mmcblk0p1 /storage/sdcard vfat rw wait
#/dev/block/mmcblk0p2 /system ext4 ro wait
#/dev/block/mmcblk0p3 /data ext4 rw,noatime,nosuid,nodev wait
The init.rc also calls swapinit.sh, which tries to mount swap on the 4th partition of the SD card, so I know I should have 4 partitions on this SD card; the 1st partition will be the boot partition, but can also be used for general storage, and the 4th partition will be the Linux Swap filesystem as big as the Zedboard's RAM (512 MB)--the 2nd and the 3rd partitions can old the system.img and the data partitions, but I will not use them. In GPartEd, I kept things simple: 1 GB each for the first 3 partitions, and the rest to the swap. 1 GB boot partition is unnecessarily large for my 4 MB boot.bin, but what the hell: this is the smallest SD card I have.
Of course, the question is whether the 4th partition will actually be mounted to /dev/block/mmcblk0p4 on the zedboard.
if [ -b /dev/block/mmcblk0p4 ] ; then
swapon /dev/block/mmcblk0p4
echo 30 > /proc/sys/vm/swappiness
sysctl -w vm.swappiness=30
break
fi
device.mk
This init, fstab, and swap init files have to get copied to the product output folder, so there is a PRODUCT_COPY_FILES at the end of device.mk:PRODUCT_COPY_FILES += \
device/xilinx/zedboard/init.xilinxzynqplatform.rc:root/init.xilinxzynqplatform.rc \
device/xilinx/zedboard/fstab.xilinxzynqplatform:root/fstab.xilinxzynqplatform \
device/xilinx/zedboard/swapinit.sh:root/sbin/swapinit.sh
#PRODUCT_COPY_FILES += $(LOCAL_KERNEL):uImage
Note the colon that separates the source and destination, and space separates each src:dest pair. Since I am NFS booting the kernel, I do NOT need to copy the kernel. OTHERWISE, the compressed kernel image $(LOCAL_KERNEL) has to be defined to $(TARGET_PREBUILT_KERNEL), which obviously has to be defined somewhere: in BoardConfig.mk, apparently. As Karim Yagmor talked about in section 4, Architecture of Embedded Android, BoardConfig.mk describes a board, and AndroidProducts.mk or SingleProduct.mk describes the packages I want on the board.
device.mk changes the product properties in several ways:
device.mk changes the product properties in several ways:
- DEVICE_PACKAGE_OVERLAYS (device/xilinx/zedboard/overlay itself holding a couple of property XML files)
- PRODUCT_CHARACTERISTICS := nosdcard
In cambridgehacker's distribution, I had a difficult time pulling in libhwui. Maybe it's because I was missing these 2 packages?
PRODUCT_PACKAGES += \
libGLES_android \
libGLES_mesa
BoardConfig.mk
Defines USE_OPENGL_RENDERER, which SHOULD pull in libhwui. Because I was having problem with dex2oat running when booting from NFS, I wanted the dex2oat to run during build, instead of the first time (as is customarily done):
WITH_DEXPREOPT := true
Without this, art (Android runtime) calls dex2oat on the 1st boot.
WITH_DEXPREOPT := true
Without this, art (Android runtime) calls dex2oat on the 1st boot.
AndroidProducts.mk
Maybe because of the example Karim Yagmor gave in his book and he was an early advocate of Android on embedded, AndroidProducts.mk simply indirects to another makefile in the same folder;
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/zedboard.mk \
$(LOCAL_DIR)/zedboard_GLES12.mk \
$(LOCAL_DIR)/zedboard_GLES20.mk
$(LOCAL_DIR)/zedboard.mk \
$(LOCAL_DIR)/zedboard_GLES12.mk \
$(LOCAL_DIR)/zedboard_GLES20.mk
Besides the 2 versions of GLES system , zedboard.mk describes the virtual display version of the system.
zedboard_GLES12.mk
I tried to reduce the size of the product from full to generic_no_telephony.
$(call inherit-product, build/target/product/generic_no_telephony.mk)
PRODUCT_PROPERTY_OVERRIDES := \
ro.config.use.gles12_only=true \
ro.config.use.android_renderer=true
...
$(call inherit-product, device/xilinx/zedboard/device.mk)
At first, I went for core_minimal--which was the smallest product that Android build would take, but I found out that Android needs fonts after all, as you can see in the inheritance relationship found in build/target/product/:
Q: when I change the parent product from "full" to "core_minimal" (which should be much smaller than the full), the build time still seems to be the same?
I also changed PRODUCT_PROPERTY_OVERRIDES. one of the workarounds for running over NFS is to prevent clearing of the IP, so I appended a property as shown below
henry@Zotac64:~/work/zed/android$ prebuilts/misc/linux-x86/ccache/ccache --max-size=50G
Set cache size limit to 50.0 Gbytes
I am not sure what envsetup does, but it's in the doc.
~/work/zed/android$ source build/envsetup.sh
At first, I want to start with a small distribution: zedmini-userdebug
~/work/zed/android$ lunch zedboard_GLES20-userdebug
Then I can (try to) build it. Since there are so many warnings (expected!), pipe the output to bitbucket to see only errors.
~/work/zed/android$ make -j 2 > /dev/null
Q: when I change the parent product from "full" to "core_minimal" (which should be much smaller than the full), the build time still seems to be the same?
I also changed PRODUCT_PROPERTY_OVERRIDES. one of the workarounds for running over NFS is to prevent clearing of the IP, so I appended a property as shown below
PRODUCT_PROPERTY_OVERRIDES += ethernet.clear.ip \
Hacking the Android source for NFS hosted /data partition
In Android framework, installd (daemon) sets up applications before it can be run. But unlike many of the core services, installd runs as the user "install", as you can see in the (edited) list of processes at the very beginning of the Android startup:
root@zedboard:/ # ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 2616 480 c011d780 00022920 S /init
root 590 2 0 0 c003eafc 00000000 S binder
logd 1021 1 6988 984 ffffffff b6ee9dc4 S /system/bin/logd
root 1022 1 3688 260 c014eb00 000310b8 S /sbin/healthd
root 1023 1 4484 1164 c014eb00 b6ebac80 S /system/bin/lmkd
system 1024 1 3248 572 c0434774 b6ecf150 S /system/bin/servicemanager
root 1025 1 7700 2168 ffffffff b6f6a994 S /system/bin/vold
system 1026 1 63568 16336 ffffffff b63b2e4e R /system/bin/surfaceflinger
root 1027 1 3208 944 c0037a74 b6f33dc4 S /system/bin/sh
root 1028 1 4384 1480 00000000 b6f5c6f0 R /system/bin/netd
root 1029 1 3840 924 c04a19e8 b6f03088 S /system/bin/debuggerd
drm 1030 1 11488 4188 ffffffff b6ea4150 S /system/bin/drmserver
media 1031 1 12736 5264 00000000 b6fe5abc R /system/bin/mediaserver
install 1032 1 3200 712 c04a19e8 b6f1d088 S /system/bin/installd
keystore 1033 1 6284 2084 c0434774 b6eca150 S /system/bin/keystore
root 1035 1 24416 7292 00000000 b6f01088 R /system/bin/app_process
shell 1036 1 3644 272 ffffffff 00020db4 S /sbin/adbd
root 1092 2 0 0 c003f43c 00000000 S kworker/0:2
graphics 1114 1 14540 4812 ffffffff b6f93150 S /system/bin/bootanimation
root 1141 1028 0 0 c002684c 00000000 Z iptables
So the hack applied to <>/frameworks/native/cmds/installd/installd.c puts in a back door.
Build
Before launching the build, increase the ccache size:henry@Zotac64:~/work/zed/android$ prebuilts/misc/linux-x86/ccache/ccache --max-size=50G
Set cache size limit to 50.0 Gbytes
I am not sure what envsetup does, but it's in the doc.
~/work/zed/android$ source build/envsetup.sh
At first, I want to start with a small distribution: zedmini-userdebug
~/work/zed/android$ lunch zedboard_GLES20-userdebug
Then I can (try to) build it. Since there are so many warnings (expected!), pipe the output to bitbucket to see only errors.
~/work/zed/android$ make -j 2 > /dev/null
The first time build takes about 5 hours, but subsequent builds are significantly faster thanks to ccache (< 1.5 hours).
/mnt/work/zed/android/out/target/product/zedboard$ ls
android-info.txt clean_steps.mk installed-files.txt ramdisk.img system
cache data obj root system.img
cache.img gen previous_build_config.mk symbols userdata.img
NFS boot with /system and /data on SD card
I discovered that Android has to be hacked to run with NFS hosted /data. So this is a hybrid approach of keeping the NFS rootfs, but /system and /data on the SD card. When the SD card is partitioned as illustrated way above (I used GPartEd), the SD card will auto mount at /media/<user>/system and /media/<user>/data. The strategy is to copy the generated system.img and userdata.img into those partitions.$ sudo mkdir -p /export/root/zedroid /tmp/system /tmp/userdata
~/work/zed/android/out/target/product/zedboard$ zcat ramdisk.img | sudo sh -c 'cd /export/root/zedroid && cpio -i --no-absolute-filenames'
~/work/zed/android/out/target/product/zedboard$ sudo mount system.img /tmp/system
$ sudo cp -a /tmp/system/* /media/henry/system
$ sudo umount /tmp/system
~/work/zed/android/out/target/product/zedboard$ sudo mount userdata.img /tmp/userdata
$ sudo cp -a /tmp/userdata/* /media/henry/data
$ sudo umount /tmp/userdata
This runs a lot of /system/bin/patchcoat--which is farther along the boot process than achieved in the alternative approach below.
NFS boot with /data also on NFS (does NOT work yet)
Among articles found on the web on how to NFS boot an Android target, Linaro seems to have formalized the procedure at least for the Panda board, and may be worth studying.~/work/zed$ git clone https://android.git.linaro.org/git-ro/platform/external/linaro-android-tools.git -b linaro_android_4.4
The commands below are trying to mimic the bash function func_create_rootfs() in linaro-android-nfs-tool.sh just cloned above.
$ sudo mkdir -p /export/root/zedroid /tmp/system /tmp/userdata
~/work/zed/android/out/target/product/zedboard$ zcat ramdisk.img | sudo sh -c 'cd /export/root/zedroid && cpio -i --no-absolute-filenames'
~/work/zed/android/out/target/product/zedboard$ sudo mount system.img /tmp/system
$ sudo cp -a /tmp/system/* /export/root/zedroid/system
$ sudo umount /tmp/system
~/work/zed/android/out/target/product/zedboard$ sudo mount userdata.img /tmp/userdata
$ sudo cp -a /tmp/userdata/* /export/root/zedroid/data
$ sudo umount /tmp/userdata
$ sudo echo "hack.installd.for.nfs=1" | sudo tee -a /export/root/zedroid/system/build.prop
The explanation for the last line is from a Linaro engineer.
...when boot via nfs, we need the install usr on nfs server to have the chown permission as it does on android. but that's no easy to do with setting of nfs. so we will make the install to run as root via theWhen booting from a flash, /system and /data are separate partitions on the flash. When booting over NFS, I have to stop mounting /system and /data in fstab.xilinxzynqplatform
property hack.installd.for.nfs set to 1 when want to boot via nfs
/dev/block/mmcblk0p1 /storage/sdcard vfat rw wait
#/dev/block/mmcblk0p2 /system ext4 ro wait
#/dev/block/mmcblk0p3 /data ext4 rw,noatime,nosuid,nodev wait
$ sudo sed -i'' -e "s/.*system.*/# &/" -e "s/.*data.*/# &/" /export/root/zedroid/fstab.xilinxzynqplatform
Others pointed out that init.rc remounting / as RO is a problem for NFS, so I comment out that line with sed. If I do NOT change the file permissions with this sed commands, I get a working shell, but get the "untracked pid" problem. This suggests that the "untracked pid" problems are due to failure to write to the RO filesystem.
$ sudo sed -i'' -e "s/mount rootfs rootfs \/ ro remount/# &/" -e "s/user shell/user root/" /export/root/zedroid/init.rc
zynq-uboot> setenv bootargs 'earlyprintk maxcpus=1 console=ttyPS0,115200 ip=dhcp root=/dev/nfs nfsroot=192.168.1.2:/export/root/zedroid,nfsvers=3 rw init=/init'
zynq-uboot> saveenv
I tried to use NFS version 3 to see if the NFS not responding error will go away (it didn't) so it's not necessary. The init argument is necessary because Android's init is NOT in one of the places the kernel checks. With these changes, Android boots, and I get a shell, where I can get su.
...
init: cannot find '/system/bin/debuggerd64', disabling 'debuggerd64'e=vfat)=0
init: cannot find '/system/bin/install-recovery.sh', disabling 'flash_recovery'
binder: 969:969 transaction failed 29189, size 0-0
random: installd urandom read with 105 bits of entropy available
Adding 728060k swap on /dev/block/mmcblk0p4. Priority:-1 extents:1 across:728060k SS
random: nonblocking pool is initialized
shell@zedboard:/ $ healthd: No charger supplies found
healthd: No battery devices found
nfs: server 192.168.1.2 not responding, still trying
shell@zedboard:/ $ healthd: battery none chg=
It seemed that console hangs after the boot animation starts, so I straced console service by modifying init.rc:
service console /system/xbin/strace -tt -o/data/boot.strace /system/bin/sh
This did not turn up anything that looked like a problem, so I then straced zygote. While staring at zygote strace, I realized that the last output from art (Android runtime) is the beginning of dex2oat: "GenerateImage...", which preceeds the beginning of dex2oat starting, but there is no further message from dex2oat. So is dex2oat running at all? WITH_DEXPREOPT, Android will instead try to relocate the oat file from /system/framework/boot.oat to /data/dalvik-cache/arm/system@framework@boot.art.
This seems to have worked:
$ sudo ls -lh /export/root/zedroid/data/dalvik-cache/arm/
total 40M
-rw-r--r-- 1 root root 0 Feb 7 08:05 system@framework@boot.art
-rw-r--r-- 1 root root 49M Feb 7 08:47 system@framework@boot.oat
Convenience: udev rule for Zedboard's Cypress USB serial connection
By default, the /dev/ttyACMx device enumerated for the Zedboard's Cypress USB serial connection is owned by root, so I always had to run commands that access the device in sudo. Now that I am trying to run adb, that workaround has gotten tiresome. So I put created /etc/udev/rules.d/51-android-rules and restarted the udev:
#adb protocol on Zedboard
SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c52b", MODE="0600", OWNER="henry"
I doubt the vendor and product would be different on your system, but if it is, you can just read off the numbers for Cypress from "lsusb" command after connecting the Zedboard to your PC.
APPENDIX: running Android from SD card: has problem
To mount the ramdisk.img created by Android build as initrd file, you have to run mkimage
$ sudo apt-get install u-boot-tools
~/work/zed/android/out/target/product/zedboard$ mkimage -A arm -O linux -T ramdisk -a 0x2000000 -n "Zedboard ramdisk" -d ramdisk.img ramdisk.image.gz
Image Name: Zedboard ramdisk
Created: Tue Feb 3 19:21:54 2015
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 610260 Bytes = 595.96 kB = 0.58 MB
Load Address: 02000000
Entry Point: 02000000
And move that to either the SD card, or to the TFTP download folder if you are TFTP downloading the kernel and the ramdisk image.
The matching U-boot sdboot and bootargs environments are are:
u-boot> setenv sdboot 'if mmcinfo; then run uenvboot; echo Copying files over TFTP to RAM && tftpboot 0x2A00000 ${serverip}:${devicetree_image} && tftpboot 0x2000000 ${serverip}:${ramdisk_image} && tftpboot 0x3000000 ${serverip}:${kernel_image} && bootm 0x3000000 0x2000000 0x2A00000; fi'
The matching U-boot sdboot and bootargs environments are are:
u-boot> setenv sdboot 'if mmcinfo; then run uenvboot; echo Copying files over TFTP to RAM && tftpboot 0x2A00000 ${serverip}:${devicetree_image} && tftpboot 0x2000000 ${serverip}:${ramdisk_image} && tftpboot 0x3000000 ${serverip}:${kernel_image} && bootm 0x3000000 0x2000000 0x2A00000; fi'
u-boot> setenv bootargs 'earlyprintk maxcpus=1 console=ttyPS0,115200 ip=dhcp init=/init'
APPENDIX Get cambridgehackers port of Anrdoid 4.1 on Zedboard; still not working
This aosp repository of course knows nothing about Zedboard. Sven Anderson got pretty close to booting Android 4.1 on Zedboard using the Android support package from cambridgehackers (Jamey Hicks), so I downloaded that repository to figure out what I have to do to add Zedboard target to AOSP (AOSP):
$ mkdir ~/work/zed/cambridge; cd ~/work/zed/cambridge
~/work/zed/cambridge$ repo init -u git://github.com/cambridgehackers/zynq-android4.git -b jb -m default.xml
~/work/zed/cambridge$ repo sync
It would appear that Android is a strictly monotonically increasing distribution, because this download ONLY takes up 21 GB on my disk. Of all these files, I am only interested in device/xilinx. Let's copy copy this whole folder to the AOSP tree, and edit as necessary.
~/work/zed/cambridge/device$ cp -r xilinx ../../android/device/
~/work/zed/android/device/xilinx$ rm -rf kernel
~/work/zed/android/device/xilinx$ find . -name .git -exec rm -rf {} \;
~/work/zed/android/device/xilinx$ ls
gralloc hwcomposer kernel zedboard zedmini
The kernel is an unnecessary folder (I have my own kernel!), so I nuked it. zedboard and zedmini are the 2 lunch menu options for Zedboard, and gralloc and hwcomposer are shared libraries necessary for display.
Understanding the cambridgehacker build configuration
In the zedmini folder, there are 4 files that describe a build target "zedmini" which will be presented to the lunch build menu.
~/work/zed/android/device$ ls xilinx/zedmini/
AndroidProducts.mk BoardConfig.mk vendorsetup.sh zedmini.mk
All vendorsetup.sh in <AOSP>/device/ folder get pulled into the lunch menu. I can add more lunch combo for each board type, but I'll live with the options presented by cambridgehacker: zedmini-userdebug and zedboard-userdebug:
~/work/zed/android$ tail -1 device/xilinx/zedmini/vendorsetup.sh
add_lunch_combo zedmini-userdebug
add_lunch_combo zedmini-userdebug
Since cambridgehacker ran the zedboard product instead of zedmini, he left out the crucial board specific init script from zedmini configuration, so I copied it from the sibling zedboard product:
~/work/zed/android/device/xilinx$ cp zedboard/init.xilinxzynqplatform.rc zedmini/
I think the init script knows to look for a file /init.$systemname.rc, but I don't know how init figures out that my systemname is xilinxzynqplatform (apparently), or where I can change this long-ass name.
This init and fstab file has to get copied to the product output folder, so I added PRODUCT_COPY_FILES at the end of zedmini.mk:
PRODUCT_COPY_FILES := \
device/xilinx/zedmini/init.xilinxzynqplatform.rc:root/init.xilinxzynqplatform.rc \
device/xilinx/zedmini/fstab.xilinxzynqplatform:root/fstab.xilinxzynqplatform
Since I want to avoid copying the system and userdata imgs to sdcard, I deleted out the mounting the loop fs imgs. Please remember this when reading the NFS boot section below.
As Karim Yagmor talked about in section 4, Architecture of Embedded Android, BoardConfig.mk describes a board, and AndroidProducts.mk or SingleProduct.mk describes the packages I want on the board.
~/work/zed/android/device/xilinx$ cp zedboard/init.xilinxzynqplatform.rc zedmini/
I think the init script knows to look for a file /init.$systemname.rc, but I don't know how init figures out that my systemname is xilinxzynqplatform (apparently), or where I can change this long-ass name.
This init and fstab file has to get copied to the product output folder, so I added PRODUCT_COPY_FILES at the end of zedmini.mk:
PRODUCT_COPY_FILES := \
device/xilinx/zedmini/init.xilinxzynqplatform.rc:root/init.xilinxzynqplatform.rc \
device/xilinx/zedmini/fstab.xilinxzynqplatform:root/fstab.xilinxzynqplatform
Since this a makefile semantics after all, the space in front of the 2 lines must be a tab! Note the colon that separates the source and destination, and space separates each src:dest pair.
I don't know what fstab I want for the target yet, so I will just create an empty file for now.
I don't know what fstab I want for the target yet, so I will just create an empty file for now.
~work/zed/android$ touch device/xilinx/zedmini/fstab.xilinxzynqplatform
Since I want to avoid copying the system and userdata imgs to sdcard, I deleted out the mounting the loop fs imgs. Please remember this when reading the NFS boot section below.
#mount ext4 loop@/mnt/sdcard/system.img /system ro
#mount ext4 loop@/mnt/sdcard/userdata.img /data rw nosuid nodev
AndroidProducts.mk
Maybe because of the example Karim Yagmor gave in his book and he was an early advocate of Android on embedded, AndroidProducts.mk simply indirects to another makefile in the same folder;
PRODUCT_MAKEFILES := $(LOCAL_DIR)/zedmini.mk
I changed zedmini.mk to pull in the smallest product I could find:
$(call inherit-product, build/target/product/core_minimal.mk)
Make complained when I tried embedded.mk and base.mk, so I went with core_minimal.mk as the smallest possible product.
To begin, I humbly use the default overlays:
DEVICE_PACKAGE_OVERLAYS := device/generic/armv7-a-neon/overlay
To display, this board needs the gralloc, and hwcomposer libraries:
PRODUCT_PACKAGES += gralloc.zynq hwcomposer.zynq
It looks like zedmini build config was not built by cambridgehackers, because I had to fix the extension from zedboard to zynq, to make it compatible with the makefile in the gralloc/ and hwcomposer/ folders. PRODUCT_NAME will appear in the lunch menu.
PRODUCT_NAME := zedmini
PRODUCT_MODEL is stored in the device's ro.product.model global property, and appear as the "Model number" in the Settings --> "About this phone".
Karim Yagmor says that PRODUCT_BRAND is typically set to Android.
BoardConfig.mk
This makefile is full of unexplained variables. I can guess why TARGET_NO_BOOTLOADER and TARGET_NO_KERNEL are true for this board, and roughly agree with the values for TARGET_ARCH_VARIANT (armv7-a-neon), TARGET_CPU_ABI (armeabi-v7a), TARGET_CPU_ABI2 (armeabi), TARGET_CPU_SMP (true), and ARCH_ARM_HAVE_TLS_REGISTER (true). I probably do not want BUILD_EMULATOR_OPENGL or USE_OPENGL_RENDERER because my Zedboard design just has framebuffer, and no OpenGL HW (a HW design including Xylon IP has it, but I would need to modify the kernel, so I am going to do away with OpenGL for now).
AOSP version 5.0 (lollipop) was complaining about TARGET_ARCH and TARGET_CPU_VARIANT not being defined, so I just added the following line into both zedmini.mk and zedboard.mk
TARGET_ARCH := arm
TARGET_CPU_VARIANT := cortex-a9
I tried putting in the following to see where the kernel and the DTB built with Buildroot (and proven to be booting with the Buildroot rootfs) windup in the Android build tree:
TARGET_PREBUILT_KERNEL := /mnt/work/zed/buildroot/output/images/uImage
DEVICE_TREE_BIN := /mnt/work/zed/buildroot/output/images/zynq-zed-adv7511-spi1.dtb
But I don't see either files in <>/out/target/prodcut/zedboard after the build (see below). Since I've been booting the Linux kernel on my Zedboard, this is not a big deal--just a little odd.
Build
Before launching the build, increase the ccache size:henry@Zotac64:~/work/zed/android$ prebuilts/misc/linux-x86/ccache/ccache --max-size=50G
Set cache size limit to 50.0 Gbytes
I am not sure what envsetup does, but it's in the doc.
~/work/zed/android$ source build/envsetup.sh
At first, I want to start with a small distribution: zedmini-userdebug
~/work/zed/android$ lunch zedmini-userdebug
Then I can (try to) build it. Since there are so many warnings (expected!), pipe the output to bitbucket to see only errors.
~/work/zed/android$ make > /dev/null
Have you heard the term "confirmation bias": tendency to see and hear things that confirm your preconception? I always felt that Android is bloated and can benefit from cleaning--especially since think that even Linux is bloated. The Android build process and the time plays into this bias. After 1 hour, I run into an OpenGL related (remember I don't have the OpenGL HW) error described here. I am trying the following workaround in <>/frameworks/base/core/jni/android/graphics/Paint.cpp:
29 #include "SkBlurMask.h"
...
810 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius);
811 //android::uirenderer::Blur::convertRadiusToSigma(radius);
Install: out/target/product/zedboard/system/lib/hw/gralloc.default.so
Import includes file: out/target/product/zedboard/obj/SHARED_LIBRARIES/gralloc.zynq_intermediates/import_includes
target thumb C++: gralloc.zynq <= device/xilinx/gralloc/gralloc.cpp
device/xilinx/gralloc/gralloc.cpp:34:21: fatal error: ion/ion.h: No such file or directory
#include <ion/ion.h>
LOCAL_SHARED_LIBRARIES := liblog libcutils libion
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_SHARED_LIBRARIES)/libion.so
Next, I hit this error:
In file included from device/xilinx/gralloc/gralloc.cpp:40:0:
device/xilinx/gralloc/gr.h:22:23: fatal error: asm/page.h: No such file or directory
# include <asm/page.h>
gr.h tries to pull in the Linux PAGE_SIZE if HAVE_ANDROID_OS is defined, which is the equivalent of the WIN #define on Windows (according to this discussion). So the question is where to get this asm/page.h, which is in <kernel>/arch/arm/include in a Linux kernel. Cambridgehacker actually included the whole kernel tree under the xilinx folder--which I want to avoid--but even then, I don't understand how he pulled in the header file. It's doubly strange that the preprocessor is finding other files like pthread.h, stdint.h and limits.h. I would guess those files are in bionic/libc/include, but page.h is not. When I poke around in the <>/bionic folder, I see a comment like this "new code should use sysconf(_SC_PAGE_SIZE)", so I tried the following workaround:
20 #ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define
21 //can't find it # include <asm/page.h>
22 #else
...
39 inline size_t roundUpToPageSize(size_t x) {
40 return (x + (sysconf(_SC_PAGE_SIZE)-1)) & ~(sysconf(_SC_PAGE_SIZE)-1);
41 //(x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
42 }
The next error is HAL_PIXEL_FORMAT_RGBA_5551 and HAL_PIXEL_FORMAT_RGBA_4444 not being declared in gralloc.cpp. Since these 2 defines now seem to be gone from <>/system/core/include/system/graphics.h, I just commented them out (and mentally prepare to deal with consequences later):
257 case HAL_PIXEL_FORMAT_RGB_565:
258 //case HAL_PIXEL_FORMAT_RGBA_5551:
259 //case HAL_PIXEL_FORMAT_RGBA_4444:
260 bpp = 2;
261 break;
typedef hwc_layer_1_t hwc_layer_t;
typedef hwc_display_contents_1_t hwc_layer_list_t;
typedef hwc_composer_device_1_t hwc_composer_device_t;
The prepare and function signatures changed too, so I modify the code minimally
78 static int hwc_prepare(hwc_composer_device_t*, size_t nD, hwc_layer_list_t* *list) {
79 if(nD != 1)//For HWC 1.0, numDisplays will always be one
80 return EINVAL;
81 if (list && list[0] && (list[0]->flags & HWC_GEOMETRY_CHANGED)) {
82 for (size_t i=0 ; i < list[0]->numHwLayers ; i++) {
83 dump_layer(&list[0]->hwLayers[i]);
84 if (i > 0)
85 list[0]->hwLayers[i].compositionType = HWC_OVERLAY;
86 }
87 }
...
91 static int hwc_set(hwc_composer_device_t*, size_t nD,
92 //hwc_display_t dpy, hwc_surface_t sur,
93 hwc_layer_list_t* *list)
94 {
95 if(nD != 1)//For HWC 1.0, numDisplays will always be one
96 return EINVAL;//and displays[0] will be non-NULL
97 if (!eglSwapBuffers((EGLDisplay)list[0]->dpy, (EGLSurface)list[0]->sur)) {
$
But apparently, the tiny android is too tiny it causes some necessary libraries to be NOT built in order?
make: *** No rule to make target `out/target/product/zedboard/obj/SHARED_LIBRARIES/libsysutils_intermediates/export_includes', needed by `out/target/product/zedboard/obj/EXECUTABLES/logd_intermediates/import_includes'. Stop.
~/work/zed/android/out/target/product/zedboard$ du -sh
18G .
~/work/zed/android/out/target/product/zedboard$ ls -oh
total 274M
-rw-rw-r-- 1 henry 14 Jan 24 16:16 android-info.txt
drwxrwxr-x 2 henry 4.0K Jan 24 16:17 cache
-rw-r--r-- 1 henry 256M Jan 24 16:17 cache.img
-rw-rw-r-- 1 henry 60K Jan 24 15:54 clean_steps.mk
drwxrwxr-x 3 henry 4.0K Jan 23 20:20 data
drwxrwxr-x 5 henry 4.0K Jan 24 17:11 gen
-rw-rw-r-- 1 henry 35K Jan 24 16:17 installed-files.txt
drwxrwxr-x 14 henry 4.0K Jan 24 16:17 obj
-rw-rw-r-- 1 henry 63 Jan 24 15:54 previous_build_config.mk
-rw-rw-r-- 1 henry 594K Jan 24 16:17 ramdisk.img
drwxrwxr-x 8 henry 4.0K Jan 23 20:20 root
drwxrwxr-x 5 henry 4.0K Jan 23 20:20 symbols
drwxrwxr-x 12 henry 4.0K Jan 24 16:15 system
-rw-r--r-- 1 henry 256M Jan 24 16:17 system.img
-rw-r--r-- 1 henry 512M Jan 24 16:17 userdata.img
total 274M
-rw-rw-r-- 1 henry 14 Jan 24 16:16 android-info.txt
drwxrwxr-x 2 henry 4.0K Jan 24 16:17 cache
-rw-r--r-- 1 henry 256M Jan 24 16:17 cache.img
-rw-rw-r-- 1 henry 60K Jan 24 15:54 clean_steps.mk
drwxrwxr-x 3 henry 4.0K Jan 23 20:20 data
drwxrwxr-x 5 henry 4.0K Jan 24 17:11 gen
-rw-rw-r-- 1 henry 35K Jan 24 16:17 installed-files.txt
drwxrwxr-x 14 henry 4.0K Jan 24 16:17 obj
-rw-rw-r-- 1 henry 63 Jan 24 15:54 previous_build_config.mk
-rw-rw-r-- 1 henry 594K Jan 24 16:17 ramdisk.img
drwxrwxr-x 8 henry 4.0K Jan 23 20:20 root
drwxrwxr-x 5 henry 4.0K Jan 23 20:20 symbols
drwxrwxr-x 12 henry 4.0K Jan 24 16:15 system
-rw-r--r-- 1 henry 256M Jan 24 16:17 system.img
-rw-r--r-- 1 henry 512M Jan 24 16:17 userdata.img
This is NOT the root; it doesn't even have the init scripts. The root/ folder is apparently closer to the expected root file system:
~/work/zed/android/out/target/product/zedboard$ ls root/charger file_contexts init.trace.rc property_contexts sepolicy ueventd.rc
data init init.usb.rc sbin service_contexts
default.prop init.environ.rc init.zygote32.rc seapp_contexts sys
dev init.rc proc selinux_version system
The system/ folder above is just a mount point, while system.img is the compressed tarball of the system/ folder right next to the root/ folder shown above (data.img and cache.img look similarly). The ramdisk.img is actually just a gzipped CPIO archive, as you can see here:
~/work/zed/android/out/target/product/zedboard$ file *.img
cache.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)
ramdisk.img: gzip compressed data, from Unix
system.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)
userdata.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files)
If I copy ramdisk.img to /tmp/ramdisk.cpio.gz, gunzip it, and then extract it (with cpio -i -F ramdisk.cpio), the contents are exactly the same as the root/ folder shown above. So just think of the ramdisk image as THE rootfs the target should boot with. When booting from SD or eMMC, the other img files are on a separate partition of the boot device, and the init process uncompresses these files to the appropriate mount points at the root file system. During development, I want to bypass having to write the images to the flash device, and just export the rootfs that contains the full system and userdata images.
But the target exhibits the similar problem that thwarted Sven Anderson.
fs_mgr: Cannot open file /fstab.xilinxzynqplatform
shell@zedboard:/ # init: untracked pid 5875 exited with status 3
init: untracked pid 6057 killed by signal 9
...
Apparently, the "init: untracked pid" is a commonly encountered problem when something within the framework or the device driver goes wrong. But as a silver lining, since I can read and write files into the root directory, I don't think I need the file /fstab.xilinxzynqplatform. I tentatively conclude that the target can successfully boot from NFS, and move onto debugging the "init: untracked pid" problem.
init: untracked pid
But the target exhibits the similar problem that thwarted Sven Anderson.
fs_mgr: Cannot open file /fstab.xilinxzynqplatform
shell@zedboard:/ # init: untracked pid 5875 exited with status 3
init: untracked pid 6057 killed by signal 9
...
Apparently, the "init: untracked pid" is a commonly encountered problem when something within the framework or the device driver goes wrong. But as a silver lining, since I can read and write files into the root directory, I don't think I need the file /fstab.xilinxzynqplatform. I tentatively conclude that the target can successfully boot from NFS, and move onto debugging the "init: untracked pid" problem.
I checked logcat for a clue to the problem. There were many lines of "W/dex2oat ..." which is just the JIT compiler, and not of interest. So I filtered it out:
$ sed -i'' "/^W\/dex2oat .*$/d" logcat.txt
There seems to be many problems, which I should tackle one by one--starting with the surface flinger problem, which seems to be the most serious.
Vold can't find expected files
--------- beginning of system
I/Vold ( 970): Vold 2.1 (the revenge) firing up
E/Vold ( 970): failed to open /fstab.xilinxzynqplatform
E/Vold ( 970): Error reading configuration (No such file or directory)... continuing anyways
--------- beginning of system
I/Vold ( 970): Vold 2.1 (the revenge) firing up
E/Vold ( 970): failed to open /fstab.xilinxzynqplatform
E/Vold ( 970): Error reading configuration (No such file or directory)... continuing anyways
Networking initialization
--------- beginning of main
I/Netd (18971): Netd 1.0 starting
E/Netd (18971): Failed to open /proc/sys/net/ipv6/conf/default/accept_ra: No such file or directory
E/InterfaceController(18971): Can't list /proc/sys/net/ipv6/conf: No such file or directory
E/Netd (18971): Failed to open /proc/sys/net/ipv6/conf/default/accept_ra_rt_table: No such file or directory
E/InterfaceController(18971): Can't list /proc/sys/net/ipv6/conf: No such file or directory
I/iptables(18971): iptables terminated by exit(3)
E/Netd (18971): exec() res=0, status=768 for /system/bin/iptables -t filter -N bw_INPUT
--------- beginning of main
I/Netd (18971): Netd 1.0 starting
E/Netd (18971): Failed to open /proc/sys/net/ipv6/conf/default/accept_ra: No such file or directory
E/InterfaceController(18971): Can't list /proc/sys/net/ipv6/conf: No such file or directory
E/Netd (18971): Failed to open /proc/sys/net/ipv6/conf/default/accept_ra_rt_table: No such file or directory
E/InterfaceController(18971): Can't list /proc/sys/net/ipv6/conf: No such file or directory
I/iptables(18971): iptables terminated by exit(3)
E/Netd (18971): exec() res=0, status=768 for /system/bin/iptables -t filter -N bw_INPUT
Surface flinger crash
I/SurfaceFlinger(18949): SurfaceFlinger is starting
I/SurfaceFlinger(18949): SurfaceFlinger's main thread ready to run. Initializing graphics H/W...
F/libEGL (18949): couldn't find an OpenGL ES implementation
F/libc (18949): Fatal signal 6 (SIGABRT), code -6 in tid 18949 (surfaceflinger)
It would appear that the root cause is that the board does not have a HW OpenGL ES implementation. Let's explore how to work around this limitation by staring at the source code:
~/work/zed/android$ lunch source build/envsetup.sh
~/work/zed/android$ lunch zedmini-userdebug
~/work/zed/android$ cgrep "couldn't find an OpenGL ES implementation"
./frameworks/native/opengl/libs/EGL/Loader.cpp:188: LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");
I KNOW my Zedboard HW does NOT have OpenGL HW. What I would like is to enable as much of the Android features using software OpenGL, so I started reading on the subject. Linaro pulled it off for ICS (Android 4.0), so maybe it's still possible.
https://wiki.linaro.org/Platform/Android/ICSwithSoftwareGL
Instead of grepping my way through the vast Android framework code base, I want to debug in Eclipse, following the guidelines in this Intel post.
I/SurfaceFlinger(18949): SurfaceFlinger is starting
I/SurfaceFlinger(18949): SurfaceFlinger's main thread ready to run. Initializing graphics H/W...
F/libEGL (18949): couldn't find an OpenGL ES implementation
F/libc (18949): Fatal signal 6 (SIGABRT), code -6 in tid 18949 (surfaceflinger)
It would appear that the root cause is that the board does not have a HW OpenGL ES implementation. Let's explore how to work around this limitation by staring at the source code:
~/work/zed/android$ lunch source build/envsetup.sh
~/work/zed/android$ lunch zedmini-userdebug
~/work/zed/android$ cgrep "couldn't find an OpenGL ES implementation"
./frameworks/native/opengl/libs/EGL/Loader.cpp:188: LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");