2021/10/30

sdkmanager Error : Exception in thread "main" java.lang.NoClassDefFoundError:

從 studio run sdkmanager OK,但是從 command line run sdkmanager 時出現錯誤:
  dkmanager 
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
	at com.android.repository.api.SchemaModule$SchemaModuleVersion.(SchemaModule.java:156)
	at com.android.repository.api.SchemaModule.(SchemaModule.java:75)
	at com.android.sdklib.repository.AndroidSdkHandler.(AndroidSdkHandler.java:81)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	... 5 more
一堆人說,用studio 的 sdkmanager 安裝 commandline-tools 之後就好了。
結果裝了還是一樣 的錯。

後來發現...
裝了 cmdline-tools 後,裡面也有一個 sdkmanager, run 這個 sdkmanager 就不會有 error 了。
這兩個 sdkmanager 都是 shell script,所以來diff 一下...
cmdline-tools/latest/bin$ diff sdkmanager ../../../tools/bin/sdkmanager 
5c5
< ##  sdkmanager start up script for Linux
---
> ##  sdkmanager start up script for UN*X
31c31
< DEFAULT_JVM_OPTS='-Dcom.android.sdklib.toolsdir=$APP_HOME'
---
> DEFAULT_JVM_OPTS='"-Dcom.android.sdklib.toolsdir=$APP_HOME"'
67c67
< CLASSPATH=$APP_HOME/lib/sdkmanager-classpath.jar
---
> CLASSPATH=$APP_HOME/lib/dvlib-26.0.0-dev.jar:$APP_HOME/lib/jimfs-1.1.jar:$APP_HOME/lib/jsr305-1.3.9.jar:$APP_HOME/lib/repository-26.0.0-dev.jar:
$APP_HOME/lib/j2objc-annotations-1.1.jar:$APP_HOME/lib/layoutlib-api-26.0.0-dev.jar:$APP_HOME/lib/gson-2.3.jar:$APP_HOME/lib/httpcore-4.2.5.jar:
$APP_HOME/lib/commons-logging-1.1.1.jar:$APP_HOME/lib/commons-compress-1.12.jar:$APP_HOME/lib/annotations-26.0.0-dev.jar:
$APP_HOME/lib/error_prone_annotations-2.0.18.jar:$APP_HOME/lib/animal-sniffer-annotations-1.14.jar:$APP_HOME/lib/httpclient-4.2.6.jar:
$APP_HOME/lib/commons-codec-1.6.jar:$APP_HOME/lib/common-26.0.0-dev.jar:$APP_HOME/lib/kxml2-2.3.0.jar:$APP_HOME/lib/httpmime-4.1.jar:
$APP_HOME/lib/annotations-12.0.jar:$APP_HOME/lib/sdklib-26.0.0-dev.jar:$APP_HOME/lib/guava-22.0.jar
果然就是 classpath,猜是 tools/bin 是給 studio 用的,它已經default 有一些 jar 了。
cmdline-tools 的才是給 command line 用的。


其實這是要 Accept Android SDK/tool licenses 時遇到的。
用 sdkmanager --licenses 來 accept 所有 license。
accept 之後,會在 Android/Sdk/License 中出現很多 license 檔。

2021/10/24

tensorflow lite android example, build

lite 的 example 跟 tensor 是合在一起的,所以要整個 clone。

雖然說明說,就用 studio 開啟project 然後 build 就可以了,結果 fail,說 :app task 少一個...wrapper (?)
只好用手動,參考 tools 下的 script,是 call project 下的 gradlew 來 build 的,
奇怪 run build_all_android... 卻沒有 build,手動 run build_android_app.sh + example_path 也一樣,一直說沒有 gradlw。

手動的話,就是到 project 下 run
./gradlew assembleRelease 
有碰到兩個 error,一個說沒有 ANDROID_SDK_ROOT 變數,就 export 一下,指定到 Sdk folder
另外一個說沒有需要的 Ndk 版本 (跟有安裝的不一樣),所以參考這一篇,安裝特定版本的 Ndk 後,就 OK 了。


使用 studio 開啟 'android' folder 是可以 build 的,但是一旦接受建議,把 gradlew 從 4.0 升級到 7.0 之後,就有 error 了。
遵照這一頁:Allow insecure protocols, android gradle,修改的話...
diff --git a/lite/examples/object_detection/android/build.gradle b/lite/examples/object_detection/android/build.gradle
index 8ccd3140..b820d78d 100644
--- a/lite/examples/object_detection/android/build.gradle
+++ b/lite/examples/object_detection/android/build.gradle
@@ -7,7 +7,7 @@ buildscript {
         mavenLocal()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.0.0'
+        classpath 'com.android.tools.build:gradle:7.0.3'
         classpath 'de.undercouch:gradle-download-task:4.0.2'
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -19,6 +19,7 @@ allprojects {
         google()
         mavenCentral()
         maven {
+           allowInsecureProtocol = true
             name 'ossrh-snapshot'
             url 'http://oss.sonatype.org/content/repositories/snapshots'
         }
第一個 diff 是 studio upgrade 時改的,第二格是要自己加的。
加完後,重新 build 就 OK了。
.. 但是用 studio build 真的比較久,build 完電腦還當機。
用 command line 比較快。


認真看一下 error message:
Could not resolve all dependencies for configuration ':app:taskApiDebugRuntimeClasspath'.
Using insecure protocols with repositories, without explicit opt-in, is unsupported. 
Switch Maven repository 'ossrh-snapshot(http://oss.sonatype.org/content/repositories/snapshots)' 
to redirect to a secure protocol (like HTTPS) or allow insecure protocols. 
See
allowInsecureProtocol
for more details. 

大部分的 project 都只需要改這些 build.gradle ,有些要改manifest。為了方便,fork 一份到自幾的 github,其中 branch: gradle7 就是為了新版 android studio 的新版 gradle 修改的

2021/10/13

eMMC Life (狀態,壽命)

有一個 tool: mmc-utils。 可以用來讀取 eMMC 的register。

就拉下來 make 就可以,在 x86 跟 ARM (pi ubuntu aarch64) 都 build OK。

然後就可以看
# /data/mmc extcsd read /dev/mmcblk0
=============================================
  Extended CSD rev 1.8 (MMC 5.1)
=============================================

Card Supported Command sets [S_CMD_SET: 0x01]
HPI Features [HPI_FEATURE: 0x01]: implementation based on CMD13
Background operations support [BKOPS_SUPPORT: 0x01]
Max Packet Read Cmd [MAX_PACKED_READS: 0x3f]
Max Packet Write Cmd [MAX_PACKED_WRITES: 0x3f]
Data TAG support [DATA_TAG_SUPPORT: 0x01]
Data TAG Unit Size [TAG_UNIT_SIZE: 0x02]
Tag Resources Size [TAG_RES_SIZE: 0x00]
Context Management Capabilities [CONTEXT_CAPABILITIES: 0x05]
Large Unit Size [LARGE_UNIT_SIZE_M1: 0x07]
Extended partition attribute support [EXT_SUPPORT: 0x03]
Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x0a]
Power off notification [POWER_OFF_LONG_TIME: 0x3c]
Cache Size [CACHE_SIZE] is 65536 KiB
Background operations status [BKOPS_STATUS: 0x00]
1st Initialisation Time after programmed sector [INI_TIMEOUT_AP: 0x1e]
Power class for 52MHz, DDR at 3.6V [PWR_CL_DDR_52_360: 0x00]
Power class for 52MHz, DDR at 1.95V [PWR_CL_DDR_52_195: 0x00]
Power class for 200MHz at 3.6V [PWR_CL_200_360: 0x00]
Power class for 200MHz, at 1.95V [PWR_CL_200_195: 0x00]
Minimum Performance for 8bit at 52MHz in DDR mode:
 [MIN_PERF_DDR_W_8_52: 0x00]
 [MIN_PERF_DDR_R_8_52: 0x00]
TRIM Multiplier [TRIM_MULT: 0x02]
Secure Feature support [SEC_FEATURE_SUPPORT: 0x55]
Boot Information [BOOT_INFO: 0x07]
 Device supports alternative boot method
 Device supports dual data rate during boot
 Device supports high speed timing during boot
Boot partition size [BOOT_SIZE_MULTI: 0x20]
Access size [ACC_SIZE: 0x07]
High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x01]
 i.e. 512 KiB
High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x01]
Reliable write sector count [REL_WR_SEC_C: 0x01]
High-capacity W protect group size [HC_WP_GRP_SIZE: 0x10]
 i.e. 8192 KiB
Sleep current (VCC) [S_C_VCC: 0x07]
Sleep current (VCCQ) [S_C_VCCQ: 0x07]
Sleep/awake timeout [S_A_TIMEOUT: 0x11]
Sector Count [SEC_COUNT: 0x00e90000]
 Device is block-addressed
Minimum Write Performance for 8bit:
 [MIN_PERF_W_8_52: 0x00]
 [MIN_PERF_R_8_52: 0x00]
 [MIN_PERF_W_8_26_4_52: 0x00]
 [MIN_PERF_R_8_26_4_52: 0x00]
Minimum Write Performance for 4bit:
 [MIN_PERF_W_4_26: 0x00]
 [MIN_PERF_R_4_26: 0x00]
Power classes registers:
 [PWR_CL_26_360: 0x00]
 [PWR_CL_52_360: 0x00]
 [PWR_CL_26_195: 0x00]
 [PWR_CL_52_195: 0x00]
Partition switching timing [PARTITION_SWITCH_TIME: 0x02]
Out-of-interrupt busy timing [OUT_OF_INTERRUPT_TIME: 0x0a]
I/O Driver Strength [DRIVER_STRENGTH: 0x1f]
Card Type [CARD_TYPE: 0x57]
 HS200 Single Data Rate eMMC @200MHz 1.8VI/O
 HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O
 HS eMMC @52MHz - at rated device voltage(s)
 HS eMMC @26MHz - at rated device voltage(s)
CSD structure version [CSD_STRUCTURE: 0x02]
Command set [CMD_SET: 0x00]
Command set revision [CMD_SET_REV: 0x00]
Power class [POWER_CLASS: 0x00]
High-speed interface timing [HS_TIMING: 0x02]
Erased memory content [ERASED_MEM_CONT: 0x00]
Boot configuration bytes [PARTITION_CONFIG: 0x08]
 Boot Partition 1 enabled
 No access to boot partition
Boot config protection [BOOT_CONFIG_PROT: 0x00]
Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x0e]
High-density erase group definition [ERASE_GROUP_DEF: 0x01]
Boot write protection status registers [BOOT_WP_STATUS]: 0x00
Boot Area Write protection [BOOT_WP]: 0x00
 Power ro locking: possible
 Permanent ro locking: possible
 ro lock status: not locked
User area write protection register [USER_WP]: 0x00
FW configuration [FW_CONFIG]: 0x00
RPMB Size [RPMB_SIZE_MULT]: 0x04
Write reliability setting register [WR_REL_SET]: 0x1f
 user area: the device protects existing data if a power failure occurs during a write operation
 partition 1: the device protects existing data if a power failure occurs during a write operation
 partition 2: the device protects existing data if a power failure occurs during a write operation
 partition 3: the device protects existing data if a power failure occurs during a write operation
 partition 4: the device protects existing data if a power failure occurs during a write operation
Write reliability parameter register [WR_REL_PARAM]: 0x14
 Device supports the enhanced def. of reliable write
Enable background operations handshake [BKOPS_EN]: 0x00
H/W reset function [RST_N_FUNCTION]: 0x01
HPI management [HPI_MGMT]: 0x01
Partitioning Support [PARTITIONING_SUPPORT]: 0x07
 Device support partitioning feature
 Device can have enhanced tech.
Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x0001d2
 i.e. 3817472 KiB
Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x00
Partitioning Setting [PARTITION_SETTING_COMPLETED]: 0x00
 Device partition setting NOT complete
General Purpose Partition Size
 [GP_SIZE_MULT_4]: 0x000000
 [GP_SIZE_MULT_3]: 0x000000
 [GP_SIZE_MULT_2]: 0x000000
 [GP_SIZE_MULT_1]: 0x000000
Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x000000
 i.e. 0 KiB
Enhanced User Data Start Address [ENH_START_ADDR]: 0x00000000
 i.e. 0 bytes offset
Bad Block Management mode [SEC_BAD_BLK_MGMNT]: 0x00
Periodic Wake-up [PERIODIC_WAKEUP]: 0x00
Program CID/CSD in DDR mode support [PROGRAM_CID_CSD_DDR_SUPPORT]: 0x01
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[127]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[126]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[125]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[124]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[123]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[122]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[121]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[120]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[119]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[118]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[117]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[116]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[115]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[114]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[113]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[112]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[111]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[110]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[109]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[108]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[107]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[106]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[105]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[104]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[103]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[102]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[101]]: 0x05
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[100]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[99]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[98]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[97]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[96]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[95]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[94]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[93]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[92]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[91]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[90]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[89]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[88]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[87]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[86]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[85]]: 0x01
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[84]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[83]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[82]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[81]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[80]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[79]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[78]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[77]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[76]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[75]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[74]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[73]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[72]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[71]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[70]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[69]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[68]]: 0xc8
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[67]]: 0xc8
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[66]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[65]]: 0x00
Vendor Specific Fields [VENDOR_SPECIFIC_FIELD[64]]: 0x0f
Native sector size [NATIVE_SECTOR_SIZE]: 0x00
Sector size emulation [USE_NATIVE_SECTOR]: 0x00
Sector size [DATA_SECTOR_SIZE]: 0x00
1st initialization after disabling sector size emulation [INI_TIMEOUT_EMU]: 0x00
Class 6 commands control [CLASS_6_CTRL]: 0x00
Number of addressed group to be Released[DYNCAP_NEEDED]: 0x00
Exception events control [EXCEPTION_EVENTS_CTRL]: 0x0000
Exception events status[EXCEPTION_EVENTS_STATUS]: 0x0000
Extended Partitions Attribute [EXT_PARTITIONS_ATTRIBUTE]: 0x0000
Context configuration [CONTEXT_CONF[51]]: 0x00
Context configuration [CONTEXT_CONF[50]]: 0x00
Context configuration [CONTEXT_CONF[49]]: 0x00
Context configuration [CONTEXT_CONF[48]]: 0x00
Context configuration [CONTEXT_CONF[47]]: 0x00
Context configuration [CONTEXT_CONF[46]]: 0x00
Context configuration [CONTEXT_CONF[45]]: 0x00
Context configuration [CONTEXT_CONF[44]]: 0x00
Context configuration [CONTEXT_CONF[43]]: 0x00
Context configuration [CONTEXT_CONF[42]]: 0x00
Context configuration [CONTEXT_CONF[41]]: 0x00
Context configuration [CONTEXT_CONF[40]]: 0x00
Context configuration [CONTEXT_CONF[39]]: 0x00
Context configuration [CONTEXT_CONF[38]]: 0x00
Context configuration [CONTEXT_CONF[37]]: 0x00
Packed command status [PACKED_COMMAND_STATUS]: 0x00
Packed command failure index [PACKED_FAILURE_INDEX]: 0x00
Power Off Notification [POWER_OFF_NOTIFICATION]: 0x01
Control to turn the Cache ON/OFF [CACHE_CTRL]: 0x01
eMMC Firmware Version: 
eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x08
eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x08
eMMC Pre EOL information [EXT_CSD_PRE_EOL_INFO]: 0x01
Secure Removal Type [SECURE_REMOVAL_TYPE]: 0x39
 information is configured to be removed using a vendor defined
 Supported Secure Removal Type:
  information removed by an erase of the physical memory
  information removed using a vendor defined
Command Queue Support [CMDQ_SUPPORT]: 0x01
Command Queue Depth [CMDQ_DEPTH]: 16
Command Enabled [CMDQ_MODE_EN]: 0x00
根據working with eMMC 的說明:

It is possible to get an estimation on the health status of the device by checking the parameters
EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A and EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B.
The estimation is given in steps of 10% so a value of 0x01 means that 0% to 10% life time used.
This functionality was introduced in eMMC 5.0.
# mmc extcsd read /dev/mmcblk2 | grep EXT_CSD_DEVICE_LIFE_TIME_EST
eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x01
eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x01  
所以上面 example 的 eMMC 壽命已經到 70~80% 了

另外一個 command 是 fstrim
Usage:
 fstrim [options] 

Discard unused blocks on a mounted filesystem.

Options:
 -a, --all           trim all supported mounted filesystems
 -A, --fstab         trim all supported mounted filesystems from /etc/fstab
 -o, --offset   the offset in bytes to start discarding from
 -l, --length   the number of bytes to discard
 -m, --minimum  the minimum extent length to discard
 -v, --verbose       print number of discarded bytes
 -n, --dry-run       does everything, but trim

 -h, --help          display this help
 -V, --version       display version
用 -v 來看,真的會顯示 discard 的 size...
ref:

2021/10/12

some memos's for anaysis log

用 sed 來處理log 會用到的 pattern:

刪除行:

刪除10~20 行:
sed -i '10,20d' myfile

刪除包含'my abc' 的那些行
sed -i '/my abc/d' myfile

要是太多,只要挑出幾個,可以用 grep:
包含 'Booting ', 'my abc', 'is OK' 的那幾行:
grep 'Booting \|my abc\|is OK' myfile

找 8 digits 16 hex
grep -E '0x[0-9A-Fa-f]{8}' myfile
-- repeat 8 次 {8} 這個 option 需要 -E 選項

這個用在 sed 的話,就要加 -r 選項
sed -i -r '/0x[0-9A-Fa-f]{8}/d' myfile

Bookmark: Chromium OS for raspberry pi

從 Link 就知道是 FydeOS build 的。
所以他們的 github 上還有一些其他的 port.

2021/10/8

armbian , for banana pi

超古老 banana pi (M1)。找得到還有支援的 distribution,就剩下 armbian
目前 debian official 已經是 11 (bull's eye),armbian for bananpi M1 最新的 stable 只到 10 (buster),但是至少 kernel 是 5.10
-- 原來有支援 debian 跟 ubuntu。各自依照 distribution 來表示。

一樣,download xz 解開,dd 到 sd card 上。
只有一個 partition,mount 進來後,已經有 /boot,不是像 raspberry pi 一樣有獨立的 /boot partition (fat)。

開機,在 console 有輸出.. 一直到 kernel booting 後就沒了 (猜是display 在 hdmi),等30 sec.. 後就出現 prompt,要求輸入 root password。
root password 有嚴格的檢查,不能包含在 dictionary 裡面的詞。(但是 login 後可以改)。

login 後 keyboard mapping 有問題,要
export TERM=vt100
才會正常。

修改 /boot/armbianEnv.txt,把 console=both 改成 serial,kernel log 就會出現在 console 上了。
開進 shell , keyboard mapping 也對了 (雖然 TERM 是 linux)

run armbian-config..

很方便,竟然有 hostspot...,而且自己外接的 wifi dongle 自動偵測到 (rt2800usb)
一段自動偵測,設定之後,會出現 interface 給你選,這個要選 ethernet。
然後就會用 default 的 SSID, password 啟動。
iptables, ip_forwards 都會設好。

要改 SSID, password 的話,再選一次 hostapd,選 advance ,就可以 edit ssid, passowrd.

hostapd, dnsmasq 都是 systemctl service,和 iptables 的設定各是:
/etc/hostapd.conf
/etc/dnsmasq.conf
/etc/iptables.ipv4.nat

使用心得... 比以前的(?) 好很多,作為 wifi router,都沒有以前動不動就 kernel trape 的現象,連 driver 也不像以前常常出現 warnning message...

mender.io : dump content from *.mender

要從 mender file 中拿到安裝檔,script...,要用 dump command:
~$ mender-artifact dump --help
NAME:
   mender-artifact dump - Dump contents from Artifacts

USAGE:
   mender-artifact dump [command options] <Artifact>

DESCRIPTION:
   Dump various raw files from the Artifact. These can be used to create a new Artifact with the same components.

OPTIONS:
   --files value      Dump all included files in the first payload into given folder
   --meta-data value  Dump the contents of the meta-data field in the first payload into given folder
   --print-cmdline    Print the command line that can recreate the same Artifact with the components being dumped. 
                      If all the components are being dumped, a nearly identical Artifact can be created. 
                      Note that timestamps will cause the checksum of the Artifact to be different, 
                      and signatures can not be recreated this way. The command line will only use long option names.
   --print0-cmdline   Same as 'print-cmdline', except that the arguments are separated by a null character (0x00).
   --scripts value    Dump all included state scripts into given folder
   
上面help 中的value 是說你要 dump 到那一個目錄...

討論區文章的說明,mender 可以直接用 tar 解開。
實際測試,tar 解開的不包含 scripts 和 print-cmdline 的內容。
大概跟 --files 的輸出一樣。

所以要拿到 state_scripts ,還是要用 dump command


另外,做 delta update 時,會確認 base image 的 checksum 和 delta ota package 中的 base image 是不是一樣。
是用 sha256sum 來確認的。
sha256sum <your partition> 

2021/10/5

kernel console , buf length and sync async

是說.. 現在 kernel printk 都已經是 async 了。
但是要 force sync 的話,還是可以,用printk.synchronous = 1,加到 boot cmdline

printk log buffer length 也可以改,有兩種方法..
一個是改 kernel,一個是用 boot cmdline

CONFIG_LOG_BUF_SHIFT : 可以用 menuconfig 設定。

log_buf_len=65536 : 可以加在 boot cmdline

banana pi, console UART

主要是 banana pi 的 console uart pin 跟 raspberry pi 不一樣。
不是在 gpio 那兩排,而是在中間突出的一小塊。

bookmark: A Minimum Complete Tutorial of Linux ext4 File System

上面 e2fsprog 裡免的 debugfs :
# debugfs -R "ls -l" /dev/sda6
  2   40755 (2)   1001   1001    4096 17-Sep-2013 04:03 .
  2   40755 (2)   1001   1001    4096 17-Sep-2013 04:03 ..
 16  100644 (1)   1001   1001    9085 17-Sep-2013 04:03 avserver.conf
 17  100644 (1)   1001   1001    2177 17-Sep-2013 04:03 bash.bashrc
 26  100644 (1)   1001   1001     722 17-Sep-2013 04:03 crontab
還有 cat 的方法:
進入 debugfs,argument 是 ext4 的 image:
$ debugfs my.ext4
debugfs:
然後就可以在 debugfs 這個 prompt 下命令。
像 ls -l 或是 cat /etc/os-release...

repo forall .. variable name

repo forall 可以用的 變數,在 subcmds/forall.py 中有說明
# Environment

pwd is the project's working directory.  If the current client is
a mirror client, then pwd is the Git repository.

REPO_PROJECT is set to the unique name of the project.

REPO_PATH is the path relative the the root of the client.

REPO_REMOTE is the name of the remote system from the manifest.

REPO_LREV is the name of the revision from the manifest, translated
to a local tracking branch.  If you need to pass the manifest
revision to a locally executed git command, use REPO_LREV.

REPO_RREV is the name of the revision from the manifest, exactly
as written in the manifest.

REPO_COUNT is the total number of projects being iterated.

REPO_I is the current (1-based) iteration count. Can be used in
conjunction with REPO_COUNT to add a simple progress indicator to your
command.

REPO__* are any extra environment variables, specified by the
"annotation" element under any project element.  This can be useful
for differentiating trees based on user-specific criteria, or simply
annotating tree details.
test...
strong
em

2021/10/4

#define PKTLINK(skb)                    (((struct sk_buff*)(skb))->prev)
然後...
        /* queueing chains not allowed and no segmented SKB (Kernel-3.18.y) */
        ASSERT(!((PKTLINK(p) != NULL) && (PKTLINK(p) != p)));