2017年12月21日 星期四

[工作] Android pm取的package name跟path的用法

取得系統中所有的package:
pm list packages

取得package的path
pm path PACKAGE_NAME

ex:
$ pm path com.android.example
$ /system/app/Example/Example.apk

取得所有package with path
pm list packages -f

2017年12月13日 星期三

[工作] Access PMIC from fastboot command (UEFI)

之前有個需求是希望能透過fastboot command來讓device進shipmode.

找了一下之後發現xbl裡面已經有提供進shipmode的function,

所以我們只需要把這個function加進protocol,

讓bootloader能access這個protocol.


xbl的部份:
Include/Protocol/EFIPmicSchg.h
增加新的定義:


+typedef
+EFI_STATUS(EFIAPI *EFI_PMIC_SCHG_ENABLE_SHIP_MODE)
+(
+  IN UINT32                     PmicDeviceIndex
+);

struct _EFI_PMIC_SCHG_PROTOCOL {
...
+EFI_PMIC_SCHG_ENABLE_SHIP_MODE                EnableShipMode;
...
};


Drivers/PmicDxe/PmicSchgProtocol.c
增加新的function:

+EFI_STATUS
+EFIAPI
+EFI_PmicSchgEnableShipMode
+(
+  IN UINT32    PmicDeviceIndex
+)
+{
+  pm_err_flag_type errFlag = PM_ERR_FLAG__SUCCESS;
+
+  errFlag = pm_schg_batif_enable_shipmode(PmicDeviceIndex);
+  if (PM_ERR_FLAG__SUCCESS != errFlag)
+  {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}









EFI_QCOM_PMIC_SCHG_PROTOCOL PmicSchgProtocolImplementation =
{
   ...
+EFI_PmicSchgEnableShipMode,
   ...
};


bootloader的部份:
把xbl裡面protocol的header檔copy過來,
Include/Protocol/EFIPmicSchg.h

Library/BootLib/BootLib.inf
加入protocol的guid:
[Protocols]
...
        gPmicSchgProtocolGuid


XXXModulePkg.dec
更改description, 加入protocol的uuid
gPmicSchgProtocolGuid =          { 0xxxxxxxxx } }


使用protocol function的方式:
EFI_STATUS Status = EFI_SUCCESS;
EFI_PMIC_SCHG_PROTOCOL *PmicSchgProtocol = NULL;
Status = gBS->LocateProtocol(&gPmicSchgProtocolGuid, NULL, (VOID **) &PmicSchgProtocol);

PmicSchgProtocol->EnableShipMode(PM_DEVICE_1);









































2017年11月2日 星期四

[工作] addr2line用法

Trace程式crash時滿好用的.

在Android上, 有程式crash時,
通常會產生一串資訊, 重點如下:
10-31 22:50:29.231 F/DEBUG   ( 5121): backtrace:
10-31 22:50:29.231 F/DEBUG   ( 5121):     #00 pc 00000000000ca8c4  /system/lib64/libsurfaceflinger.so (_ZNK4HWC25Layer11isAbandonedEv+56)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #01 pc 00000000000be370  /system/lib64/libsurfaceflinger.so (_ZN7android5Layer11hasHwcLayerEi+372)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #02 pc 00000000000bc33c  /system/lib64/libsurfaceflinger.so (_ZN7android14SurfaceFlinger15setUpHWComposerEv+2312)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #03 pc 00000000000bb03c  /system/lib64/libsurfaceflinger.so (_ZN7android14SurfaceFlinger20handleMessageRefreshEv+108)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #04 pc 00000000000bae3c  /system/lib64/libsurfaceflinger.so (_ZN7android14SurfaceFlinger17onMessageReceivedEi+124)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #05 pc 0000000000015e58  /system/lib64/libutils.so (_ZN7android6Looper9pollInnerEi+336)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #06 pc 0000000000015c54  /system/lib64/libutils.so (_ZN7android6Looper8pollOnceEiPiS1_PPv+60)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #07 pc 000000000008f620  /system/lib64/libsurfaceflinger.so (_ZN7android12MessageQueue11waitMessageEv+92)
10-31 22:50:29.231 F/DEBUG   ( 5121):     #08 pc 00000000000b9990  /system/lib64/libsurfaceflinger.so (_ZN7android14SurfaceFlinger3runEv+20)
10-31 22:50:29.232 F/DEBUG   ( 5121):     #09 pc 0000000000002d08  /system/bin/surfaceflinger (main+960)
10-31 22:50:29.232 F/DEBUG   ( 5121):     #10 pc 000000000001ba78  /system/lib64/libc.so (__libc_init+88)
10-31 22:50:29.232 F/DEBUG   ( 5121):     #11 pc 00000000000028a8  /system/bin/surfaceflinger (do_arm64_start+80)

addr2line就是幫助你從這堆東西裡面,
找出在哪段程式碼出錯的工具.

ex:
./aarch64-linux-android-addr2line -e ~/work/BSP/android/out/target/product/Cell/symbols/system/lib64/libsurfaceflinger.so 00000000000ca8c4


注意, 必須是要在out/target/product/[project]/symbol下面的

他會顯示出錯誤的地方在哪個檔案, 第幾行.

2017年7月31日 星期一

2017年7月20日 星期四

[工作] command line寫入16進位binary到檔案

$ echo -e "\x10\x11\x12" > test
$ cat test | xxd
$ 0000000: 1011 120a

後面的0x0a為換行符號

$ printf '\xde\xad\xbe\xef' > file
$ cat file | xxd
$ 0000000: dead beef

[工作] 在sysfs下加入GPIO debug

在那根GPIO還沒有被request的狀態下:
echo [GPIO number] > /sys/class/gpio/export
就會產生/sys/class/gpio/gpio[GPIO number]
ex.
echo 4 > /sys/class/gpio/export
cd /sys/class/gpio/gpio4
裡面會有幾個節點可以操作
active_low
device
edge
power
uevent
value

如果那根GPIO已經被driver request,
則上面的方式會無效,
需要從code裡面來作:
呼叫gpiolib裡提供的方式
gpiod_export(GPIO_NUM);

就會產生類似上面的節點.

2017年7月5日 星期三

[工作] 在Android上如何能在USB拔除後繼續抓log

一般來說子程序在父程序結束後也會被kill掉,
Android上有個nohup指令能防止子程序被kill,
並把父程序轉給init(pid = 1)

使用範例:
adb shell "nohup cat /proc/kmsg > /sdcard/test"

之後就算你USB拔除, 他還是會繼續抓log

2017年7月3日 星期一

[工作] Kernel driver讀寫文件的方式

Header檔:
#include <linux/fs.h>
#include <linux/file.h>
#include <asm/uaccess.h>

程式碼:
char *path = "/abc/test"
struct file *fp = NULL;
mm_segment_t old_fs;
u8 buf[256];

fp = filp_open(path, O_RDONLY, 0);
if (fp == NULL) {
    return -1;
}

old_fs = get_fs();
set_fs(KERNEL_DS);

fp->f_op->read(fp, buf, sizeof(buf), &fp->f_pos);

set_fs(old_fs);

filp_close(fp, NULL);


主要重點是紅字的部份

簡單來說是要防止User space破壞到Kernel space的內容

傳遞給->read / ->write的參數因為是kernel的位址

會被認為不合法, user被禁止存取,

所以要先把ds改成kernel, 才不會被誤認成user

大概是個root的概念

不過操作完記得設回來

2017年6月27日 星期二

[工作] Get dir name and file name of a path

在Linux下如何使用command取得一串path的dirname跟filename

其實很簡單, 有兩個command, dirname, basename
ex: pathname  = /abc/def/test.c

$ dirname $pathname
$ /abc/def

$ basename $pathname
$ test.c

2017年6月24日 星期六

[Game] 鐵血聯盟2 GOG版本在Macbook上執行的方式

之前被介紹文推坑,等到前陣子終於GOG特價,
我租屋處只有MacBook Pro,不過我看他有支援Mac OS就放心入手了。


不過興高采烈的下載下來安裝之後發現無法進入遊戲,
一執行後都是看到藍畫面後閃退,
看一下GOG上最後更新大概是四年前了,
之間Mac OS有些更新後可能無法相容,
四處搜尋之後總算解決,解法如下

1. 下載最新的Wineskin Winery
http://wineskin.urgesoftware.com/tiki-index.php?page=Downloads

下載之後執行,按畫面上的 "+" 新增新的Engine
我是下載最新的版本 (WS9Wine2.6)

載好之後就可以先關掉

2. 更新GOG版鐵血聯盟2的Winery engine
GOG版本的鐵血聯盟2預設就是包著Winery來執行
不過版本比較舊,不相容於現在的Mac OS

開啟Finder -> 左邊喜好項目點選應用程式 -> 找到鐵血聯盟2的目錄 ->
右鍵(或是雙指點擊觸控板) 點選顯示套件內容 -> Contents -> Resources -> Game ->
右鍵點選Jagges Alliance 2 -> 顯示套件內容 -> 執行Wineskin

然後在Advanced -> Tools -> Update wrapper
選擇你下載的最新的wrapper就ok了

2017年6月22日 星期四

[工作] 有時用shell比較兩個字串, 結果卻不是你預期的?

比方說, 在Android下,
你想比較product name是不是你要的,
你大概會這麼做:

#!/bin/bash

PRODUCT=`adb shell getprop ro.product.name`

echo "$PRODUCT"
if [ "$PRODUCT" == "MyProduct" ] ; then
        echo "Product found!"
else
        echo "Not this product."
fi

但是執行結果卻...
$ MyProduct
$ Not this product.

就算得到的product name是你想要的,
但比對結果卻不正確.

把得到的結果轉換成16進位印出,
會發現其實得到的結果有多餘的東西...

adb shell getprop "ro.product.name" | xxd
$ 0000000: 4d79 5072 6f6a 6563 740d0a                 MyProject..

echo "MyProject" | xxd
$ 0000000: 4d79 5072 6f6a 6563 740a                     MyProject.

原來取得的值多了一個\r (0d)

解法就是取得值將\r去掉:
BOOT_COMPLETE=`adb shell getprop "ro.product.name" | tr -d '\r'`

再去比對就沒問題了

2017年5月21日 星期日

[工作] 在Android上如何確認你的裝置有連外的能力

在Android上, 我們可能會用ConnectivityManager來檢查連線狀態:
public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}
 
這只能檢查Android device是否有連線到AP, 卻不能知道是否有對外連線的能力.
 
想要檢查現在裝置是否能對外連線, 目前找到兩種方式:
1. 用ping檢查
public boolean isOnline() {
    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    }
    catch (IOException e)          { e.printStackTrace(); }
    catch (InterruptedException e) { e.printStackTrace(); }

    return false;
}
 
2. 連線至DNS檢查  
public boolean isOnline() {
    try {
        int timeoutMs = 1500;
        Socket sock = new Socket();
        SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);

        sock.connect(sockaddr, timeoutMs);
        sock.close();

        return true;
    } catch (IOException e) { return false; }
}
 
來源參考:
http://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-times-out
 

2017年5月20日 星期六

[工作] Windows10版docker安裝路徑更改

我的Windows10是Home Edition的,

所以只能安裝Docker tool

首先在還沒開始安裝之前, 需要先設定以下環境變數.

MACHINE_STORAGE_PATH
DOCKER_CERT_PATH
路徑設為你要安裝的地方.

然後再開始安裝docker tool, 就ok了

2017年3月26日 星期日

[工作] shell script加減乘除

在shell script計算加減乘除的方式, 可以用expr

#!/bin/sh

VALUE=100
VALUE=`expr $VALUE - 10`
echo "After minus: $VALUE"

VALUE=`expr $VALUE + 10`
echo "After plus: $VALUE"

VALUE=`expr $VALUE / 10`
echo "After divide: $VALUE"

VALUE=`expr $VALUE * 10`
echo "After multiply: $VALUE"
執行結果:
After minus: 90
After plus: 100
After divide: 10
After multiply: 100

不過在Android上, 會發生找不到expr的錯誤
所以要改用下面的方式

#!/bin/sh

VALUE=100

VALUE=$((VALUE - 10))
echo "$VALUE after minus"

VALUE=$((VALUE + 10))
echo "$VALUE after plus"

VALUE=$((VALUE / 10))
echo "$VALUE after divide"

VALUE=$((VALUE * 10))
echo "$VALUE after multiply"

執行結果:
90 after minus
100 after plus
10 after divide
100 after multiply

2017年3月21日 星期二

[工作] vim修正Windows換行符號,並移除空白行

在vim中可以下
:set ff=unix
將格式改成unix的檔案格式(原本ff=dos)

並且
:g/^$/d
可將開頭為空白的行刪除

2017年2月15日 星期三

[工作] Android Studio 從舊專案建立新專案並改名

1. 手動複製舊專案到新資料夾並改名
2. AndroidManifest.xml
  將package改成你要的名字
3. app裡build.gradle
  application改成你新的package name
4. 在檔案右鍵Refactor -> Rename改成新的package name

2017年1月12日 星期四

[工作] Kernel driver發uevent的方法

方法很單純,就是把你想要發的event包一包發出去。

    char event[20];
    char *envp[] = { event, NULL };

    sprintf(event_string, "STAND_EVENT=undock");
    kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);