2015/12/31

ethernet service eneble/disable in android 5

ethernet service:
./services/java/com/android/server/SystemServer.java:674:                if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {


    private void startOtherServices() {
        ...
        ...
                if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
                    mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
                }
茶一下 FEATURE_ETHERNET...
./core/java/android/content/pm/PackageManager.java:1570:    public static final String FEATURE_ETHERNET = "android.hardware.ethernet";
這個: android.hardware.ethernet 是在:
frameworks/native/data/etc/android.hardware.ethernet.xml:

<permissions>
    <feature name="android.hardware.ethernet" />
</permissions>


這個 file 是被copy ...
device/fsl/imx6/sabreauto_6q.mk:

PRODUCT_COPY_FILES += \
        frameworks/native/data/etc/android.hardware.audio.output.xml:system/etc/permissions/android.hardware.audio.output.xml \
        frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \
        ....
        ...
        frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml \
把這行刪掉以後,ethernet service 就不會起來了。

2015/12/28

正確的 SD init..
mmc_attach_sd
mmc_sd_get_cid ocr:60000
 | SD_OCR_CCS
 | SD_OCR_S18R
sd_get_host_max_current
300
 | SD_OCR_XPC
mmc2: host does not support reading read-only switch. assuming write-enable.
sd_get_host_max_current
300
mmc2: new ultra high speed SDR104 SDHC card at address 59b4


build . BoardConfig.mk 中 bootloader 部份:
TARGET_BOARD_DTS_CONFIG := imx6q:imx6q-sabreauto.dtb imx6dl:imx6dl-sabreauto.dtb
所以是 dtb 不同。

這兩個 dts. 很多不一樣:
dl 只有兩個mxcfb
q 有四個

Write Protect:
static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
{
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
        struct esdhc_platform_data *boarddata = &imx_data->boarddata;

        switch (boarddata->wp_type) {
        case ESDHC_WP_GPIO:
                return mmc_gpio_get_ro(host->mmc);
        case ESDHC_WP_CONTROLLER:
                return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
                               SDHCI_WRITE_PROTECT);
        case ESDHC_WP_NONE:
                break;
        }

        return -ENOSYS;
}

.....

        if (of_get_property(np, "fsl,wp-controller", NULL))
                boarddata->wp_type = ESDHC_WP_CONTROLLER;

 
        boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
        if (gpio_is_valid(boarddata->wp_gpio))
                boarddata->wp_type = ESDHC_WP_GPIO;

.....


CD PIN:
        switch (boarddata->cd_type) {
        case ESDHC_CD_GPIO:
                err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio);
                if (err) {
                        dev_err(mmc_dev(host->mmc),
                                "failed to request card-detect gpio!\n");
                        goto disable_clk;
                }
                /* fall through */

        case ESDHC_CD_CONTROLLER:
                /* we have a working card_detect back */
                host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
                break;

        case ESDHC_CD_PERMANENT:
                host->mmc->caps |= MMC_CAP_NONREMOVABLE;
                break;

        case ESDHC_CD_NONE:
                break;
        }

....
        if (of_get_property(np, "non-removable", NULL))
                boarddata->cd_type = ESDHC_CD_PERMANENT;

        if (of_get_property(np, "fsl,cd-controller", NULL))
                boarddata->cd_type = ESDHC_CD_CONTROLLER;
        ....

        boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
        if (gpio_is_valid(boarddata->cd_gpio))
                boarddata->cd_type = ESDHC_CD_GPIO;

2015/12/25

uboot - debug uart config

有關 debug UART setting:
mx6qsabreauto.h:#define CONFIG_MXC_UART_BASE UART4_BASE
mx6sabresd.h:   #define CONFIG_MXC_UART_BASE UART1_BASE

mx6slevk.h:#define CONFIG_MXC_UART_BASE  UART1_IPS_BASE_ADDR
mx6sx_arm2.h:#define CONFIG_MXC_UART_BASE  UART1_BASE
mx6sxsabreauto.h:#define CONFIG_MXC_UART_BASE  UART1_BASE
mx6sxsabresd.h:#define CONFIG_MXC_UART_BASE  UART1_BASE

所以 auto 是 UART4, SD是 UART1

這是included by..include/config.h
內容是..
/* Automatically generated - do not edit */
#define CONFIG_IMX_CONFIG       board/freescale/mx6qsabreauto/mx6solo.cfg
#define CONFIG_MX6SOLO  1
#define CONFIG_DEFAULT_FDT_FILE "imx6dl-sabreauto.dtb"
#define CONFIG_DDR_MB   1024
#define CONFIG_SYS_BOOT_NAND    1
#define CONFIG_SYS_NOSMP        "nosmp"
#define CONFIG_SYS_ARCH  "arm"
#define CONFIG_SYS_CPU   "armv7"
#define CONFIG_SYS_BOARD "mx6qsabreauto"
#define CONFIG_SYS_VENDOR "freescale"
#define CONFIG_SYS_SOC    "mx6"
#define CONFIG_BOARDDIR board/freescale/mx6qsabreauto
#include  < config_cmd_defaults.h >
#include  < config_defaults.h >
#include  < configs/mx6qsabreauto.h >
#include  < asm/config.h >
#include  < config_fallbacks.h >
#include  < config_uncmd_spl.h >

這是由 mkconfig 產生...
...
cat << EOF >> config.h
#include < config_cmd_defaults.h >
#include < config_defaults.h >
#include < configs/${CONFIG_NAME}.h >
#include < asm/config.h >
...

其中 CONFIG_NAME 就是..
if [ "$options" ] ; then
        echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else



還有 pad mux 的部份:
./mx6qsabreauto/mx6qsabreauto.c:326:  static void setup_iomux_uart(void)
./mx6sabresd   /mx6sabresd.c   :250:  static void setup_iomux_uart(void)

uboot , make and board config

刪除掉 out target 的 u-boot*
make showcommands bootloader
看一下 config 成 auto 時,u-boot 的 config files 有哪些...

Configuring for mx6qsabreautoandroid - Board: mx6qsabreauto, 
Options: 
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6q.cfg,
MX6Q,
DEFAULT_FDT_FILE="imx6q-sabreauto.dtb",
DDR_MB=2048,
ANDROID_SUPPORT


Configuring for mx6dlsabreautoandroid - Board: mx6qsabreauto, 
Options: 
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,
MX6DL,
DEFAULT_FDT_FILE="imx6dl-sabreauto.dtb",
DDR_MB=2048,
ANDROID_SUPPORT


Configuring for mx6solosabresdandroid - Board: mx6sabresd, 
Options: 
IMX_CONFIG=board/freescale/mx6sabresd/mx6solo_4x_mt41j128.cfg,
MX6SOLO,
DEFAULT_FDT_FILE="imx6dl-sabresd.dtb",
DDR_MB=512,
SYS_USE_SPINOR,
SYS_NOSMP="nosmp",
ANDROID_SUPPORT


Configuring for mx6qsabreautoandroid_nand - Board: mx6qsabreauto, 
Options: 
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6q.cfg,
MX6Q,
DEFAULT_FDT_FILE="imx6q-sabreauto.dtb",
DDR_MB=2048,
SYS_BOOT_NAND,
ANDROID_SUPPORT


Configuring for mx6dlsabreautoandroid_nand - Board: mx6qsabreauto, 
Options: 
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,
MX6DL,
DEFAULT_FDT_FILE="imx6dl-sabreauto.dtb",
DDR_MB=2048,
SYS_BOOT_NAND,
ANDROID_SUPPORT


Configuring for mx6solosabreauto_nand - Board: mx6qsabreauto, 
Options: 
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6solo.cfg,
MX6SOLO,
DEFAULT_FDT_FILE="imx6dl-sabreauto.dtb",
DDR_MB=1024,
SYS_BOOT_NAND,
SYS_NOSMP="nosmp"



這些都定義在 boards.cfg:
Active  arm   armv7          mx6         freescale       mx6qsabreauto       mx6dlsabreautoandroid
mx6qsabreauto:
IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,
MX6DL,
DEFAULT_FDT_FILE="imx6dl-sabreauto.dtb",
DDR_MB=2048,
ANDROID_SUPPORT


對照一下 sabresd:
Active  arm   armv7          mx6         freescale       mx6sabresd          mx6dlsabresdandroid    
mx6sabresd:
IMX_CONFIG=board/freescale/mx6sabresd/mx6dl_4x_mt41j128.cfg,
MX6DL,
DEFAULT_FDT_FILE="imx6dl-sabresd.dtb",
DDR_MB=1024,
SYS_USE_SPINOR,
ANDROID_SUPPORT

Active  arm         armv7          mx6         freescale       mx6sabresd          mx6qsabresdandroid
mx6sabresd:
IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,
MX6Q,
DEFAULT_FDT_FILE="imx6q-sabresd.dtb",
DDR_MB=1024,
SYS_USE_SPINOR,
ANDROID_SUPPORT    

2015/12/18

大概是..
repo forall -c '~/mypathch.sh'

然後就可以依照 manifest.xml 到每個 project 操作..

2015/12/11

wandboard -- with official freescale bsp

project bootable/bootloader/uboot-imx/          branch wand
project device/fsl/                             branch wand
project hardware/broadcom/libbt/                branch wand
project hardware/imx/                           branch wand
project hardware/libhardware_legacy/            branch wand
project kernel_imx/                             branch wand
project system/core/                            branch wand

有一個 brcm 的 folder, 所以找一下有沒有用到...
./linux-linaro-stable-mx6/include/linux/platform_data/brcmfmac-sdio.h
./out/target/product/wandboard/system/etc/firmware/brcm/brcmfmac4329-sdio.txt
./out/target/product/wandboard/system/etc/firmware/brcm/brcmfmac4330-sdio.txt
./out/target/product/wandboard/system/etc/firmware/brcm/brcmfmac4330-sdio.bin
./out/target/product/wandboard/system/etc/firmware/brcm/brcmfmac4329-sdio.bin
./out/target/product/wandboard/system/lib/modules/brcmfmac.ko
./device/fsl/wandboard/brcm-firmware/brcmfmac4329-sdio.txt
./device/fsl/wandboard/brcm-firmware/brcmfmac4330-sdio.txt
./device/fsl/wandboard/brcm-firmware/brcmfmac4330-sdio.bin
./device/fsl/wandboard/brcm-firmware/brcmfmac4329-sdio.bin
./kernel_imx/include/linux/platform_data/brcmfmac-sdio.h
./kernel_imx/include/config/brcmfmac.h
./kernel_imx/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.mod.o
./kernel_imx/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.mod.c
./kernel_imx/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.o
./kernel_imx/drivers/net/wireless/brcm80211/brcmfmac/brcmfmac.ko
./kernel_imx/.tmp_versions/brcmfmac.mod
./brcm/brcmfmac4329-sdio.txt
./brcm/brcmfmac4330-sdio.txt
./brcm/brcmfmac4330-sdio.bin
./brcm/brcmfmac4329-sdio.bin

覆蓋後 branch:
*  copy-wand                 | in:
                                   bootable/bootloader/uboot-imx
                                   build
                                   device/fsl
                                   hardware/broadcom/libbt
                                   hardware/imx
                                   hardware/libhardware_legacy
                                   kernel_imx
                                   prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9
還有新增了 cooker folder,
另外新增的 brcm linux-linaro-stable-mx6 好像沒用到。

原來的 kernel bootcmd 已經有 androidboot.selinux=disabled
只要把 device/fsl/imx6/etc/init.rc 的 adb.secure 1 改 0 之後,adb 就可以動了。
-- 如果要使用 Vysor, 要用 adb remount 讓 system 變成 rw

因為uboot 用了 SPL. 所以一起 build 的時候,如果使用太多 thread 來 build, 就會 fail. -- 說找不到 SPL
所以要先 build 好 uboot:
make bootloader
之後就可以了。

OK..make bootloader && make -j10 就可以 build 完,之後 copy cooker 過來。
一樣run env_wb.sh 後 flashcard /dev/sdb 就可以。


另一個,在 官方 bsp 覆蓋 wandboard source 的方式。
最後, bt, wifi 都 working 的修改...
project bootable/bootloader/uboot-imx/          branch wand
project device/fsl/                             branch wand
project hardware/broadcom/libbt/                branch copy-wand
project hardware/imx/                           branch copy-wand
project hardware/libhardware_legacy/            branch copy-wand
project kernel_imx/                             branch copy-wand


所以把patch 放到 github: https://github.com/checko/wandboard-5.0.2_r1

先依照 freescale bsp 的 user guide 準備好 android-5.0.2_r1 的 source.
然後依照 github readme 的目錄位置一一 patch 就可以了

這個patch 只有修改 source code,所以燒錄與 eMMC/SD 的 pattition layout 都和標準 freescale bsp 一樣。
所以燒錄SD的方式是用 fsl-sdcard-partition.sh

2015/12/3

wandbord bsp and freescale official bsp ...

結果, sabresd 的 eMMC 是 SDHC4, wandboard 的 eim sd slot 是 SDHC3
wandboard 的 bootmode 是 boot to SD3
所以 u-boot 去 check SD3 的 CD pin, 發現level 不對。就沒 init 了。

只要改
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index d24eea1..9646438 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -549,7 +549,7 @@ int board_mmc_getcd(struct mmc *mmc)
                ret = !gpio_get_value(USDHC2_CD_GPIO);
                break;
        case USDHC3_BASE_ADDR:
-               ret = !gpio_get_value(USDHC3_CD_GPIO);
+               ret = 1; /* wandboard : assum always boot from SD3 *?
                break;
        case USDHC4_BASE_ADDR:
                ret = 1; /* eMMC/uSDHC4 is always present */

就可以開機了..
然後開機到 kernel.....
之後因為 wandboard 是用 LDO 分散式的 電源,sabresd 是用 pmic , ,, 所以....

兩邊用 tig 看一下 git log, 發現wandboard 真的是基於 l5.0.0_1.0.0-ga 這個tag 開始修改。


/hardware/imx/wlan/atheros/compat-wireless/config.mk:49: 
*** "ERROR: your kernel has CONFIG_CFG80211=y, you should have it CONFIG_CFG80211=m if you want to use this thing.".  Stop.
wandboard 的 bsp 是:
diff --git a/wlan/Android.mk b/wlan/Android.mk
index 5fb1071..25f5781 100644
--- a/wlan/Android.mk
+++ b/wlan/Android.mk
@@ -1,4 +1,4 @@
 atheros_dirs := compat-wireless
 ifeq ($(BOARD_WLAN_DEVICE),$(filter $(BOARD_WLAN_DEVICE),ar6003 UNITE))
-    include $(call all-subdir-makefiles,$(atheros_dirs))
+    #include $(call all-subdir-makefiles,$(atheros_dirs))
 endif
所以是用 kernel 的 source.


燒錄出問題。
dd: failed to open ‘boot-imx6dl.img’: No such file or directory
dd: failed to open ‘recovery-imx6dl.img’: No such file or directory

看一下 燒錄 script:
function flash_android
{
    bootloader_file="u-boot-${soc_name}.imx"
    bootimage_file="boot-${soc_name}.img"
    recoveryimage_file="recovery-${soc_name}.img"
if [ "${flash_images}" -eq "1" ]; then
    echo "flashing android images..."    
    echo "bootloader: ${bootloader_file}"
    echo "boot image: ${bootimage_file}"
    echo "recovery image: ${recoveryimage_file}"
    echo "system image: ${systemimage_file}"
    dd if=/dev/zero of=${node} bs=1k seek=384 count=129
    dd if=${bootloader_file} of=${node} bs=1k seek=1
    dd if=${bootimage_file} of=${node}${part}1
    dd if=${recoveryimage_file} of=${node}${part}2
    dd if=${systemimage_file} of=${node}${part}5
    sync
fi
}

soc_name 就是 -f 的 option

所以要看一下 有沒有..
  • u-boot-XXX.imx
  • boot-XXX.img
  • recovery-XXX.img
  • system.img
先從 boot-XXX.img 開始..
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)

        for dtsplat in $(TARGET_BOARD_DTS_CONFIG); do \
                DTS_PLATFORM=`echo $$dtsplat | cut -d':' -f1`; \
                DTS_BOARD=`echo $$dtsplat | cut -d':' -f2`; \
                BOOT_IMAGE_BOARD=$(patsubst %.img,%-$$DTS_PLATFORM.img,$@); \
                $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --second $(PRODUCT_OUT)/$$DTS_BOARD $(BOARD_MKBOOTIMG_ARGS) --output $@; \
                $(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY) $@;\
                $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)); \
                cp -f $@ $$BOOT_IMAGE_BOARD; \
        done
其中
     BOOT_IMAGE_BOARD=$(patsubst %.img,%-$$DTS_PLATFORM.img,$@); \
決定 boot-$$DTS_PLATFORM.img
就是從 TARGET_BOARD_DTS_CONFIG 來的。
這個宣告在 device/fsl/wandboard/BoardConfig.mk:
wandboard/BoardConfig.mk:
TARGET_BOARD_DTS_CONFIG := imx6q-wandboard.dtb imx6dl-wandboard.dtb
所以是這裡寫錯了...
應該是..
TARGET_BOARD_DTS_CONFIG := imx6q:imx6q-wandboard.dtb imx6dl:imx6dl-wandboard.dtb

這樣就會 build 出 xxx=imx6dl 的 image

2015/12/2

uboot - from imx to wandboard

來看 wandboard.
device/fsl/wandboard/BoardConfig.mk:
TARGET_BOOTLOADER_CONFIG := wandboard_spl_android_defconfig
TARGET_BOARD_DTS_CONFIG := imx6q-wandboard.dtb imx6dl-wandboard.dtb

build/core/Makefile是一樣的,
所以 UBOOT_CONFIG 會是 null
所以 最後 build 出來的 bin 會是 u-boot-wandboard_spl_android_defconfig.img

wandboard 的 uboot 版本(2014.10)跟 freescale 標準 bsp 不同(2014.04)。
wandboard 使用kconfig, 所以跟 kernel 一樣,是用 defconfig
不是用 mkconfig 解析 target string

wandboard 的 defconfig 都放在 configs 下。
所以,會是 wandboard_spl_android_defconfig

Makefile % -- uboot

ref: http://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html#Pattern-Rules

說明 '%' 代表萬用字,就有點像 shell command 的 '*'

所以 uboot Makefile 中:
%_config:: outputmakefile
        @$(MKCONFIG) -A $(@:_config=)
就是任意以 _config 結尾的 target.

所以uboot 的 readme 說... make (board_name)_config

會把 (board_name) 餵進 MKCONFIG (就是 mkconfig 是一個 shell script)

uboot - imx6

device/fsl/sabresd_6dq/BoardConfig.mk
TARGET_BOOTLOADER_CONFIG := imx6q:mx6qsabresdandroid_config imx6dl:mx6dlsabresdandroid_config
TARGET_BOARD_DTS_CONFIG := imx6q:imx6q-sabresd.dtb imx6dl:imx6dl-sabresd.dtb imx6q-ldo:imx6q-sabresd-ldo.dtb

Makefile:
BOOTLOADER_CROSS_TOOLCHAIN := `pwd`/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
BOOTLOADER_ENV := ARCH=arm CROSS_COMPILE=$(BOOTLOADER_CROSS_TOOLCHAIN)
HOST_PROCESSOR := $(shell cat /proc/cpuinfo | grep processor | wc -l)
TARGET_BOOTLOADER_IMAGE := $(PRODUCT_OUT)/u-boot.imx

BOOTLOADER_PATH := bootable/bootloader/uboot-imx/
BOOTLOADER_CONFIG_FILE := $(BOOTLOADER_PATH)/include/config.h

bootloader: $(TARGET_BOOTLOADER_IMAGE)

$(TARGET_BOOTLOADER_IMAGE):
        for ubootplat in $(TARGET_BOOTLOADER_CONFIG); do \
                UBOOT_PLATFORM=`echo $$ubootplat | cut -d':' -f1`; \
                UBOOT_CONFIG=`echo $$ubootplat | cut -d':' -f2`; \
        echo $(UBOOT_PLATFORM); \
        echo $(UBOOT_CONFIG); \
                $(MAKE) -C bootable/bootloader/uboot-imx/ distclean $(BOOTLOADER_ENV); \
                $(MAKE) -C bootable/bootloader/uboot-imx/ $$UBOOT_CONFIG $(BOOTLOADER_ENV); \
                $(MAKE) -C bootable/bootloader/uboot-imx/ $(BOOTLOADER_ENV); \
                install -D bootable/bootloader/uboot-imx/u-boot.imx $(PRODUCT_OUT)/u-boot-$$UBOOT_PLATFORM.imx; \
                install -D bootable/bootloader/uboot-imx/u-boot.imx $@; \
        done

所以不管 lunch 選的是什麼,bootloader 一定會 build 兩個 target (imx6q, imx6dl) 出來。
所以:
  • imx6q : mx6qsabresdandroid_config
  • imx6dl: mx6dlsabresdandroid_config

make 的 command 就是:
export ARCH=arm
export CROSS_COMPILE=`pwd`/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-

cd bootable/bootlaoder/uboot-imx
make distclean
make mx6dlsabresdandroid_config
uboot 的 README 說:
Selection of Processor Architecture and Board Type:
---------------------------------------------------

For all supported boards there are ready-to-use default
configurations available; just type "make _config".

Example: For a TQM823L module type:

        cd u-boot
        make TQM823L_config

For the Cogent platform, you need to specify the CPU type as well;
e.g. "make cogent_mpc8xx_config". And also configure the cogent
directory according to the instructions in cogent/README.


Configuration Options:
----------------------

Configuration depends on the combination of board and CPU type; all
such information is kept in a configuration file
"include/configs/.h".

Example: For a TQM823L module, all configuration settings are in
"include/configs/TQM823L.h".
所以 make mx6dlsabresdandroid_config , board_name 就是 mx6dlsabreshandroid

刪除 target out folder 的 u-boot-*, 之後 make bootloader, 才會重新 build
可以看到 make log 有:
Configuring for mx6qsabresdandroid - 
Board: mx6sabresd, 
Options: 
IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,
MX6Q,
DEFAULT_FDT_FILE="imx6q-sabresd.dtb",
DDR_MB=1024,
SYS_USE_SPINOR,
ANDROID_SUPPORT
Configuring for mx6dlsabresdandroid - 
Board: mx6sabresd, 
Options: 
IMX_CONFIG=board/freescale/mx6sabresd/mx6dl_4x_mt41j128.cfg,
MX6DL,
DEFAULT_FDT_FILE="imx6dl-sabresd.dtb",
DDR_MB=1024,
SYS_USE_SPINOR,
ANDROID_SUPPORT

2015/11/30

有點麻煩的...

覆蓋後,repo status 列出修改:
project bionic/                                 (*** NO BRANCH ***)
project bootable/recovery/                      (*** NO BRANCH ***)
project bootable/bootloader/uboot-imx/          (*** NO BRANCH ***)
 -- board/alpha
project/ap_sh4a_4a/Kconfig
 -- board/alpha
project/ap_sh4a_4a/MAINTAINERS
project build/                                  (*** NO BRANCH ***)
project dalvik/                                 (*** NO BRANCH ***)
project device/fsl/                             (*** NO BRANCH ***)
project external/bluetooth/bluedroid/           (*** NO BRANCH ***)
project external/chromium_org/                  (*** NO BRANCH ***)
project external/dnsmasq/                       (*** NO BRANCH ***)
project external/kernel-headers/                (*** NO BRANCH ***)
project external/libselinux/                    (*** NO BRANCH ***)
project external/linux-tools-perf/              (*** NO BRANCH ***)
project external/ppp/                           (*** NO BRANCH ***)
project external/skia/                          (*** NO BRANCH ***)
project external/tinyalsa/                      (*** NO BRANCH ***)
project external/wpa_supplicant_8/              (*** NO BRANCH ***)
project frameworks/av/                          (*** NO BRANCH ***)
project frameworks/native/                      (*** NO BRANCH ***)
project frameworks/opt/telephony/               (*** NO BRANCH ***)
project frameworks/webview/                     (*** NO BRANCH ***)
project hardware/broadcom/libbt/                (*** NO BRANCH ***)
project hardware/imx/                           (*** NO BRANCH ***)
project hardware/libhardware/                   (*** NO BRANCH ***)
project hardware/libhardware_legacy/            (*** NO BRANCH ***)
project frameworks/base/                        (*** NO BRANCH ***)
project hardware/qcom/wlan/                     (*** NO BRANCH ***)
project hardware/ril/                           (*** NO BRANCH ***)
project kernel_imx/                             (*** NO BRANCH ***)
project libcore/                                (*** NO BRANCH ***)
project packages/apps/Browser/                  (*** NO BRANCH ***)
project packages/apps/Camera2/                  (*** NO BRANCH ***)
project packages/apps/Gallery/                  (*** NO BRANCH ***)
project packages/apps/Gallery2/                 (*** NO BRANCH ***)
project packages/apps/Launcher2/                (*** NO BRANCH ***)
project packages/apps/LegacyCamera/             (*** NO BRANCH ***)
project packages/apps/Settings/                 (*** NO BRANCH ***)
project packages/apps/SoundRecorder/            (*** NO BRANCH ***)
project prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9/ (*** NO BRANCH ***)
project system/core/                            (*** NO BRANCH ***)
project system/extras/                          (*** NO BRANCH ***)
project system/netd/                            (*** NO BRANCH ***)
project system/vold/                            (*** NO BRANCH ***)

..太麻煩了..
bootloader base function 也不一樣。
wandboard 好像是從 boundarydevice 的 EVB 改的,他的 bsp 比較接近 boundarydevice

console UART 是 UART1
-- 所以比較接近 sd ?

core EDM 上的 SD socket 是 SD3
-- SD,AI board 的 SD3 是接到 eMMC

2015/11/27

bookmarks about android audio output device selection

lineout 聲音

http://forums.wandboard.org/viewtopic.php?f=11&t=410
http://forums.wandboard.org/viewtopic.php?f=11&t=777
https://groups.google.com/forum/#!topic/wandboard/r6gF4UrXc0U
https://boundarydevices.com/hdmi/
https://groups.google.com/forum/#!topic/wandboard/0CctR_VjdlE

wandboard, 5.0.2 燒錄 sdcard

使用 prebuilt image : wandboard-lp-5.0.2-ga-20150622-sdcard.img 開機後的..
tmpfs  /dev tmpfs rw,nosuid,relatime,mode=755 0 0
tmpfs  /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0
tmpfs  /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0
tmpfs  /mnt/shm tmpfs rw,relatime,size=1024k,mode=775,uid=1013,gid=1000 0 0
devpts /dev/pts devpts rw,relatime,mode=600 0 0
proc   /proc proc rw,relatime 0 0
sysfs  /sys sysfs rw,relatime 0 0
pstore /sys/fs/pstore pstore rw,relatime 0 0
tmpfs  /data tmpfs rw,nosuid,nodev,noatime,size=262144k,mode=771,uid=1000,gid=1000 0 0
adb    /dev/usb-ffs/adb functionfs rw,relatime 0 0
none   /sys/kernel/debug debugfs rw,relatime 0 0
none   /acct cgroup rw,relatime,cpuacct 0 0
none   /sys/fs/cgroup tmpfs rw,relatime,mode=750,gid=1000 0 0
none   /dev/cpuctl cgroup rw,relatime,cpu 0 0

/dev/block/mmcblk2p6 /cache ext4 rw,nosuid,nodev,relatime,data=ordered 0 0
/dev/block/mmcblk2p7 /device ext4 ro,nosuid,nodev,relatime,data=ordered 0 0
/dev/block/mmcblk2p5 /system ext4 ro,relatime,data=ordered 0 0

kernel cmd 是:
Kernel command line: root=/dev/mmcblk2p2 rootwait rw console=ttymxc0,115200 
init=/init androidboot.console=ttymxc0 androidboot.hardware=freescale 
vmalloc=300M androidboot.selinux=disabled

board 上的 RS232 connect 要加上 null-modem adaptor

partitions :
  sdb: sdb1 sdb2 sdb3 < sdb5 sdb6 sdb7 sdb8 sdb9 > sdb4

$ sudo fdisk -l /dev/sdb

Disk /dev/sdb: 7.2 GiB, 7750025216 bytes, 15136768 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot   Start      End  Sectors   Size Id Type
/dev/sdb1         15438   154379   138942  67.9M 83 Linux
/dev/sdb2        154380   185255    30876  15.1M 83 Linux
/dev/sdb3        185256  2408327  2223072   1.1G  5 Extended
/dev/sdb4       2408328 15885701 13477374   6.4G 83 Linux
/dev/sdb5        185257  1235039  1049783 512.6M 83 Linux
/dev/sdb6       1235041  2284823  1049783 512.6M 83 Linux
/dev/sdb7       2284825  2315699    30875  15.1M 83 Linux
/dev/sdb8       2315701  2331137    15437   7.6M 83 Linux
/dev/sdb9       2331139  2346575    15437   7.6M 83 Linux


android5/cooker 有 env_wb.sh
裡面有 flashcard( )
看一下,好像很適合。
所以..
cd android5
. cooker/env_wb.sh
flashcard /dev/sdb
就開始燒錄 sdcard 了。
裡面有用到 sudo..

稍玩也可以開機..

就看 env_wb.sh 的 flashcard( ) 可以看到 wandboard 的開機流程。
uboot 分成了兩部份: uboot-spl 和 uboot-img
uboot-spl 燒到 sdcard 的開機位置 (1024)
uboot-spl 會到第一個 partition (boot) 把 uboot-img load 近來 run
uboot-img 會到第一個 partition (boot) 看一下 環境參數 uEnv
依照 uEnv 的內容,到第一個 partition (boot) load kernel (zImage) 和 root (uramdisk.img)
就這樣開進 kernel 了...

第一個 partition (boot) 是 vfat, 所以可以任意copy file 進去。
所以直接修改裡面的檔案就可以改開機參數。

Vysor 不能動:用 adb remount 把所有 filesystem 都改成 rw 後,就可以了。

2015/11/16

又是 tinyalsa.. 還有 audio system

/system/core/include/system/audio.h
包含所有 android system 定義的 audio 相關內容:
  • STREAM
  • CONTENT
  • USAGE
  • FLAG
  • SOURCE
  • SESSION
  • FORMAT
  • CHANNEL
  • MODE
  • DEVICE
  • OUTPUT_FLAG
  • INPUT_FLAG
經由 /dev/snd/controlC 取得系統的 audio card list
和 support 的 audio_card_list[] 比較,如果找到,就放到 adev->card_list[] 中。

set_route_by_array( ) 就是以前 alsa config 的 routing..
在 tinyalsa 改由 hard coding 來做,
當然也可以用 structure, property 來設計。

以前的 routing path 全部寫在 config_XXXX.h
-- config_wm8962.h 有各種 routing.


所以,直接把 open flag 的 MMAP 刪掉,的確可以把 write 改為 WRITEI。
雖然kernel 最後好像還是使用 mmap .. sync_ptr.. 原因未明。

2015/11/13

pcm_write

tinyalsa 的 pcm_write:
static int pcm_write_wrapper(struct pcm *pcm, const void * buffer, size_t bytes, int flags)
{
    int ret = 0;
    if(flags & PCM_MMAP)
         ret = pcm_mmap_write(pcm, (void *)buffer, bytes);
    else
         ret = pcm_write(pcm, (void *)buffer, bytes);
一般都沒有用 MMAP.
所以都是直接 call pcm_write( )

tinyalsa 實做的 pcm_write( ) 就是用for loop 把 buffer 一一寫入 ioctl:
    struct snd_xferi x;

    x.buf = (void*)data;
    x.frames = count / (pcm->config.channels *
                        pcm_format_to_bits(pcm->config.format) / 8);

    ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))

這樣就進入 kernel 了..

kernel 的 snd_pcm_playback_ioctl1 呼叫 snd_pcm_lib_write 來做:
static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
                                      unsigned int hwoff,
                                      unsigned long data, unsigned int off,
                                      snd_pcm_uframes_t frames)
{
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
        char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);

        if (substream->ops->copy) {
                if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
                        return err;
        } else {
                char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
                if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
                        return -EFAULT;
        }
        return 0;
}



錯了。結果是用 MMAP...
所以,trace 到最後,是 call kernel 的 snd_pcm_sync_ptr..

修改一下 hardware/imx/alsa/tinyalsa_hal.c, 拿掉 MMAP, 就會 call pcm_write(), 就可以換掉 pcm_write 了..
snd_pcm_playback_ioctl1        : do_vfs_ioctl+0x80/0x5bc
snd_pcm_common_ioctl1          : snd_pcm_playback_ioctl1+0x158/0x44c
snd_pcm_playback_ioctl1        : do_vfs_ioctl+0x80/0x5bc
snd_pcm_common_ioctl1          : snd_pcm_playback_ioctl1+0x158/0x44c
snd_pcm_hw_params              : snd_pcm_common_ioctl1+0x478/0xdc0
soc_pcm_hw_params              : snd_pcm_hw_params+0xc0/0x390
imx_cs42888_surround_hw_params : soc_pcm_hw_params+0x14c/0x47c
snd_soc_dai_set_tdm_slot       : imx_cs42888_surround_hw_params+0x90/0xb4
fsl_esai_set_dai_tdm_slot      : snd_soc_dai_set_tdm_slot+0x60/0x78

2015/11/12

Worklog : imx. tdm

soc/fsl/imx-cs42888.c -- imx_cs42888_surround_hw_params
        /* set i.MX active slot mask */
        snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);
soc/soc-core.c
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
所以 ..
  • slots = 2
  • slot_width=32

BCLK 是 data 的 freqx2, 這樣,在 CLK rising 時 sample Data 的資料。
data 每 32 bit 視為一個 slot.
實際上slot 內的資料,可以是 8, 16, 24 bit, 不一定要將 32bit 用完。
LRCLK 是用來區分 L, R 的資料。

2015/11/9

Wandboard

結果很小一塊,connector 也是小的,所以有點不方便。


官方的 server 好像有問題,所以沒有git server 可以使用。
目前source 是用 download tar 的方式。

ref: http://coldnew.github.io/blog/2015/wandboard_android_4.4.2/
所以是故意的?

build android from source: https://embeddedandroidsystem.wordpress.com/

$tar xvf wandboard_lp-5.0.2-ga_fullsource_20150630.tar.xz

$cd android5/
$source build/envsetup.sh
$lunch wandboard-userdebug
$make -j4
結果 fail:
install: cannot stat ‘bootable/bootloader/uboot-imx/SPL’: No such file or directory
install: cannot stat ‘bootable/bootloader/uboot-imx/SPL’: No such file or directory
make: *** [out/target/product/wandboard/SPL] Error 1
make: *** Waiting for unfinished jobs....
看來是dependency 問題。
用 single thread make 就 OK
--- 其實中途就又用 j10 來 build , 也 OK, 只要確認 uboot 已經 build 過了。

製作開機 sdcard 和 freescale bsp 的作法不同。
ref: http://android.serverbox.ch/?p=899

wandboard 的 root 是 real partition
--- freescale 是 rootfs

wandboard 把 root 和 system 放在同一個 partition
kernel uImage 另外用一個ext2 的 partition

這個好像也不是 wandboard 5.0 bsp 的作法,是該blogger 自己的作法。

2015/11/5

machine -- jobs.

jessie431
aosp, emulator - OK
make sdk --failed
should...
lunch sdk-eng
make sdk

3rd
aosp, master. new compilation tool test. - android-6.0.1 branch/tag OK
run "emulator -no-window" OK

vbjessie
gitlab installation

jr
test build sdk - px3
lack of goldfish device.
aosp -b android-4.4.4_r2 (follow px3), test build sdk in first

lunch ... all in build/target/product

lunch 之後要選擇 product type.
並不是所有都有列出來。
一般 vendor bsp product 都會在 device/ 下。...

Android 原有的會在 build/target/product 下...
隨著支援平台增加,var 也變多了...
像以往的 sdk (arm). 現在多了:
sdk_arm64, ask_mips, sdk_x86, sdk_x86_64..

2015/11/4

android WITH_DEXPREOPT=true

在BoardConfig.mk 中加入
WITH_DEXPREOPT=true
這樣,開機的 read apk , optimize then save on /data/dalvik-cache 的動作會在 compile time 就做了。
所以首次開機會快一點。
而且 /data/dalvik-cache 會是空的。

但是原來的 .jar, .apk 都會多一個 .odex 檔。

avidemux and deb-multimedia.org

不知道什麼原因,以前的 debian-mulitmedia.org 被debain 要求改成 deb-multimedia.org
debian 說,不希望他用 debian 的名子。

所以 source.list 就要改了。

增加 source.list:
deb http://www.deb-multimedia.org jessie main non-free

加入 key:
06/02/2015 :
Maybe I went too quickly to my new GPG key.
If apt-get don't find the new key, do that :

wget http://www.deb-multimedia.org/pool/main/d/deb-multimedia-keyring/deb-multimedia-keyring_2015.6.1_all.deb
sudo dpkg -i deb-multimedia-keyring_2015.6.1_all.deb
apt-get update

apt-get should be happy now.

2015/11/3

some bookmarks for memo...

接著 ref:
  • https://yaapb.wordpress.com/2012/09/22/build-a-custom-android-emulator-image/
  • https://code.google.com/p/android/issues/detail?id=61210
  • http://events.linuxfoundation.org/sites/events/files/slides/SDK%20Add-ons.pdf
  • http://stackoverflow.com/questions/9598782/deploying-sdk-addon-component
  • https://newcircle.com/s/post/1571/exploring_sdk_add_ons_for_android_devices_larry_schiefer_video
  • https://android.googlesource.com/platform/build/+/kitkat-wear/core/tasks/sdk-addon.mk
  • http://programmingtolive.blogspot.tw/2012/07/share-your-android-sdk-andon.html
  • http://stackoverflow.com/questions/9022750/running-emulator-after-building-android-from-source

banana pi , build kernel for jessie

follow : http://www.orangepi.org/orangepibbsen/forum.php?mod=viewthread&tid=43
內容:
sudo apt-get install git build-essential libncurses5-dev u-boot-tools uboot-mkimage
git clone https://github.com/silentcreek/bananapi-kernel --depth 1
cd bananapi-kernel
make sun7i_defconfig
make menuconfig                        # exit & save     
make -j2 uImage modules                # ~ 2.5h working
sudo make modules_install
sudo mount /dev/mmcblk0p1 /boot
sudo mv /boot/uImage /boot/uImage_old  # save precedent uImage, can be restored 
sudo cp arch/arm/boot/uImage /boot
sudo reboot

.. native build.. 超久...8hrs..以上..

結果....boot fail,,, 他說 id 不認識...

還是要 follow : http://www.htpcguides.com/build-debian-image-for-banana-pi-pro-sata-port-multiplier/

據說是 debian 的 kernel.

2015/11/2

aosp. emulator and make sdk.

如果照 https://yaapb.wordpress.com/2012/09/22/build-a-custom-android-emulator-image/

直接 拉 googlesource 的 master 來build. 現在是 6.0

6.0 的 build system 好像變了,不是以前的 gnu Make, 變成 Ninja..
所以 build 到 41% 後出現 Jack connection fail...
--- Jack 是 android 的新 build system (ref: http://source.android.com/source/jack.html )

5.1.1 的話,會有 clang c++ library fail,
切到 5.0.1_r2 也一樣。

後來,make clean 後再 make 就 OK 了。
所以要看看是不是 5.1.1 也一樣 clean 後 OK

用 android-6.0.0_r1 這個branch 的話,也可以 build OK (full_x86)

用 android-5.0.2_r1 來 build aosp_x86
build 完後,which 看一下 emulator 的位置, 在 prebuilts/android-emulator/linux-x86_64/emulator
直接 run emulator, 他就會用 剛剛 build 好的 aosp_x86 image 來開機。
在 emulator 的 about 中可以看到 android system 的 build 版本。
----------------------------------------------
make sdk..

一樣,follow: https://android.googlesource.com/platform/sdk/+/master/docs/howto_build_SDK.txt
  $ cd ~/my-android-git
  $ . build/envsetup.sh
  $ lunch sdk-eng
  $ make sdk
這樣build 出 linux sdk
要build windows sdk 要 follow 後面說的,改用
  $ make win_sdk

需要tofrodos 跟 mingw32
----------------------------------
imx sdk

結果 fail:
make: *** [out/target/product/generic/obj/APPS/BasicDreams_intermediates/arm/package.odex] Aborted (core dumped)

因為是 generic 這個 platform fail..
所以 lunch 用 imx 的試試看...

還是 fail...
development/build/sdk.atree:193: couldn't locate source file: userdata.img
development/build/sdk.atree:482: couldn't locate source file: system/app/EmulatorSmokeTests/EmulatorSmokeTests.apk

ref: http://www.programgo.com/article/1118474640/

解決方法,跟google 到的一樣,把 sdk.atree 中,couldn't locate source file 的 item 都 comment 掉,再 make 一次就可以了。

-----------------------------------
aosp sdk
5.0.2_r1, aosp_x86-eng, make sdk..
development/build/sdk.atree:47: couldn't locate source file: bin/sqlite3
development/build/sdk.atree:49: couldn't locate source file: bin/etc1tool
development/build/sdk.atree:86: couldn't locate source file: bin/bcc_compat
development/build/sdk.atree:167: couldn't locate source file: framework/layoutlib.jar
development/build/sdk.atree:168: couldn't locate source file: framework/icu4j.jar
development/build/sdk.atree:481: couldn't locate source file: framework/layoutlib-tests.jar
development/build/sdk.atree:482: couldn't locate source file: system/app/EmulatorSmokeTests/EmulatorSmokeTests.apk
查.除了 sqlite3以外,真的都沒有 build 出來。
layoutlib 是給 eclipe 用的。

然後 JBQ 說: https://groups.google.com/forum/#!topic/android-building/kePECtbvGlE
lunch sdk-eng
make sdk

原來是有歷史的,..make sdk 要先..

還是失敗 -- gitlab install from source

https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md
--- 這篇不夠清楚。一直 fail...最後連 GemFile 都不見了

可能要試試看這一篇..
https://www.linode.com/docs/applications/development/how-to-install-and-configure-gitlab-on-ubuntu-14-04-trusty-tahr

一樣,到 ,,.git bundle install 時出現 GemFile 找不到。

會是 arm platform 的問題?

改用 virtualbox 裝 jessie 是一次。

紀錄一下手動安裝 ruby 的 install path

ruby..
$sudo make install
...
...
installing binary commands:   /usr/local/bin
installing base libraries:    /usr/local/lib
installing arch files:        /usr/local/lib/ruby/2.1.0/armv7l-linux-eabihf
installing pkgconfig data:    /usr/local/lib/pkgconfig
installing command scripts:   /usr/local/bin
installing library scripts:   /usr/local/lib/ruby/2.1.0
installing common headers:    /usr/local/include/ruby-2.1.0
installing manpages:          /usr/local/share/man/man1
installing extension objects: /usr/local/lib/ruby/2.1.0/armv7l-linux-eabihf
installing extension objects: /usr/local/lib/ruby/site_ruby/2.1.0/armv7l-linux-eabihf
installing extension objects: /usr/local/lib/ruby/vendor_ruby/2.1.0/armv7l-linux-eabihf
installing extension headers: /usr/local/include/ruby-2.1.0/armv7l-linux-eabihf
installing extension scripts: /usr/local/lib/ruby/2.1.0
installing extension scripts: /usr/local/lib/ruby/site_ruby/2.1.0
installing extension scripts: /usr/local/lib/ruby/vendor_ruby/2.1.0
installing extension headers: /usr/local/include/ruby-2.1.0/ruby
installing default gems:      /usr/local/lib/ruby/gems/2.1.0 (build_info, cache, doc, extensions, gems, specifications)
                              bigdecimal 1.2.4
                              io-console 0.4.3
                              json 1.8.1
                              minitest 4.7.5
                              psych 2.0.5
                              rake 10.1.0
                              rdoc 4.1.0
                              test-unit 2.1.7.0

流水帳

可能有兩件事可以做:
  • 繼續install gitlib (on arm platform)
  • test build ldd3 example
  • test build sdk with my own new framework api & use my sdk on android studio
  • build image for emulator
都是在 banana pi 上。

2015/10/28

instal ruby 2.2 on raspberry pi

pi@raspberrypi:~$ curl -L https://get.rvm.io > rvm.sh
pi@raspberrypi:~$ ./rvm.sh  stable --ruby                                                                         
Downloading https://github.com/rvm/rvm/archive/1.26.11.tar.gz                                                     
Downloading https://github.com/rvm/rvm/releases/download/1.26.11/1.26.11.tar.gz.asc
gpg: Signature made Mon 30 Mar 2015 21:52:13 UTC using RSA key ID BF04FF17
gpg: Can't check signature: public key not found     
Warning, RVM 1.26.0 introduces signed releases and automated check of signatures when GPG software found.
Assuming you trust Michal Papis import the mpapis public key (downloading the signatures).
                                                                    
GPG signature verification failed for '/home/pi/.rvm/archives/rvm-1.26.11.tgz' - 'https://github.com/rvm/rvm/relea
ses/download/1.26.11/1.26.11.tar.gz.asc'! 
try downloading the signatures:            
                                     
    gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3  
                                      
or if it fails:                
                                                       
    command curl -sSL https://rvm.io/mpapis.asc | gpg --import -    
                                     
the key can be compared with:          
                                 
    https://rvm.io/mpapis.asc                                     
    https://keybase.io/mpapis  
只好分兩步,先
curl -sSL https://rvm.io/mpapis.asc > mpapis.asc
gpg --import mpapis.asc
重run rvm.sh .. 繼續..

Hi 新的開始

舊的用了一陣子。都不想更新了。
來換個新的 -- 高海拔烏龍茶

加油!