2017年12月21日 星期四
[工作] Android pm取的package name跟path的用法
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)
找了一下之後發現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年10月18日 星期三
2017年7月31日 星期一
2017年7月20日 星期四
[工作] command line寫入16進位binary到檔案
$ cat test | xxd
$ 0000000: 1011 120a
後面的0x0a為換行符號
$ printf '\xde\xad\xbe\xef' > file
$ cat file | xxd
$ 0000000: dead beef
[工作] 在sysfs下加入GPIO debug
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
Android上有個nohup指令能防止子程序被kill,
並把父程序轉給init(pid = 1)
使用範例:
adb shell "nohup cat /proc/kmsg > /sdcard/test"
之後就算你USB拔除, 他還是會繼續抓log
2017年7月3日 星期一
[工作] Kernel driver讀寫文件的方式
#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
其實很簡單, 有兩個command, dirname, basename
ex: pathname = /abc/def/test.c
$ dirname $pathname
$ /abc/def
$ basename $pathname
$ test.c
2017年6月24日 星期六
[Game] 鐵血聯盟2 GOG版本在Macbook上執行的方式
我租屋處只有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比較兩個字串, 結果卻不是你預期的?
你想比較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年6月17日 星期六
2017年5月21日 星期日
[工作] 在Android上如何確認你的裝置有連外的能力
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安裝路徑更改
所以只能安裝Docker tool
首先在還沒開始安裝之前, 需要先設定以下環境變數.
MACHINE_STORAGE_PATH
DOCKER_CERT_PATH
路徑設為你要安裝的地方.
然後再開始安裝docker tool, 就ok了
2017年3月26日 星期日
[工作] shell script加減乘除
#!/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日 星期二
2017年2月15日 星期三
[工作] Android Studio 從舊專案建立新專案並改名
2. AndroidManifest.xml
將package改成你要的名字
3. app裡build.gradle
application改成你新的package name
4. 在檔案右鍵Refactor -> Rename改成新的package name
2017年1月12日 星期四
[工作] Kernel driver發uevent的方法
char event[20];
char *envp[] = { event, NULL };
sprintf(event_string, "STAND_EVENT=undock");
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);