使用 wandboard 兩年多了,我才決定想要紀錄一下如何編譯 wandboard 的 Android 4.4.2 (kitkat) 。這塊板子使用了 Freescale i.MX6 作為 CPU,並且有 Solo (單核)、Dual (雙核)、Quad (四核) 幾個版本可以選擇,並支援 Yocto 、Android、FreeBSD 等系統, 如果想學 Linux Driver、Android 移植等事情,這是一塊不錯的板子,畢竟 CPU 的 datasheet 可以透過 Freescale 官方網站下載(相比之下,raspberry pi 提供的 cpu 資訊不足,不適合用來學習 Linux Kernel driver 移植)。
講完優點,當然要講一下缺點。wandboard 早期提供了 Android 原始碼可以讓你透過
repo 命令去直接編譯你的 Android 系統,但是自 2013 年底他們的 Android source
mirror 就爛掉了,並且至今尚未修復,以後大概也不會修復了。wandboard 官方網站雖然
提供了 Android 原始碼,但是裡面不包含 .git 訊息,因此你也很難從中了解
wandboard 團隊到底改了什麼。
本文將提供一個指引,讓你透過 AOSP 原始碼加上 Freescale 提供的 patch,建立自己的 wandboard Android 系統,而不是只是取得被閹掉 .git 資訊的原始碼來建立 Android。
以個人的立場,我很討厭開發版/廠商使用了開放原始碼專案的程式碼,卻在提供程式碼時 刻意閹掉 .git 訊息。
(以此角度來看 wandboard 並非很好的 Android 開發版)
安裝 repo 命令
要取得 Android 原始碼,就必須先安裝 Android 用來管理專案用的工具 repo ,你可以透
過以下命令將其存放到你的 ~/bin 目錄
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo
安裝完成後,可以使用 which 命令來檢查是否可以找到 repo 命令
coldnew@Rosia ~ $ which repo /home/coldnew/bin/repo
如果找不到的話,記得將 ~/bin 加入到你的 PATH 中
coldnew@Rosia ~ $ export PATH="~/bin:$PATH"
取得 AOSP 4.4.2 原始碼
首先先建立我們要用來存放 Android 原始碼的資料夾
coldnew@Rosia ~ $ mkdir ~/aosp_imx-4.4.2_r1 && cd $_
接著透過 repo 命令,初始化你的專案,這邊我們使用 android-4.4.2_r1 這個 branch
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ repo init -u https://android.googlesource.com/platform/manifest -b android-4.4.2_r1
再來就要使用 repo sync 進行程式碼的取得,這裡可能會很花時間,所以可以趁這機會去泡杯咖啡~
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ repo sync -j9
下載 Freescale patches
Freescale 針對其旗下的 i.MX6 CPU 提供了建立 Android 系統所需要的 patch,我們可以 到 Freescale 官方網站去下載 Android 4.4.2 所需要的 BSP (Board Support Packages)。
請點選 此處 到 Freescale 註冊並下載此篇文章所需要的 android_kk4.4.2_1.0.0-ga_core_source.tar.gz 檔案。
下載完成後,我們進入到我們剛剛建立的 Android 4.4.2 專案,並將 android_kk4.4.2_1.0.0-ga_core_source.tar.gz 解壓,完成後你現在的目
錄應該是這個樣子:
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ ls Makefile android_kk4.4.2_1.0.0-ga_core_source bionic build dalvik development docs frameworks libcore ndk packages prebuilts system abi art bootable cts developers device external hardware libnativehelper out pdk sdk tools
接著使用以下命令將 patch 打上
source android_kk4.4.2_1.0.0-ga_core_source/code/kk4.4.2_1.0.0-ga/and_patch.sh c_patch android_kk4.4.2_1.0.0-ga_core_source/code/kk4.4.2_1.0.0-ga imx_kk4.4.2_1.0.0-ga
後面的 imx_kk4.4.2_1.0.0-ga 這個是說當 patch 打上以後,有被修改的部分都會切到
imx_kk4.4.2_1.0.0-ga 這個 branch,方便對程式進行管理。
下載 wandboard 的 device 設定與 kernel/u-boot
除了打上 Freescale 的 patch 以外,我們還需要下載 wandboard 的 kernel/uboot 以及設定檔。
device_fsl_wandboard
在 wandboard 的 Android 程式碼中,他們強制修改了
device/fsl並加上 wandboard 設定,其實這是一個很討厭的作法,所以我將他切割出 來並放置於 GitHub ,你可以使用 git 下載到device/fsl/wandboardgit clone https://github.com/coldnew/device_fsl_wandboard.git -b imx_kk4.4.2_1.0.0-ga device/fsl/wandboard
kernel
接著下載 wandboard 的 kernel 到
kernel_imxgit clone https://github.com/wandboard-org/linux.git -b wandboard_imx_3.0.35_kk4.4.2_1.0.0-ga kernel_imx
u-boot
在 GitHub 上的 wandbord 的 uboot 是不含 Android 版本的,
你看 wandboard 多適合 Android 開發者啊,因此 u-boot 這邊我只好從 wandboard 提供的 Android 原始 碼裡面提取 (該死的 first commit),請使用我傳到 GitHub 的版本,下載到bootable/bootloader/uboot-imxgit clone https://github.com/coldnew/u-boot-fslc.git -b wandboard_imx_3.0.35_kk4.4.2_1.0.0-ga bootable/bootloader/uboot-imx
進行一些小修正
由於 wandboard 使用的 wifi driver 和 Freescale 提供的開發版 (sabresd …etc) 設
定不太一樣,因此我們必須對 wifi 驅動進行修正,這樣才能避免編譯錯誤。造成這個問題
的主因,是因為在 wandboard 的 BoardConfig.mk 中我們指定了 BOARD_WLAN_DEVICE
的名稱,但是在 hardware/ 下面卻無法有匹配的資訊,導致需要的 lib 沒有被編譯到。
在我們的 BoardConfig.mk 是這樣設定的:
BOARD_WLAN_DEVICE := brcmfmac
因此有個地方要修改:
hardware/realtek/wlan/Android.mk
diff --git a/Android.mk b/Android.mk index ff0812e..7e77b6c 100755 --- a/Android.mk +++ b/Android.mk @@ -1,4 +1,4 @@ -ifeq ($(BOARD_WLAN_DEVICE),$(filter $(BOARD_WLAN_DEVICE), REALTEK UNITE)) +ifeq ($(BOARD_WLAN_DEVICE),$(filter $(BOARD_WLAN_DEVICE), REALTEK UNITE brcmfmac)) include $(call all-subdir-makefiles) endif
hardware/qcom/wlan/qcwcn/Android.mk
diff --git a/Android.mk b/Android.mk index b83e42b..44c9fe7 100644 --- a/Android.mk +++ b/Android.mk @@ -1,3 +1,3 @@ -ifeq ($(BOARD_WLAN_DEVICE),$(filter $(BOARD_WLAN_DEVICE), qcwcn UNITE)) +ifeq ($(BOARD_WLAN_DEVICE),$(filter $(BOARD_WLAN_DEVICE), qcwcn UNITE brcmfmac)) include $(call all-subdir-makefiles) endif
加入 codec 支援
除了前面提到的修正,我們也需要替 wandboard 加上 codec 的支援,這部分要設定在
hardware/imx/alsa 裡面,由於 wandboard 使用的 codec IC 為 sgtl5000 ,因此我們
先增加 config_sgtl5000.h 這個檔案,其內容如下
/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2012 Freescale Semiconductor, Inc. */ #ifndef ANDROID_INCLUDE_IMX_CONFIG_SGTL5000_H #define ANDROID_INCLUDE_IMX_CONFIG_SGTL5000_H #include "audio_hardware.h" /* ALSA cards for IMX, these must be defined according different board / kernel config*/ static struct audio_card sgtl5000_card = { .name = "sgtl5000-audio", .driver_name = "sgtl5000-audio", .supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | AUDIO_DEVICE_OUT_ALL_SCO | AUDIO_DEVICE_OUT_DEFAULT), .supported_in_devices = ( AUDIO_DEVICE_IN_COMMUNICATION | AUDIO_DEVICE_IN_AMBIENT | AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_ALL_SCO | AUDIO_DEVICE_IN_DEFAULT), .defaults = NULL, .bt_output = NULL, .speaker_output = NULL, .hs_output = NULL, .earpiece_output = NULL, .vx_hs_mic_input = NULL, .mm_main_mic_input = NULL, .vx_main_mic_input = NULL, .mm_hs_mic_input = NULL, .vx_bt_mic_input = NULL, .mm_bt_mic_input = NULL, .card = 0, .out_rate = 0, .out_channels = 0, .out_format = 0, .in_rate = 0, .in_channels = 0, .in_format = 0, }; #endif /* ANDROID_INCLUDE_IMX_CONFIG_HDMI_H */
接著依照以下 patch 修改 tinyalsa_hal.c 這個檔案,將我們的設定加入就完成囉 ~
diff --git a/tinyalsa_hal.c b/tinyalsa_hal.c index 5084138..05a8e9f 100644 --- a/tinyalsa_hal.c +++ b/tinyalsa_hal.c @@ -46,6 +46,7 @@ #include "config_nullcard.h" #include "config_spdif.h" #include "config_cs42888.h" +#include "config_sgtl5000.h" /* ALSA ports for IMX */ @@ -95,10 +96,11 @@ /*"null_card" must be in the end of this array*/ struct audio_card *audio_card_list[SUPPORT_CARD_NUM] = { + &usbaudio_card, + &sgtl5000_card, + &hdmi_card, &wm8958_card, &wm8962_card, - &hdmi_card, - &usbaudio_card, &spdif_card, &cs42888_card, &null_card,
編譯 Android
上面的修改都完成後,我們就可以開始來編譯 Android, 首先要切換一下目前的 shell 環境
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ source build/envsetup.sh including device/fsl/imx5x/vendorsetup.sh including device/fsl/imx6/vendorsetup.sh including device/fsl/wandboard/vendorsetup.sh including device/samsung/manta/vendorsetup.sh including device/asus/deb/vendorsetup.sh including device/asus/flo/vendorsetup.sh including device/asus/tilapia/vendorsetup.sh including device/asus/grouper/vendorsetup.sh including device/generic/mips/vendorsetup.sh including device/generic/x86/vendorsetup.sh including device/generic/armv7-a-neon/vendorsetup.sh including device/lge/hammerhead/vendorsetup.sh including device/lge/mako/vendorsetup.sh including sdk/bash_completion/adb.bash
接著我們就可以使用 lunch 去選擇想要編譯的環境
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ lunch
You're building on Linux
Lunch menu... pick a combo:
....
17. hdmidongle_6dq-eng
18. hdmidongle_6dq-user
19. wandboard-eng
20. wandboard-user
21. aosp_manta-userdebug
22. aosp_deb-userdebug
...
Which would you like? [aosp_arm-eng] 20
選擇好後就可以開始進行編譯
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ m -j9 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.4.2 TARGET_PRODUCT=wandboard TARGET_BUILD_VARIANT=user TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a-neon TARGET_CPU_VARIANT=cortex-a9 HOST_ARCH=x86 HOST_OS=linux HOST_OS_EXTRA=Linux-4.1.4-gentoo-x86_64-Intel-R-_Core-TM-_i5-5257U_CPU_@_2.70GHz-with-gentoo-2.2 HOST_BUILD_TYPE=release BUILD_ID=1.0.0-rc3 OUT_DIR=out ============================================ ...
假設一切都很順利的話,你就會在 out/target/product/wandboard/ 看到你編譯出來的檔案
coldnew@Rosia ~/aosp_imx-4.4.2_r1 $ ls out/target/product/wandboard/ android-info.txt fake_packages previous_build_config.mk recovery.img system.img boot.img installed-files.txt ramdisk.img root u-boot.bin clean_steps.mk kernel ramdisk-recovery.img symbols u-boot-wandboard_config.bin dex_bootjars obj recovery system uImage