2017/8/31

linux distro in wandboard

這一篇 https://eewiki.net/display/linuxonarm/Wandboard 很有趣呀。
用以前的方是,手動,...build kernel, prepare root, dd ..

然後這一篇https://github.com/Nuand/bladeRF/wiki/Creating-Linux-based-Embedded-System-Images-with-Yocto 是用yocto 手動寫 bblayer 和 拉 meta-receipt build 出 system。

大概就是..
checkout poky (yotco)
checkout yocto sdr (what's this?)
checkout oe
checkout meta-fsl-arm
checkout meta-fsl-arm-extra ( git clone -b jethro git://github.com/Freescale/meta-fsl-arm-extra.git )
然後用 openembedded 的環境設定 script 產生一個基本的 configuration folder 外型
source poky-jethro-2.0/oe-init-build-env buildfolder
然後就會有 conf 出現在 buildfolder 下..

這個只雛型,要修改他成為你要的設定..
修改 conf/local.conf
  • 指定 MACHINE
  • 指定 download 到...
  • 因為有 meta-fsl-arm, 所以要加一行 ACCEPT_FSL_EULA 到最後
然後修改 bblayer, 裡面是你要的東西...
一些 linux system 基本的,都在 meta-openembedded 裡面了。
只要把你要的寫進 BBLAYERS ..

然後就可以 bitbake core-image-minimal
一樣,image 在 ..../deploy/images/wandboard/,用 gzip 解開
gzip -d --force core-image-minimal-wandboard.sdcard.gz
dd 到 sdcard。
wandboard 一樣,uart , null-modem + gender-changer
boot OK, login-name : root, no password

2017/8/30

最後參考...http://git.freescale.com/git/cgit.cgi/imx/meta-nxp-agl.git/tree/README.txt?h=krogoth :
This builds the Wayland-Weston AGL image with the basic AGL interface. 
Demos can then be run on top of this.

This image has only been run on i.MX 6QP Sabre and Sabre Auto.
It is not supported nor tested.  It is simply a demo showing that the basic image runs.
It runs on the 4.1.15-1.0.0 Freescale release of Linux.

Build instructions:
To get the BSP you need to have `repo` installed.

Install the `repo` utility (only need to do once per user):
--------------------------------------------------

$: mkdir ~/bin
$: curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$: chmod a+x ~/bin/repo
$: PATH=${PATH}:~/bin

Download the BSP Yocto Project Environment into your directory:
-------------------------------------------

$: mkdir fsl-arm-yocto-bsp
$: cd fsl-arm-yocto-bsp
$: repo init -u git://git.freescale.com/imx/fsl-arm-yocto-bsp.git -b imx-4.1-krogoth -m imx-4.1.15-2.0.0-agl-demo.xml

$: repo sync

Setup and Build for Wayland (currently, only one supported)
-------------------------------------------
$: DISTRO=nxp-imx-agl-wayland MACHINE=imx6qpsabreauto source nxp-setup-agl.sh -b bld-agl

IMAGES
-------------------------------------------
Most interesting results currently seen with:
$: bitbake agl-demo-platform

Other images:
$: bitbake agl-image-minimal
$: bitbake agl-image-ivi
$: bitbake agl-image-weston

The "navi" demo is also included.  To run it, follow the instructions in the README.md in sources/gpsnavi-agl.

The CES2016 demo is in this image.  To run it, you need to connect an HDMI monitor in the "portrait" orientation.
The dimensions in the demos are hard coded.  The files used are in /opt/AGL/CES2016 and /etc/xdg/weston.  
然後machine 改 wandboard 再 build, failed...
WARNING: wayland-ivi-extension-1.9.1-r0 do_fetch: Failed to fetch URL file://wandboard_fix_build.patch, attempting MIRRORS if available
ERROR: wayland-ivi-extension-1.9.1-r0 do_fetch: Fetcher failure: Unable to find file file://wandboard_fix_build.patch anywhere. 
...
...
ERROR: wayland-ivi-extension-1.9.1-r0 do_fetch: Function failed: Fetcher failure for URL: 'file://wandboard_fix_build.patch'. Unable to fetch URL from any source.
ERROR: Logfile of failure stored in: /home/charles-chang/fsl-arm-yocto-bsp/bld-agl-wandboard/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/wayland-ivi-extension/1.9.1-r0/temp/log.do_fetch.1143
ERROR: Task 3832 (/home/charles-chang/fsl-arm-yocto-bsp/sources/meta-nxp-agl/recipes-graphics/wayland/wayland-ivi-extension_1.9.1.bb, do_fetch) failed with exit code '1'

yocto - wandboard , FSL_EULA

延續上一篇。ACCEPT_FSL_EULA 的設定。
參考 meta-agl/templates/machine/imx6qsabrelite/50_setup.sh:
find_and_ack_eula $METADIR/meta-fsl-arm EULA 
export EULA_FLAG_NAME="ACCEPT_FSL_EULA"
對照 imx6sabrelite 跟 wandboard,缺 50_setup.sh
所以 copy 過去..

結果一樣...

cache image size

很奇怪,明明改了 cache image size,不知謂何又被改回去。
所以,,
在 build 下 grep cacheimage..找到
core/Makefile:.PHONY: cacheimage-nodeps
所以 make cacheimage-nodeps
make_ext4fs -s -T -1 -S out/target/product/msm8953_64/root/file_contexts -L cache -l 268435456 -a cache out/target/product/msm8953_64/cache.img out/target/product/msm8953_64/cache out/target/product/msm8953_64/system
果然...

所以找一下,這個值是 device/,.../BoardConfig.mk:
BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456

所以修改一下,..
BOARD_CACHEIMAGE_PARTITION_SIZE := 1317011456
再 run 一次make 測試。OK

2017/8/29

AGL on wandboard

這一篇 Download Source 有說明...
repo init -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo
repo sync
然後選平台:
source meta-agl/scripts/aglsetup.sh -h
------------ aglsetup.sh: Starting
Usage: . aglsetup.sh [options] [feature [feature [... ]]]

Version: 1.1.0
Compatibility: bash, zsh, ksh

Options:
   -m|--machine 
      what machine to use
      default: 'qemux86-64'
   -b|--build 
      build directory to use
      default: './build'
   -s|--script 
      file where setup script is generated
      default: none (no script)
   -f|--force
      flag to force overwriting any existing configuration
      default: false
   -v|--verbose
      verbose mode
      default: false
   -d|--debug
      debug mode
      default: false
   -h|--help
      get some help

Available machines:
   [meta-agl]
       beaglebone
       cyclone5
       dra7xx-evm
       dragonboard-410c
       h3ulcb
       imx6qsabreauto
       imx6qsabrelite
       intel-corei7-64
       joule
       m3ulcb
       m3ulcb-nogfx
       nitrogen6x
       porter
       porter-nogfx
       qemux86
     * qemux86-64
       raspberrypi2
       raspberrypi3
       raspberrypi3-64
       wandboard

Available features:
   [meta-agl]
       agl-all-features :( agl-demo  agl-appfw-smack  agl-devel  agl-netboot  agl-sota  agl-sdl )
       agl-appfw-smack
       agl-archiver
       agl-ci
       agl-ci-change-features :( agl-demo  agl-appfw-smack  agl-devel  agl-devel  agl-netboot  agl-appfw-smack  agl-sdl )
       agl-ci-change-features-nogfx :( agl-devel  agl-netboot  agl-appfw-smack )
       agl-ci-snapshot-features :( agl-demo  agl-appfw-smack  agl-devel  agl-devel  agl-netboot  agl-appfw-smack  agl-isafw  agl-archiver  agl-sdl )
       agl-ci-snapshot-features-nogfx :( agl-devel  agl-netboot  agl-appfw-smack  agl-isafw  agl-archiver )
       agl-devel
       agl-isafw
       agl-netboot
       agl-sota
   [meta-agl-demo]
       agl-demo :( agl-appfw-smack  agl-devel )
       agl-iotivity
       agl-sdl
   [meta-agl-devel]
       agl-egvirt
       agl-oem-extra-libs
       agl-renesas-kernel
   [meta-agl-extra]
       agl-localdev
要 build wandboard...
所以..參考 build for raspberry pi 的部份..
$source meta-agl/scripts/aglsetup.sh -m wandboard agl-demo agl-netboot agl-appfw-smack
------------ aglsetup.sh: Starting
Generating configuration files:
   Build dir: /home/charles-chang/AGL/build
   Machine: wandboard
   Features: agl-appfw-smack agl-demo agl-devel agl-netboot 
   Running /home/charles-chang/AGL/poky/oe-init-build-env
   Templates dir: /home/charles-chang/AGL/meta-agl/templates/base
   Config: /home/charles-chang/AGL/build/conf/bblayers.conf
   Config: /home/charles-chang/AGL/build/conf/local.conf
   Setup script: /home/charles-chang/AGL/build/conf/setup.sh
   Executing setup script ... --- beginning of setup script
--- fragment /home/charles-chang/AGL/meta-agl/templates/base/01_setup_EULAfunc.sh
--- fragment /home/charles-chang/AGL/meta-agl/templates/base/99_setup_EULAconf.sh
--- end of setup script
OK
Generating setup file: /home/charles-chang/AGL/build/agl-init-build-env ... OK
------------ aglsetup.sh: Done

### Shell environment set up for builds. ###

You can now run 'bitbake '

Common targets are:
  - meta-agl:          (core system)
    agl-image-minimal
    agl-image-minimal-qa
    
    agl-image-ivi
    agl-image-ivi-qa
    agl-image-ivi-crosssdk
    
    agl-image-weston

  - meta-agl-demo:     (demo with UI)
    agl-demo-platform  (* default demo target)
    agl-demo-platform-qa
    agl-demo-platform-crosssdk
    
    agl-demo-platform-html5

然後 build..
$bitbake agl-demo-platform
然後就出現 error:
ERROR: Layer directory '/home/charles-chang/AGL/meta-fsl-arm' does not exist! Please check BBLAYERS in /home/charles-chang/AGL/build/conf/bblayers.conf
... 難怪 imx 的都沒 prebuild 了...

然後倒退...chinook 3.0.2 版,不會出現這個 error
3.0.1/0 都會出現 meta-rcar sha error

build fail
ERROR: imx-gpu-viv-1_5.0.11.p8.4-hfp-r0 do_unpack: To use 'imx-gpu-viv' you need to accept the Freescale EULA at '/home/charles-chang/AGL/meta-fsl-arm/EULA'. Please read it and in case you accept it, write: ACCEPT_FSL_EULA = "1" in your local.conf.
ERROR: imx-gpu-viv-1_5.0.11.p8.4-hfp-r0 do_unpack: Function failed: do_unpack
ERROR: Logfile of failure stored in: /home/charles-chang/AGL/build/tmp/work/cortexa9hf-neon-mx6qdl-agl-linux-gnueabi/imx-gpu-viv/1_5.0.11.p8.4-hfp-r0/temp/log.do_unpack.8709
ERROR: Task 2321 (/home/charles-chang/AGL/meta-fsl-arm/recipes-graphics/imx-gpu-viv/imx-gpu-viv_5.0.11.p8.4-hfp.bb, do_unpack) failed with exit code '1'
所以遵照說明,在 build/conf/local.confg 最後加上:
ACCEPT_FSL_EULA = "1"
test build
build$ bitbake -b /home/charles-chang/AGL/meta-fsl-arm/recipes-graphics/imx-gpu-viv/imx-gpu-viv_5.0.11.p8.4-hfp.bb 
重 build 一次,出現 Error:
ERROR: aim-network-0.1-r0 do_compile: oe_runmake failed
ERROR: aim-network-0.1-r0 do_compile: Function failed: do_compile (log file is located at /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/temp/log.do_compile.3681)
ERROR: aim-sound-0.1-r0 do_compile: oe_runmake failed
ERROR: aim-sound-0.1-r0 do_compile: Function failed: do_compile (log file is located at /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/temp/log.do_compile.3589)
ERROR: Logfile of failure stored in: /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/temp/log.do_compile.3681
Log data follows:
| DEBUG: Executing shell function do_compile
| NOTE: make -j 8 KERNEL_SRC=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source KERNEL_PATH=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source KERNEL_VERSION=3.14.28_1.0.0_ga-wandboard+ge2df042 CC=arm-agl-linux-gnueabi-gcc  -mno-thumb-interwork -marm -fuse-ld=bfd LD=arm-agl-linux-gnueabi-ld.bfd   AR=arm-agl-linux-gnueabi-ar  O=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-build-artifacts
| make -C /home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source M=/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network modules
| make[1]: Entering directory `/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source'
|   CC [M]  /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.o
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c: In function 'aim_probe_channel':
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c:366:23: error: macro "alloc_netdev" passed 4 arguments, but takes just 3
|           most_nd_setup);
|                        ^
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c:365:4: error: 'alloc_netdev' undeclared (first use in this function)
|     alloc_netdev(0, "meth%d", NET_NAME_UNKNOWN,
|     ^
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c:365:4: note: each undeclared identifier is reported only once for each function it appears in
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c: At top level:
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.c:293:13: warning: 'most_nd_setup' defined but not used [-Wunused-function]
|  static void most_nd_setup(struct net_device *dev)
|              ^
| make[3]: *** [/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network/networking.o] Error 1
| make[2]: *** [_module_/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/git/driver/aim-network] Error 2
| make[1]: *** [sub-make] Error 2
| make[1]: Leaving directory `/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source'
| make: *** [all] Error 2
| WARNING: exit code 1 from a shell command.
| ERROR: oe_runmake failed
| ERROR: Function failed: do_compile (log file is located at /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-network/0.1-r0/temp/log.do_compile.3681)
ERROR: Task 632 (/home/charles-chang/AGL/meta-agl-demo/recipes-kernel/aim-network/aim-network.bb, do_compile) failed with exit code '1'
ERROR: Logfile of failure stored in: /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/temp/log.do_compile.3589
Log data follows:
| DEBUG: Executing shell function do_compile
| NOTE: make -j 8 KERNEL_SRC=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source KERNEL_PATH=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source KERNEL_VERSION=3.14.28_1.0.0_ga-wandboard+ge2df042 CC=arm-agl-linux-gnueabi-gcc  -mno-thumb-interwork -marm -fuse-ld=bfd LD=arm-agl-linux-gnueabi-ld.bfd   AR=arm-agl-linux-gnueabi-ar  O=/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-build-artifacts
| make -C /home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source M=/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound modules
| make[1]: Entering directory `/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source'
|   CC [M]  /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound/sound.o
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound/sound.c: In function 'audio_probe_channel':
| /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound/sound.c:598:8: error: implicit declaration of function 'snd_card_new' [-Werror=implicit-function-declaration]
|   ret = snd_card_new(NULL, -1, card_name, THIS_MODULE,
|         ^
| cc1: some warnings being treated as errors
| make[3]: *** [/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound/sound.o] Error 1
| make[2]: *** [_module_/home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/git/driver/aim-sound] Error 2
| make[1]: *** [sub-make] Error 2
| make[1]: Leaving directory `/home/charles-chang/AGL/build/tmp/work-shared/wandboard/kernel-source'
| make: *** [all] Error 2
| ERROR: oe_runmake failed
| ERROR: Function failed: do_compile (log file is located at /home/charles-chang/AGL/build/tmp/work/wandboard-agl-linux-gnueabi/aim-sound/0.1-r0/temp/log.do_compile.3589)
ERROR: Task 646 (/home/charles-chang/AGL/meta-agl-demo/recipes-kernel/aim-sound/aim-sound.bb, do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 3603 tasks of which 827 didn't need to be rerun and 2 failed.
Waiting for 0 running tasks to finish:

Summary: 2 tasks failed:
  /home/charles-chang/AGL/meta-agl-demo/recipes-kernel/aim-network/aim-network.bb, do_compile
  /home/charles-chang/AGL/meta-agl-demo/recipes-kernel/aim-sound/aim-sound.bb, do_compile
Summary: There were 7 WARNING messages shown.
Summary: There were 4 ERROR messages shown, returning a non-zero exit code.
試試看 3.0.5 --- 之後的 tag 都沒有 meta-fsl 了...

變成;
ERROR: imx-gpu-viv-1_5.0.11.p8.4-hfp-r0 do_configure: QA Issue: imx-gpu-viv: LIC_FILES_CHKSUM points to an invalid file: /home/charles-chang/AGL/build/tmp/work/cortexa9hf-neon-mx6qdl-agl-linux-gnueabi/imx-gpu-viv/1_5.0.11.p8.4-hfp-r0/imx-gpu-viv-5.0.11.p8.4-hfp/gpu-core/usr/include/gc_vdk.h [license-checksum]
ERROR: imx-gpu-viv-1_5.0.11.p8.4-hfp-r0 do_configure: Fatal QA errors found, failing task.
ERROR: imx-gpu-viv-1_5.0.11.p8.4-hfp-r0 do_configure: Function failed: do_qa_configure
ERROR: Logfile of failure stored in: /home/charles-chang/AGL/build/tmp/work/cortexa9hf-neon-mx6qdl-agl-linux-gnueabi/imx-gpu-viv/1_5.0.11.p8.4-hfp-r0/temp/log.do_configure.4436
ERROR: Task 2317 (/home/charles-chang/AGL/meta-fsl-arm/recipes-graphics/imx-gpu-viv/imx-gpu-viv_5.0.11.p8.4-hfp.bb, do_configure) failed with exit code '1'
NOTE: Tasks Summary: Attempted 3431 tasks of which 1284 didn't need to be rerun and 1 failed.
Waiting for 0 running tasks to finish:

Summary: 1 task failed:
  /home/charles-chang/AGL/meta-fsl-arm/recipes-graphics/imx-gpu-viv/imx-gpu-viv_5.0.11.p8.4-hfp.bb, do_configure
Summary: There was 1 WARNING message shown.
Summary: There were 3 ERROR messages shown, returning a non-zero exit code.
找一下,是..meta-fsl-arm/recipes-graphics/imx-gpu-viv/imx-gpu-viv.inc..
LIC_FILES_CHKSUM = "file://gpu-core/usr/include/gc_vdk.h;beginline=5;endline=11;md5=12c028cbbbedb4b8770267131500592c"
ref:http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#usingpoky-configuring-LIC_FILES_CHKSUM

2017/8/24

AIDL

AIDL 宣告了 service 提供的 function。
所以:
  • service 要實做這些 function
  • client 可以要求 service 執行這些 function

aidl 這額 compiler,就是把 *.aidl 轉成 *.java
一個 java 檔,完成以上兩件事,讓..
  • service focuse 在實做 function
  • client 簡單呼叫這些 functrion
而 client 呼叫 function 時,把對應 argument 包裝起來,呼叫 Binder,交給 service 處理,
然後service處理完,把 result 包裝起來,傳回 binder,
clien5 再把 result 解開,交給 caller

這些動作,都坐在 *.aidl 轉成的 *.java 裡。

所以 *.aidl 轉成的 *.java,包含了給 client 和 service 兩人用的 code
-- 當然,兩人各用各的 function,只是寫在同一個 *.java 裡。

aidl 做出來的 *.java,最外層是直接翻譯 *.aidl 內容,class。
裡面是 static abstract class : Stub
這個 Stub 是上面寫的做雜事的主體,
雖然是同時給 service 和 client 用。但是大部分是給 service 用的。
給 client 用的只有一個 static class : Proxy

然後提供一個生成函式給 client 用: asInterface( )
他的內容就是把 Proxy new 出來。

至於service,就直接拿 Stub class 來用,實做 aidl 宣告的 interface function 就可以。


這一篇StackOverflow 的回答...
'Stub' is a class that implements the remote interface in a way that you can use it as if it were a local one. 
It handles data marashalling/unmarshalling and sending/receiving to/from the remote service. 
The term 'stub' is generally used to describe this functionality in other RPC methods (COM, Java remoting, etc.), 
but it can mean slightly different things.

所以programmer 建

2017/8/21

https://gitea.io/zh-TW/

來試試這個好了,開個container run 一下,最好還能順便碰一下 golang

2017/8/18

BaseNetworkObsever 定義要 Monitor Interface的狀態時的 動作:
StateChange
Add
Remove
叫 Network Manager 在出現 interface .. StateChange, Add, Remove 時分別 call 這三個 function.
所以..
我們寫下我們自己 implement 的 class
    private class InterfaceObserver extends BaseNetworkObserver {
        @Override
        public void interfaceLinkStateChanged(String iface, boolean up) {
            updateInterfaceState(iface, up);
        }

        @Override
        public void interfaceAdded(String iface) {
            maybeTrackInterface(iface);
        }

        @Override
        public void interfaceRemoved(String iface) {
            stopTrackingInterface(iface);
        }
    }
然後在系統啟動的時候,向 Network Management Service 註冊:
        // Start tracking interface change events.
        mInterfaceObserver = new InterfaceObserver();
        try {
            mNMService.registerObserver(mInterfaceObserver);
        } catch (RemoteException e) {
            Log.e(TAG, "Could not register InterfaceObserver " + e);
        }

ethernet interface config -- android

在 frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactoty.java:
/**
 * Manages connectivity for an Ethernet interface.
 *
 * Ethernet Interfaces may be present at boot time or appear after boot (e.g.,
 * for Ethernet adapters connected over USB). This class currently supports
 * only one interface. When an interface appears on the system (or is present
 * at boot time) this class will start tracking it and bring it up, and will
 * attempt to connect when requested. Any other interfaces that subsequently
 * appear will be ignored until the tracked interface disappears. Only
 * interfaces whose names match the config_ethernet_iface_regex
 * regular expression are tracked.
 *
 * This class reports a static network score of 70 when it is tracking an
 * interface and that interface's link is up, and a score of 0 otherwise.
 *
 * @hide
 */
參考的地方是...
        mIfaceMatch = context.getResources().getString(
                com.android.internal.R.string.config_ethernet_iface_regex);
 
         ...
    private boolean maybeTrackInterface(String iface) {
        // If we don't already have an interface, and if this interface matches
        // our regex, start tracking it.
        if (!iface.matches(mIfaceMatch) || isTrackingInterface())
            return false;

        Log.d(TAG, "Started tracking interface " + iface);
        setInterfaceUp(iface);
        return true;
    }

2017/8/16

frameworks/base/core/java/android/net
ConnectivityManager.java:
裡面有定義各類連線類型: TYPE_WIFI, TYPE_MOBILE_MMS, TYPE_BLUETOOTH, TYPE_DUMMY, TYPE_ETHERNET, TYPE_PROXY,

跟 "目前網路狀態" 有關的,好像是...
    /**
     * Returns details about the currently active default data network. When
     * connected, this network is the default route for outgoing connections.
     * You should always check {@link NetworkInfo#isConnected()} before initiating
     * network traffic. This may return {@code null} when there is no default
     * network.
     * 

This method requires the caller to hold the permission * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. * * @return a {@link NetworkInfo} object for the current default network * or {@code null} if no default network is currently active */ public NetworkInfo getActiveNetworkInfo() { try { return mService.getActiveNetworkInfo(); } catch (RemoteException e) { return null; } } /** * Returns a {@link Network} object corresponding to the currently active * default data network. In the event that the current active default data * network disconnects, the returned {@code Network} object will no longer * be usable. This will return {@code null} when there is no default * network. *

This method requires the caller to hold the permission * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. * * @return a {@link Network} object for the current default network or * {@code null} if no default network is currently active */ public Network getActiveNetwork() { try { return mService.getActiveNetwork(); } catch (RemoteException e) { return null; } }

還有一個,好像是要使用網路之前,要call 的...

另外在 frameworks/opt/net 下也有.. ethernet, ims, voip, wifi 四個 categories..

2017/8/10

filesytem 的 uid/gid : AID_XXXX 定義在 system/core/include/private/android_filesystem_config.h
/* This is the master Users and Groups config for the platform.
 * DO NOT EVER RENUMBER
 */

#define AID_ROOT             0  /* traditional unix root user */

#define AID_SYSTEM        1000  /* system server */

#define AID_RADIO         1001  /* telephony subsystem, RIL */
#define AID_BLUETOOTH     1002  /* bluetooth subsystem */
#define AID_GRAPHICS      1003  /* graphics devices */
#define AID_INPUT         1004  /* input devices */
#define AID_AUDIO         1005  /* audio devices */
#define AID_CAMERA        1006  /* camera devices */
#define AID_LOG           1007  /* log devices */
#define AID_COMPASS       1008  /* compass device */
#
...
...
#define AID_EVERYBODY     9997  /* shared between all apps in the same profile */
#define AID_MISC          9998  /* access to misc storage */
#define AID_NOBODY        9999

#define AID_APP          10000  /* first app user */


2017/8/9

android 為了 sdcard/usbdisk 使用 Fuse filesystem,寫了一個 tool : sdcard
/system/core/sdcard

其中 option 的部份:
    while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) {
        switch (opt) {
            case 'u':
                uid = strtoul(optarg, NULL, 10);
                break;
            case 'g':
                gid = strtoul(optarg, NULL, 10);
                break;
            case 'U':
                userid = strtoul(optarg, NULL, 10);
                break;
            case 'm':
                multi_user = true;
                break;
            case 'w':
                full_write = true;
                break;
            case '?':
            default:
                return usage();
        }
    }
其中 multi-user 的意思:
    if (multi_user) {
        /* Multi-user storage is fully isolated per user, so "other"
         * permissions are completely masked off. */
        if (fuse_setup(&fuse_default, AID_SDCARD_RW, 0006)
                || fuse_setup(&fuse_read, AID_EVERYBODY, 0027)
                || fuse_setup(&fuse_write, AID_EVERYBODY, full_write ? 0007 : 0027)) {
            ERROR("failed to fuse_setup\n");
            exit(1);
        }
    } else {
        /* Physical storage is readable by all users on device, but
         * the Android directories are masked off to a single user
         * deep inside attr_from_stat(). */
        if (fuse_setup(&fuse_default, AID_SDCARD_RW, 0006)
                || fuse_setup(&fuse_read, AID_EVERYBODY, full_write ? 0027 : 0022)
                || fuse_setup(&fuse_write, AID_EVERYBODY, full_write ? 0007 : 0022)) {
            ERROR("failed to fuse_setup\n");
            exit(1);
        }
    }

2017/8/3

OpenGapp

好有趣,竟然還有這個:OpenGAPP
就是把 google 的 gapp 包裝成 update file

download zip, 解開後...
update-binary 實際上是一個 shellscript。但是最終還是 call install.sh

有關 core app 部份:
for gapp_name in $core_gapps_list; do
  get_apparchives "Core/$gapp_name"
  for archive in $apparchives; do
    case $gapp_name in
      setupwizarddefault) if [ "$device_type" != "tablet" ]; then extract_app "$archive"; fi;;
      setupwizardtablet)  if [ "$device_type"  = "tablet" ]; then extract_app "$archive"; fi;;
      *)  extract_app "$archive";;
    esac
  done
done;
ui_print " ";
也就是 extract_app:
extract_app() {
  tarpath="$TMP/$1.tar" # NB no suffix specified here
  if "$TMP/unzip-$BINARCH" -o "$OPENGAZIP" "$1.tar*" -d "$TMP"; then # wildcard for suffix
    app_name="$(basename "$1")"
    which_dpi "$app_name"
    echo "Found $1 DPI path: $dpiapkpath"
    folder_extract "$tarpath" "$dpiapkpath" "$app_name/common"
  else
    echo "Failed to extract $1.tar* from $OPENGAZIP"
  fi
}
就是 folder_extract:
  elif [ -e "$archive.lz" ]; then
    for f in "$@"; do
      if [ "$f" != "unknown" ]; then
        "$TMP/tar-$BINARCH" -xf "$archive.lz" -C "$TMP" "$f" && install_extracted "$f"
      fi
    done
    rm -f "$archive.lz"
解開m,然後 install_extracted:
install_extracted() {
  file_list="$(find "$TMP/$1/" -mindepth 1 -type f | cut -d/ -f5-)"
  dir_list="$(find "$TMP/$1/" -mindepth 1 -type d | cut -d/ -f5-)"
  for file in $file_list; do
      install -D "$TMP/$1/${file}" "$SYSTEM/${file}"
      ch_con "$SYSTEM/${file}"
      set_perm 0 0 644 "$SYSTEM/${file}";
  done
  for dir in $dir_list; do
    ch_con "$SYSTEM/${dir}"
    set_perm 0 0 755 "$SYSTEM/${dir}";
  done
  case $preodex in
    true*)
      installedapkpaths="$(find "$TMP/$1/" -name "*.apk" -type f | cut -d/ -f5-)"
      for installedapkpath in $installedapkpaths; do  # TODO fix spaces-handling
        if ! checkmanifest "$SYSTEM/$installedapkpath" "classes.dex"; then
          ui_print "- pre-ODEX-ing $gapp_name";
          log "pre-ODEX-ing" "$gapp_name";
          odexapk "$SYSTEM/$installedapkpath"
        fi
      done
    ;;
  esac
  bkup_list=$'\n'"${file_list}${bkup_list}"
  rm -rf "$TMP/$1"
}

install 是 busybox 提供的...
ch_con 是 chcon:
ch_con() {
  chcon -h u:object_r:system_file:s0 "$1";
}
所以間單來說,只要 gms 的話,要裝 gms 跟 gsf . 然後 permission 也要。
所以就是解開:之後,把 priv-app push 到 /system/priv-app, 把 permission push 到 /system/etc/permissions , 把 sysconfig push 到 /system/etc/sysconfig 之後,重開機就可以。
我解開(install) 的有:
  • Core/defaultetc-comm : permissions and sysconfig
  • Core/gmscore-arm64 : PrebuiltGmsCore
  • Core/gsf-all : GoogleServiceFramework
  • Core/gsflogin-all : GoogleLoginService
-- permission 好像還是沒過,所以還是有改 framework 的 PackageManagerService, 把 Permission 都改 GRANT

2017/8/1

Error Message 出自於:
    private void enforce(
            String permission, int resultOfCheck,
            boolean selfToo, int uid, String message) {
        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(
                    (message != null ? (message + ": ") : "") +
                    (selfToo
                     ? "Neither user " + uid + " nor current process has "
                     : "uid " + uid + " does not have ") +
                    permission +
                    ".");
        }
    }
Fail 檢查是: 第二個argument : int resultOfCheck
從 caller 看:
    public void enforceCallingOrSelfPermission(
            String permission, String message) {
        enforce(permission,
                checkCallingOrSelfPermission(permission),
                true,
                Binder.getCallingUid(),
                message);
    }

第二個argument 是 checkCallingOrSelfPermission()
他call的是:
    public int checkCallingOrSelfPermission(String permission) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }

        return checkPermission(permission, Binder.getCallingPid(),
                Binder.getCallingUid());
    }

所以就是 checkPermission( )
    public int checkPermission(String permission, int pid, int uid) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }

        try {
            return ActivityManagerNative.getDefault().checkPermission(
                    permission, pid, uid);
        } catch (RemoteException e) {
            return PackageManager.PERMISSION_DENIED;
        }
    }

跑到 : services/core/java/com/android/server/am/ActivityManagerService.java:
    public int checkPermission(String permission, int pid, int uid) {
        if (permission == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        return checkComponentPermission(permission, pid, uid, -1, true);
    }

   ...
   ...
   ...
    int checkComponentPermission(String permission, int pid, int uid,
            int owningUid, boolean exported) {
        if (pid == MY_PID) {
            return PackageManager.PERMISSION_GRANTED;
        }
        return ActivityManager.checkComponentPermission(permission, uid,
                owningUid, exported);
    }

在:core/java/android/app/ActivityManager.java
    public static int checkComponentPermission(String permission, int uid,
            int owningUid, boolean exported) {
        // Root, system server get to do everything.
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // Isolated processes don't get any permissions.
        if (UserHandle.isIsolated(uid)) {
            return PackageManager.PERMISSION_DENIED;
        }
        // If there is a uid that owns whatever is being accessed, it has
        // blanket access to it regardless of the permissions it requires.
        if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // If the target is not exported, then nobody else can get to it.
        if (!exported) {
            /*
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
                    here);
            */
            return PackageManager.PERMISSION_DENIED;
        }
        if (permission == null) {
            return PackageManager.PERMISSION_GRANTED;
        }
        try {
            return AppGlobals.getPackageManager()
                    .checkUidPermission(permission, uid);
        } catch (RemoteException e) {
            // Should never happen, but if it does... deny!
            Slog.e(TAG, "PackageManager is dead?!?", e);
        }
        return PackageManager.PERMISSION_DENIED;
    }
最後,就是 getPackageManager().checkUidPermission( ) 了..
base/services/core/java/com/android/server/pm/PackageManagerService.java:
    public int checkUidPermission(String permName, int uid) {
        final int userId = UserHandle.getUserId(uid);

        if (!sUserManager.exists(userId)) {
            return PackageManager.PERMISSION_DENIED;
        }

        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
            if (obj != null) {
                final SettingBase ps = (SettingBase) obj;
                final PermissionsState permissionsState = ps.getPermissionsState();
                if (permissionsState.hasPermission(permName, userId)) {
                    return PackageManager.PERMISSION_GRANTED;
                }
                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
                    return PackageManager.PERMISSION_GRANTED;
                }
            } else {
                ArraySet perms = mSystemPermissions.get(uid);
                if (perms != null) {
                    if (perms.contains(permName)) {
                        return PackageManager.PERMISSION_GRANTED;
                    }
                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
                        return PackageManager.PERMISSION_GRANTED;
                    }
                }
            }
        }

        return PackageManager.PERMISSION_DENIED;
    }



final SparseArray<ArraySet<String>> mSystemPermission = systemConfig.getSystemPermissions();
framework/base/services/core/java/com/android/server/SystemConfig.java:
readPermissionsFromXml
整個 read system config/permission file 的 code:
    SystemConfig() {
        // Read configuration from system
        readPermissions(Environment.buildPath(
                Environment.getRootDirectory(), "etc", "sysconfig"), false);
        // Read configuration from the old permissions dir
        readPermissions(Environment.buildPath(
                Environment.getRootDirectory(), "etc", "permissions"), false);
        // Only read features from OEM config
        readPermissions(Environment.buildPath(
                Environment.getOemDirectory(), "etc", "sysconfig"), true);
        readPermissions(Environment.buildPath(
                Environment.getOemDirectory(), "etc", "permissions"), true);
        // Remove android extension pack for opengles version 3.0
        int value = SystemProperties.getInt("ro.opengles.version", 0);
        if (value > 0 && (value == 196608)) {
           if (mAvailableFeatures.remove("android.hardware.opengles.aep") != null) {
               Slog.d(TAG, "Removed android.hardware.opengles.aep feature for opengles 3.0");
           }
        }
    }