就是在 /etc/sysctl.d/ 下新增一個 10-idea.conf
fs.inotify.max_user_watches = 524288然後 run
sudo sysctl -p --system
fs.inotify.max_user_watches = 524288然後 run
sudo sysctl -p --system
TimeoutStartSec=infinity這樣就不會出現 Error。
ExecStartPre=/bin/sleep 40這個地方如果有 run script,也可以在 script 中 sleep。
ClientAliveInterval ClientAliveMax是用來偵測/決定 Client 是不是存在的設定。
ClientAliveInterval 10 ClientAliveMax 5或是
ClientAliveInterval 60 ClientAliveMax 0後者的設法,就是不用送 null request 給 client 了,時間到直接切掉。
debug1: Got 100/24 for keepalive debug1: Got 100/25 for keepalive debug1: Got 100/26 for keepalive debug1: Got 100/27 for keepalive如果收到這格,sshd 就會reset ClientAliveInterval 的計數。
tr -cd '\11\12\15\40-\176' < file-with-binary-chars > clean-file
make configure之後,就可以 run configure 了。
$ ./configure --without-tcltk --without-curl --without-openssl CFLAGS="${CFLAGS} -static -static-libgcc" NO_OPENSSL=1之後就 build 成功了。
dkmanager Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema at com.android.repository.api.SchemaModule$SchemaModuleVersion.一堆人說,用studio 的 sdkmanager 安裝 commandline-tools 之後就好了。(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
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 了。
./gradlew assembleRelease有碰到兩個 error,一個說沒有 ANDROID_SDK_ROOT 變數,就 export 一下,指定到 Sdk folder
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 時改的,第二格是要自己加的。
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. SeeallowInsecureProtocol
for more details.
# /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 的說明:
# 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% 了
Usage: fstrim [options]用 -v 來看,真的會顯示 discard 的 size...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
sed -i '10,20d' myfile
sed -i '/my abc/d' myfile
grep 'Booting \|my abc\|is OK' myfile
grep -E '0x[0-9A-Fa-f]{8}' myfile-- repeat 8 次 {8} 這個 option 需要 -E 選項
sed -i -r '/0x[0-9A-Fa-f]{8}/d' myfile
export TERM=vt100才會正常。
/etc/hostapd.conf /etc/dnsmasq.conf /etc/iptables.ipv4.nat
~$ 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 到那一個目錄...
sha256sum <your partition>
# 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 my.ext4 debugfs:然後就可以在 debugfs 這個 prompt 下命令。
# 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.
udhcpc -iwlan0 -R可以看到取得 ip,然後用 ip addr 看 wlan0 有 ip address。
udhcpc -iwlan0一樣,client 取得 ip,udhcpc 在背景。
git clone https://github.com/lvgl/lv_port_linux_frame_buffer.git cd lv_port_linux_frame_buffer/ git submodule update --init --recursive make
git clone https://github.com/libsdl-org/SDL.git cd SDK git checkout release-2.0.10configure , make and install
./configure --host=x86-linux --prefix=/usr --disable-x11 --enable-debug -disable-voodoo -disable-mmx --disable-see --enable-sdl --enable-jpeg --enable-zlib --enable-png --disable-gif --enable-freetype --disable-video4linux --disable-video4linux2 --with-gfxdrivers=none --with-inputdrivers=linuxinput make sudo make installdefault install path 是 /usr/lib/libSDL2.so 會自動安裝 pkgconfig
git clone --recursive https://github.com/littlevgl/pc_simulator_sdl_eclipse.git就一樣,make 後就可以 run 了,直接可以在 X 上 run ...
/* * This is a sample X11 program using Xt and the Athena widget set that * simply puts up a main window with the text "hello" in it. */ #include >X11/Intrinsic.h> #include <X11/StringDefs.h> #include <X11/Xaw/Label.h> int main(int argc, char* argv[]) { XtAppContext app_context; Widget toplevel, hello; toplevel = XtVaAppInitialize( &app_context, "XHello", NULL, 0, &argc, argv, NULL, NULL); hello = XtVaCreateManagedWidget("hello", labelWidgetClass, toplevel, NULL); XtRealizeWidget(toplevel); XtAppMainLoop(app_context); }build 的 command:
gcc helloxwindow.c -lXt -lXaw可以試試看後面的 -l 缺的化,各是會出現什麼Error..
helloxwindow.c:(.text+0x5d): undefined reference to `labelWidgetClass
undefined reference to symbol 'XtRealizeWidget'
helloxwindow.c:(.text+0x4e): undefined reference to `XtVaAppInitialize' helloxwindow.c:(.text+0x5d): undefined reference to `labelWidgetClass' helloxwindow.c:(.text+0x7a): undefined reference to `XtVaCreateManagedWidget' helloxwindow.c:(.text+0x8a): undefined reference to `XtRealizeWidget' helloxwindow.c:(.text+0x96): undefined reference to `XtAppMainLoop'
Datasheet P 19: * Register R44: Input Control * Bit 8 * Label: MBVSEL * Default: 0 * Description: Microphone Bias Voltage Control 0: 0.9 x AVDD 1: 0.75 x AVDD所以在 wm8974.c 中加一個 amixer control:
diff --git a/linux-4.14/sound/soc/codecs/wm8974.c b/linux-4.14/sound/soc/codecs/wm8974.c index 61fbd7c55..7a1c492d2 100644 --- a/linux-4.14/sound/soc/codecs/wm8974.c +++ b/linux-4.14/sound/soc/codecs/wm8974.c @@ -66,6 +66,7 @@ static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" }; static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" }; static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" }; static const char *wm8974_alc[] = {"ALC", "Limiter" }; +static const char *wm8974_mbvsel[]= {"0.9", "0.75"}; static const struct soc_enum wm8974_enum[] = { SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */ @@ -85,6 +86,7 @@ static const struct soc_enum wm8974_enum[] = { SOC_ENUM_SINGLE(WM8974_EQ5, 5, 4, wm8974_eq5), SOC_ENUM_SINGLE(WM8974_ALC3, 8, 2, wm8974_alc), + SOC_ENUM_SINGLE(WM8974_INPUT, 8, 2, wm8974_mbvsel), }; static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" }; @@ -131,6 +133,7 @@ SOC_ENUM("Equaliser EQ4 Bandwidth", wm8974_enum[9]), SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]), SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv), + SOC_ENUM("Equaliser EQ5 Bandwidth", wm8974_enum[11]), SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]), SOC_SINGLE_TLV("EQ5 Volume", WM8974_EQ5, 0, 24, 1, eq_tlv), @@ -151,6 +154,8 @@ SOC_SINGLE("ALC Capture Hold", WM8974_ALC2, 4, 7, 0), SOC_SINGLE("ALC Capture Target", WM8974_ALC2, 0, 15, 0), SOC_ENUM("ALC Capture Mode", wm8974_enum[13]), +SOC_ENUM("MIC Bias Voltage", wm8974_enum[14]), + SOC_SINGLE("ALC Capture Decay", WM8974_ALC3, 4, 15, 0), SOC_SINGLE("ALC Capture Attack", WM8974_ALC3, 0, 15, 0),這樣就多一個
numid=38,iface=MIXER,name='MIC Bias Voltage'cget, set
# amixer cget numid=38 numid=38,iface=MIXER,name='MIC Bias Voltage' ; type=ENUMERATED,access=rw------,values=1,items=2 ; Item #0 '0.9' ; Item #1 '0.75' : values=1設完後,cat register-map 來看,reg 2C bit 8 有改變。
repo init -u mymanifestmymanifest 就是放 default.xml 的 project folder
. ├── proj1 └── proj2想要用 repo/manifest 來管理。
<?xml version="1.0" encoding="UTF-8"?> <manifest> <remote name="origin" fetch="./" /> <default revision="master" remote="origin" /> <project path='proj1' name='proj1' /> <project path='prij2' name='proj2' /> </manifest>然後 myrepo 下有三個 git projects:
. ├── manifests │ └── default.xml ├── proj1 └── proj2這樣,在 local 端,就可以用 repo init 來 clone 整個 project
mkdir testrepo && cd testrepo repo init -u ~/myrepo/manifests downloading Repo source from https://gerrit.googlesource.com/git-repo remote: Counting objects: 2, done remote: Finding sources: 100% (12/12) remote: Total 12 (delta 0), reused 12 (delta 0) Unpacking objects: 100% (12/12), done. Downloading manifest from /home/charles-chang/myrepo/manifests/ remote: Counting objects: 15, done. remote: Compressing objects: 100% (10/10), done. remote: Total 15 (delta 4), reused 0 (delta 0) Your identity is: charles.chang <charles.chang@loyaltech.com> If you want to change this, please re-run 'repo init' with --config-name repo has been initialized in /home/charles-chang/testrepo之後 repo sync 就會拉下所有的 project (不包含 manifest,manifest 會在 .repo/manifests)
charles-chang@rdsuper:~/testmirror$ repo manifest <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote fetch="./" name="origin"/> <default remote="origin" revision="master"/> <project name="pp/project1" path="project1"/> <project name="project2" path="priject2"/> </manifest>加上 supress-upstream-revision
charles-chang@rdsuper:~/testmirror$ repo manifest -r --suppress-upstream-revision <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote fetch="./" name="origin"/> <default remote="origin" revision="master"/> <project dest-branch="master" name="pp/project1" path="project1" revision="7c4bcfb45cd9aa2266c0acf3f850a9ea50ae5ef9"/> <project dest-branch="master" name="project2" path="priject2" revision="907de68553f9b6d638aceb967c7a9f55bc8fcb03"/> </manifest>舊可可以把這個列出的結果存成新的 myversion.xml,加到 manifests.git 中。
. ├── priject2 │ └── pp2 └── project1 ├── p3 │ └── myfile └── pp1p3 在 project1 裡。
<manifest> <remote name="origin" fetch="./" /> <default revision="master" remote="origin" /> <project path='project1' name='pp/project1' /> <project path='priject2' name='project2' /> <project path='project1/p3' name='p3' /> </manifest>可以看到 project path='project1/p3' 這樣。
p3
revision="36fb2aa4f7f25946e0ce3d4223095ce9601dd17f" upstream="cafe/QCLA.2.0-r00015.3"這樣的話,project 要有 rev="36fb2aa4f7f25946e0ce3d4223095ce9601dd17f" 的 commit 存在,同時,還要有個branch nane叫 ""cafe/QCLA.2.0-r00015.3".
xeontitan:/etc/systemd/system# cat reportip.service [Unit] Description=send my ip address file to rdsuper Afteter=network-online.target [Service] User=charles-chang WorkingDirectory=/home/charles-chang ExecStart=/home/charles-chang/reportip.sh [Install] WantedBy=multi-user.targetcharles-chang 自己的 shell script:
cat /home/charles-chang/reportip.sh #!/bin/bash while true do ping -c 1 rdsuper if [ $? -eq 0 ] then break fi sleep 10 done ip addr > $HOSTNAME-ip scp $HOSTNAME-ip rdsuper:~/enable & start
systemctl daemon-reload systemctl enable reportip.service systemctl start reportip.service
~$ cat updatehosts.py import socket def update_hosts_file(ip, hostname): # Read the current contents of /etc/hosts with open('/etc/hosts_u', 'r') as file: lines = file.readlines() # Check if the hostname already exists in the file exists = False for i, line in enumerate(lines): if hostname in line: # Update the existing entry lines[i] = f"{ip} {hostname}\n" exists = True break # If the hostname does not exist, add a new entry if not exists: lines.append(f"{ip} {hostname}\n") # Write the updated contents back to /etc/hosts with open('/etc/hosts_u', 'w') as file: file.writelines(lines) def start_server(port): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', port)) server_socket.listen(5) print(f"Listening on port {port}...") while True: client_socket, client_address = server_socket.accept() print(f"Connection from {client_address}") data = client_socket.recv(1024).decode('utf-8') if data: ip, hostname = data.split(',') update_hosts_file(ip, hostname) print(f"Updated /etc/hosts with IP: {ip}, Hostname: {hostname}") client_socket.close() if __name__ == "__main__": start_server(61234)然後 systemd service file:
$ cat updatehosts.service [Unit] Description=Sender Python Service After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/python3 /home/charles-chang/updatehosts.py Restart=on-failure [Install] WantedBy=multi-user.target
$ cat sender_updatehosts.py import socket import time import netifaces SERVER_IP = '192.168.147.182' SERVER_PORT = 61234 def get_ip_address(interface): try: ip_address = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr'] except (ValueError, KeyError): ip_address = None hostname = socket.gethostname() return ip_address, hostname def send_data(ip, hostname): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((SERVER_IP, SERVER_PORT)) message = f"{ip},{hostname}" s.sendall(message.encode('utf-8')) response = s.recv(1024) print('Received', repr(response)) def main(): interface = 'eno1' while True: ip, hostname = get_ip_address(interface) if ip: break print("Waiting for valid IP address...") time.sleep(5) send_data(ip, hostname) if __name__ == "__main__": main()
cat << EOF > aaaa this is line one and two EOF可以用來產生 aaaa,內容就是 this is line one,
cat << "EOF"代表 把 EOF 之間的內容都當作 字串處理。
# diff /data/backup/mender.conf /etc/mender/mender.conf --- /data/backup/mender.conf +++ /etc/mender/mender.conf @@ -24,13 +24,13 @@ "StateScriptRetryTimeoutSeconds": 0, "StateScriptRetryIntervalSeconds": 0, "ModuleTimeoutSeconds": 0, - "ServerCertificate": "", + "ServerCertificate": "/data/demo.crt", "ServerURL": "", "UpdateLogPath": "", - "TenantToken": "eyJI......", + "TenantToken": "", "Servers": [ { - "ServerURL": "https://hosted.mender.io" + "ServerURL": "https://docker.mender.io" } ] }ServerURL 好像一定要概,不然會出現 Error:
level=error msg="Failure occurred while executing authorization request: Method: Post, URL: https://host.mender.io/api/devices/v1/authentication/auth_requests" func="github.com/mendersoftware/me level=error msg="Authorize failed: transient error: authorization request failed: transient error: authorization request failed: Unknown url.Error type: Host validation error" func="github.com/m level=info msg="State transition: authorize [Sync] -> authorize-wait [Idle]" func=github.com/mendersoftware/mender/app.transitionState file="/home/pi/mender-src/app/mender.go:461"一定要用 docker.mender.io 的原因可能是因為 demo server 的 hosts 有加:
127.0.0.1 s3.docker.mender.io 127.0.0.1 docker.mender.iodemo.crt copy 過來,mender.conf只要改成這樣, demo server 上就可以看到 request device
ExecStart=/usr/bin/mender --log-level debug daemon這樣 systemlog 也會有詳細的 debug log (包含 src line no).
Aug 27 06:41:40 Ambarella user.info mender[392]: time="2021-08-27T06:41:40Z" level=info msg="State transition: check-wait [Idle] -> update-check [Sync]" func=github.com/mendersoftware/mender/app.transitionState file="/home/pi/mender-src/app/mender.go:461" Aug 27 06:41:40 Ambarella user.info mender[392]: time="2021-08-27T06:41:40Z" level=info msg="Correct request for getting image from: https://s3.amazonaws.com/hosted-mender-artifacts/60114bfe1e73ac58902b5283/600f0b00-c182-4347-8fdc-e48e3ec40751?X-Amz-Algorithm=AWS4-HMAC-S Aug 27 06:41:40 Ambarella user.info mender[392]: time="2021-08-27T06:41:40Z" level=info msg="State transition: update-check [Sync] -> update-fetch [Download_Enter]" func=github.com/mendersoftware/mender/app.transitionState file="/home/pi/mender-src/app/mender.go:461" Aug 27 06:41:40 Ambarella user.info mender[392]: time="2021-08-27T06:41:40Z" level=info msg="Running Mender client version: 2.6.1" func="github.com/mendersoftware/mender/app.(*DeploymentLogManager).Enable" file="/home/pi/mender-src/app/deployment_logger.go:143" Aug 27 06:41:41 Ambarella user.info mender[392]: time="2021-08-27T06:41:41Z" level=info msg="State transition: update-fetch [Download_Enter] -> update-store [Download_Enter]" func=github.com/mendersoftware/mender/app.transitionState file="/home/pi/mender-src/app/mender.g Aug 27 06:41:42 Ambarella user.info mender[392]: time="2021-08-27T06:41:42Z" level=info msg="No public key was provided for authenticating the artifact" func=github.com/mendersoftware/mender/installer.ReadHeaders file="/home/pi/mender-src/installer/installer.go:109" Aug 27 06:41:42 Ambarella user.info mender[392]: time="2021-08-27T06:41:42Z" level=info msg="Opening device \"/dev/mmcblk0p8\" for writing" func=github.com/mendersoftware/mender/installer.bdevice.Open file="/home/pi/mender-src/installer/block_device.go:66" Aug 27 06:41:42 Ambarella user.info mender[392]: time="2021-08-27T06:41:42Z" level=info msg="Native sector size of block device /dev/mmcblk0p8 is 512 bytes. Mender will write in chunks of 1048576 bytes" func=github.com/mendersoftware/mender/installer.bdevice.Open file="/ ..
$ func templates list C# Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Durable Functions activity Durable Functions entity (class) Durable Functions entity (function) Durable Functions Entity HTTP starter Durable Functions HTTP starter Durable Functions orchestrator Azure Event Grid trigger Azure Event Hub trigger HTTP trigger IoT Hub (Event Hub) Kafka output Kafka trigger Azure Queue Storage trigger RabbitMQ trigger SendGrid Azure Service Bus Queue trigger Azure Service Bus Topic trigger SignalR negotiate HTTP trigger Timer trigger Custom Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Azure Event Grid trigger Azure Event Hub trigger HTTP trigger IoT Hub (Event Hub) Kafka trigger Azure Queue Storage trigger RabbitMQ trigger SendGrid Azure Service Bus Queue trigger Azure Service Bus Topic trigger SignalR negotiate HTTP trigger Timer trigger JavaScript Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Durable Functions activity Durable Functions entity Durable Functions Entity HTTP starter Durable Functions HTTP starter Durable Functions orchestrator Azure Event Grid trigger Azure Event Hub trigger HTTP trigger IoT Hub (Event Hub) Kafka output Kafka trigger Azure Queue Storage trigger RabbitMQ trigger SendGrid Azure Service Bus Queue trigger Azure Service Bus Topic trigger SignalR negotiate HTTP trigger Timer trigger PowerShell Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Durable Functions activity (preview) Durable Functions HTTP starter (preview) Durable Functions orchestrator (preview) Azure Event Grid trigger Azure Event Hub trigger HTTP trigger IoT Hub (Event Hub) Kafka output Kafka trigger Azure Queue Storage trigger SendGrid Azure Service Bus Queue trigger Azure Service Bus Topic trigger SignalR negotiate HTTP trigger Timer trigger Python Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Durable Functions activity Durable Functions entity Durable Functions HTTP starter Durable Functions orchestrator Durable Functions orchestrator Azure Event Grid trigger Azure Event Hub trigger HTTP trigger Kafka output Kafka trigger Azure Queue Storage trigger RabbitMQ trigger Azure Service Bus Queue trigger Azure Service Bus Topic trigger Timer trigger TypeScript Templates: Azure Blob Storage trigger Azure Cosmos DB trigger Durable Functions activity Durable Functions entity Durable Functions Entity HTTP starter Durable Functions HTTP starter Durable Functions orchestrator Azure Event Grid trigger Azure Event Hub trigger HTTP trigger IoT Hub (Event Hub) Kafka output Kafka trigger Azure Queue Storage trigger RabbitMQ trigger SendGrid Azure Service Bus Queue trigger Azure Service Bus Topic trigger SignalR negotiate HTTP trigger Timer trigger Powershell Templates: RabbitMQ trigger
# udhcpc -iwlan0 -A 1 -b udhcpc: started, v1.31.1 udhcpc: sending discover udhcpc: sending select for 192.168.1.100 udhcpc: lease of 192.168.1.100 obtained, lease time 86400 deleting routers route: SIOCDELRT: No such process adding dns 168.95.1.1 adding dns 168.95.192.1所以就..
# udhcpc -iwlan0 -A 1 -b 2>&1 | grep dns | sed 's/adding dns/nameserver/g' > /etc/resolv.conf看看對不對...
# cat /etc/resolv.conf nameserver 168.95.1.1 nameserver 168.95.192.1
#define B57600 0010001 #define B115200 0010002 #define B230400 0010003 #define B460800 0010004 #define B500000 0010005 #define B576000 0010006 #define B921600 0010007 #define B1000000 0010010 #define B1152000 0010011 #define B1500000 0010012 #define B2000000 0010013 #define B2500000 0010014 #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017有一堆高速baudrate 定義。
~/picocom$ git diff diff --git a/term.c b/term.c index 4abe6cd..66a72ee 100644 --- a/term.c +++ b/term.c @@ -637,6 +637,9 @@ term_set_baudrate (int fd, int baudrate) case 921600: spd = B921600; break; + case 1500000: + spd = B1500000; + break; #endif default: term_errno = TERM_EBAUD;其實就加上去就可以了。
transient error: update commit failed: statescript: The statescript version file is missing. This file needs to be present and contain a single number representing which version of the statescript support the client is using in order to successfully run statescripts on the client只好去找 source..
versionFilePath := filepath.Join(l.RootfsScriptsPath, "version") f, err := os.Open(versionFilePath) if err != nil && os.IsNotExist(err) { errmsg := "statescript: The statescript version file is missing. This file needs to be " + "present and contain a single number representing which version of the statescript " + "support the client is using in order to successfully run statescripts on the client" return errors.New(errmsg) } else if err != nil { return errors.Wrap(err, "statescript") } ver, err := readVersion(f) if _, ok := err.(readVersionParseError); ok { errmsg := "statescript: Failed to parse the version file in the statescript directory (%s). " + "The file needs to contain a single integer signifying which version of the statescript " + "support which this client is using" return fmt.Errorf(errmsg, err) }所以是需要一個叫 version 的 file,裡面是數字。
conf/paths.go: DefaultRootfsScriptsPath = path.Join(GetConfDirPath(), "scripts")應該就是 /etc/mender/scripts
transient error: update commit failed: statescript: unsupported scripts version: 0找到:
func NewStateScriptExecutor(config *conf.MenderConfig) statescript.Launcher { ret := statescript.Launcher{ ArtScriptsPath: config.ArtifactScriptsPath, RootfsScriptsPath: config.RootfsScriptsPath, SupportedScriptVersions: []int{2, 3}, ..把version內容由 0 改為 3 之後,果然就 ota OK 了,沒有 Error,但是 state script 以=也沒有執行....
func (l Launcher) get(state, action string) ([]os.FileInfo, string, error) { sDir := l.ArtScriptsPath if state == "Idle" || state == "Sync" || state == "Download" { sDir = l.RootfsScriptsPath } ...先看script 位置,依照 state 而有不同。
DefaultArtScriptsPath = path.Join(GetStateDirPath(), "scripts") DefaultRootfsScriptsPath = path.Join(GetConfDirPath(), "scripts") DefaultDataStore = "/var/lib/mender" func GetStateDirPath() string { return DefaultDataStore } func GetConfDirPath() string { return "/etc/mender" }所以 Idle, Sync, Download 是在 /etc/mender。
# ls /etc/mender/scripts/ ArtifactCommit_Enter_00 Download_Enter_00 Sync_Enter_00 ArtifactInstall_Enter_00 Download_Leave_01 version ArtifactReboot_Enter_00 Download_Leave_02每一個 script 都是在 /data/ 下 touch 自己的 filename.
date > /data/$(basename "$0")然後從 /data 就可以知道有哪些 script 有正確執行。
#!/bin/bash LIST="" for f in state_scripts/Artifact* do LIST="${LIST} -s ${f}" done echo ${LIST}
#!/bin/bash STR=`uname -a` SUB='Linux' if [[ "$STR" == *"$SUB"* ]]; then echo "It's there." fi但是在 busybox 的 shell 不支援,所以要用另一個語法:
#!/bin/bash STR=`uname -a` SUB='Linux' case $STR in *"$SUB"*) echo "It's there." ;; esac
mender-artifact write rootfs-image -f /mnt/root-part.ext4 \ -n artifact-name \ --software-version 1.0 \ -o snapshot-release.1.0.mender \ -t device-type就可以轉成上傳道 mender.io server 的 release 檔 (snapshot-release.1.0.mender)
USER="user" HOST="host-ip" mender snapshot dump --source /dev/mmcblk0p8 | ssh $USER@$HOST /bin/sh -c 'cat > $HOME/root-part.ext4`
mender -install /data/1234.mender一樣會更新到另一個 partition,然後呼叫 fw_setenv 來更新開機參數。
Plugin sudoers_policy /usr/lib/sudoers.so出現 Error:
sudo: error in /etc/sudo.conf, line 14 while loading plugin "sudoers_policy" sudo: unable to load /usr/lib/sudoers.so: /lib/libcrypt.so.1: version `XCRYPT_2.0' not found (required by /usr/lib/sudoers.so)
Ambarella sshd[14584]: /usr/sbin/sshd: relocation error: /usr/sb in/sshd: symbol EVP_KDF_ctrl version OPENSSL_1_1_1b not defined in file libcrypt o.so.1.1 with link time reference應該是系統原來就有 libcrypt,我用另一個版本覆蓋了導致。
./configure --enable-openssl=/home/pi/openssl --prefix=/home/pi/sudoinstall先 disable 全部..
--disable-shared Disable dynamic shared object support. By default, sudo is built with a plugin API capable of loading arbitrary policy and I/O logging plugins. If the --disable-shared option is specified, this support is disabled and the default sudoers policy and I/O plugins are embedded in the sudo binary itself. This will also disable the noexec option as it too relies on dynamic shared object support. --disable-shared-libutil Disable the use of the dynamic libsudo_util library. By default, sudo, the sudoers plugin and the associated sudo utilities are linked against a shared version of libsudo_util. If the --disable-shared-libutil option is specified, a static version of the libsudo_util library will be used instead. This option may only be used in conjunction with the --enable-static-sudoers option. --enable-static-sudoers By default, the sudoers plugin is built and installed as a dynamic shared object. When the --enable-static-sudoers option is specified, the sudoers plugin is compiled directly into the sudo binary. Unlike --disable-shared, this does not prevent other plugins from being used and the noexec option will continue to function.一樣,都 disable,也 disable openssl,結果一樣要 XCRYOT_2.0,只插在 /etc/sudo,conf 不用了。
PIL.UnidentifiedImageError: cannot identify image filegoogle 一下,有人說用
import os from PIL import Image folder_path = 'data\img' extensions = [] for fldr in os.listdir(folder_path): sub_folder_path = os.path.join(folder_path, fldr) for filee in os.listdir(sub_folder_path): file_path = os.path.join(sub_folder_path, filee) print('** Path: {} **'.format(file_path), end="\r", flush=True) im = Image.open(file_path) rgb_im = im.convert('RGB') if filee.split('.')[1] not in extensions: extensions.append(filee.split('.')[1])檢查 image 是不是合格。
Traceback (most recent call last):in/cats/666.jpg ** File "checkimage.py", line 10, in用 mediainfo 看 666.jpg,沒有內容。一看 file size 是 0im = Image.open(file_path) File "/home/charles-chang/miniconda3/envs/tensorflow-gpu/lib/python3.8/site-packages/PIL/Image.py", line 2967, in open raise UnidentifiedImageError( PIL.UnidentifiedImageError: cannot identify image file './cats_and_dogs_small/train/cats/666.jpg'
-Wdate-time Warn when macros "__TIME__", "__DATE__" or "__TIMESTAMP__" are encountered as they might prevent bit-wise-identical reproducible compilations.這個好像是為了 reproducible build。
config FEATURE_SUID_CONFIG bool "Enable SUID configuration via /etc/busybox.conf" default y depends on FEATURE_SUID help Allow the SUID/SGID state of an applet to be determined at runtime by checking /etc/busybox.conf. (This is sort of a poor man's sudo.) The format of this file is as follows: APPLET = [Ssx-][Ssx-][x-] [USER.GROUP] s: USER or GROUP is allowed to execute APPLET. APPLET will run under USER or GROUP (regardless of who's running it). S: USER or GROUP is NOT allowed to execute APPLET. APPLET will run under USER or GROUP. This option is not very sensical. x: USER/GROUP/others are allowed to execute APPLET. No UID/GID change will be done when it is run. -: USER/GROUP/others are not allowed to execute APPLET. An example might help: |[SUID] |su = ssx root.0 # applet su can be run by anyone and runs with | # euid=0,egid=0 |su = ssx # exactly the same | |mount = sx- root.disk # applet mount can be run by root and members | # of group disk (but not anyone else) | # and runs with euid=0 (egid is not changed) | |cp = --- # disable applet cp for everyone The file has to be owned by user root, group root and has to be writeable only by root: (chown 0.0 /etc/busybox.conf; chmod 600 /etc/busybox.conf) The busybox executable has to be owned by user root, group root and has to be setuid root for this to work: (chown 0.0 /bin/busybox; chmod 4755 /bin/busybox) Robert 'sandman' Griebl has more information here:
The panel encountered a problem while loading "BriskMenuFactory::BraskMenu".有時候重開機就好,有時候會不行。
mkdir out && cd out cpio -idv < ../initrd.img
mount -t proc none /proc之後 remount OK
exec chroot /rom /linuxrc這樣就可以了。
/bin/sh就會開進 shell 測試在這時候的 command 有沒有用。
#!/bin/sh mount -t proc none /proc mount -t tmpfs none /overlay mkdir /overlay/lower mkdir /overlay/upper mkdir /overlay/worker mkdir /overlay/newroot mount / /overlay/lower mount -o remount,ro /overlay/lower mount -t overlay overlay -olowerdir=/overlay/lower,upperdir=/overlay/upper,workdir=/overlay/worker /overlay/newroot exec chroot /overlay/newroot /linuxrc測試...開機後,在 / create abc, ls to see if exist.
overlay on / type overlay (rw,relatime,lowerdir=/overlay/lower,upperdir=/overlay/upper,workdir=/overlay/worker)大概是成功了。
mount: overlay on / type overlay (rw,noatime,lowerdir=/lower,upperdir=/upper/data,workdir=/upper/work)boot cmd:
$ cat /proc/cmdline coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 boot=overlay console=ttyS0,115200 console=tty1 root=PARTUUID=3661545e-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwai大概是:boot=overlay, root=UARTUUID...,rootfstype=ext4 之類。
charles-chang@beaver:~/test$ tree upper/ upper/ ├── dir │ └── g ├── e └── f 1 directory, 3 files charles-chang@beaver:~/test$ tree lower/ lower/ ├── a ├── b ├── dir │ ├── c │ └── d └── test用 mount command 把 upper 疊在 lower 之上,最後成為 'merged' 目錄:
sudo mount -t overlay overlay -olowerdir=./lower,upperdir=./upper,workdir=./work merged看看 merged 目錄:
tree merged/ merged/ ├── a ├── b ├── dir │ ├── c │ ├── d │ └── g ├── e ├── f └── test可以看到 upper 跟 lower合併在一起了。
make qemu_arm_vexpress_defconfig make qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel output/images/zImage -append "root=/dev/mmcblk0 console=ttyAMA0 loglevel=8" -dtb output/images/vexpress-v2p-ca9.dtb -sd output/images/rootfs.ext2 -nographic就可以用 root 登入。
qemu-system-x86_64 -s -kernel linux-4.9.263/arch/x86_64/boot/bzImage --append "console=ttyS0" -nographic
could not determine kind of name for C.X509_V_ERR_CA_KEY TOO_SMALL ...還有一堆 ssl 的 C.X509.
./makefile.sh -v --init --force --test dummy date ls ssh | | | List of allowed commands | User's login namem 然後就可以放在 /etc/passwd 中,讓那個 user login 後用那個 為他 build 的 shell
qemu-system-x86_64 -kernel ./bzImage -initrd ./rootfs.img.gz -nographic -append "console=ttyS0 root=/dev/ram init=/linuxrc"qemu default 會用 SDL,開啟 graphic console(雖然也是 console),所以要用 -nographic,然後加上 console=ttyS0,讓 console 從 ttyS0 到 command line console.
mount -o rw,remount /dev/root / touch /etc/passwd touch /etc/group adduser charles這樣,就可以su - charles,測試 root 和 charles (general user) 對 busybox command 的權限。
poweroff: (null): Operation no permitted但是,用 ip 來測試,一樣在 /sbin/ip。一樣說 not found,但是用 /sbin/ip 來執行,就可以正常執行了。
OpenCV has been built. You can find the header files and libraries in /usr/local/include/opencv2/ and /usr/local/lib"然後會 modify project 的相關build script/Makefile,把原來使用 package install path 的位置改道script 安裝的位置。
python3 -m venv mp_env && source mp_env/bin/activatemediapipe 用 pip 安裝就可以 ...
(mp_env)$ pip install mediapipe然後要用 python3
/proc/sys/net/ipv4/tcp_keepalive_timedefault 是 7200 (2hrs)。
net.ipv4.tcp_keepalive_time=1800* 注意內容表示和 /proc path 的關係,就是 /proc/sys 之後的 path,用 '.' 來代替。
// LoadVerifyLocations tells the context to trust all certificate authorities // provided in either the ca_file or the ca_path. // See http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html for // more. func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_ca_file, c_ca_path *C.char if ca_file != "" { c_ca_file = C.CString(ca_file) defer C.free(unsafe.Pointer(c_ca_file)) } if ca_path != "" { c_ca_path = C.CString(ca_path) defer C.free(unsafe.Pointer(c_ca_path)) } if C.SSL_CTX_load_verify_locations(c.ctx, c_ca_file, c_ca_path) != 1 { return errorFromErrorQueue() } runtime.KeepAlive(c) return nil }caller 是:
func loadServerTrust(ctx *openssl.Ctx, conf *Config) (*openssl.Ctx, error) { defaultCertDir, err := openssl.GetDefaultCertificateDirectory() if err != nil { return ctx, errors.Wrap(err, "Failed to get the default OpenSSL certificate directory. Please verify the OpenSSL setup") } sysCertsFound, err := nrOfSystemCertsFound(defaultCertDir) if err != nil { log.Warnf("Failed to list the system certificates with error: %s", err.Error()) } // Set the default system certificate path for this OpenSSL context err = ctx.SetDefaultVerifyPaths() if err != nil { return ctx, fmt.Errorf("Failed to set the default OpenSSL directory. OpenSSL error code: %s", err.Error()) } // Load the server certificate into the OpenSSL context err = ctx.LoadVerifyLocations(conf.ServerCert, "") if err != nil { if strings.Contains(err.Error(), "No such file or directory") { log.Warnf(errMissingServerCertF, conf.ServerCert) } else { log.Errorf("Failed to Load the Server certificate. Err %s", err.Error()) } // If no system certificates, nor a server certificate is found, // warn the user, as this is a pretty common error. if sysCertsFound == 0 { log.Error(errMissingCerts) } } return ctx, err }
write 64h in CTRL1(20h) write 04h in CTRL6(25h) write 20h in CTRL7(3fh) write 00h in WAKE_UP_DUR(35h) write 02h in WAKE_UP_THS(34h) write 20h in CTRL4_INT1_PAD_CTRL(23h)還有一個用USER OFFSET 做srce 的設定範例,採用 X-0. Y-0. Z-02 之後,大於 threshold 之後產生 interrupt (因為 duration 0)
write 04h in CTRL6(25h) write 34h in CTRL7(35h) write 00h in X/Y_OFS_USR(3ch,3dh) write 40h in Z_OFS_USR(3eh) write 00h in WAKE_UP_DUR(35h) write 02h in WAKE_UP_THS(34h) write 20h in CTRL4_INT1_PAD_CTRL(23h) write 64h in CTRL1(20h)發現 官方的 input driver 沒有宣告 CTRK7(3fh).
[ 0.945939] lis2dwi2c w 21 4c [ 0.949619] lis2dwi2c w 20 1 [ 0.953205] lis2dwi2c w 22 10 [ 0.956880] lis2dwi2c w 21 c [ 0.960467] lis2dwi2c w 36 1 [ 0.964054] lis2dwi2c w 36 9 [ 0.968054] lis2dwi2c w 30 9 [ 0.971642] lis2dwi2c w 34 2 [ 5.170523] lis2dwi2c w 20 11 [ 5.175374] lis2dwi2c w 20 51enable input4/wake_up/enable 的話..
[ 198.030489] lis2dwi2c w 23 20所以wakeup需要的幾乎都沒設
7 6 5 4 3 2 1 0 ----------------------------------------------------------------------------------------------- STATUS | 27h | FIFO_THS | WU_IA | SLEEP_STATE | DOUBLE_TAP | SINGLE_TAP | 6D_IA | FF_IA | DRDY |在sysfs input4/wake_up 下增加一個 regv
# echo 1 > enable [ 161.304567] --lis2dw12_enable_sensors-- [ 161.308934] --lis2dw12_update_drdy_irq-- [ 161.313552] lis2dwi2c w 23 20 [ 161.317201] lis2dwi2c w 20 64 [ 161.320851] lis2dwi2c w 25 4 [ 161.324128] lis2dwi2c w 3f 20 [ 161.327782] lis2dwi2c w 35 0 [ 161.331009] lis2dwi2c w 34 2 [ 161.334305] lis2dwi2c w 23 20 # # cat regv 1 # cat regv 0 # cat regv 1 # cat regv 0 ----- 敲打機器 ---- # cat regv 41 # cat regv 40WU_IA bit set,所以應該 OK
# cat /etc/systemd/system/runmyshutdown.service [Unit] Description=Run my custom task at shutdown DefaultDependencies=no Before=shutdown.target [Service] Type=oneshot ExecStart=/usr/local/bin/myshutdown.sh TimeoutStartSec=0 [Install] WantedBy=shutdown.target還有測試的 script:
# cat /usr/local/bin/myshutdown.sh #!/bin/bash /bin/touch /data/sssss然後..
# systemctl daemon-reload # systemctl enable runmyshutdown Created symlink /etc/systemd/system/shutdown.target.wants/runmyshutdown.service → /etc/systemd/system/runmyshutdown.service.原來沒有 /etc/systemd/system/shutdown.target.wants 這個目錄。
static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, lis2dw12_get_enable, lis2dw12_set_enable);然後..
static struct attribute *lis2dw12_accel_attribute[] = { &dev_attr_enable.attr, &dev_attr_resolution.attr, &dev_attr_polling_rate.attr, &dev_attr_scale_avail.attr, &dev_attr_scale.attr, NULL, }; static struct attribute *lis2dw12_step_ff_attribute[] = { &dev_attr_enable.attr, NULL, }; static struct attribute *lis2dw12_tap_attribute[] = { &dev_attr_enable.attr, NULL, }; static struct attribute *lis2dw12_double_tap_attribute[] = { &dev_attr_enable.attr, NULL, }; static struct attribute *lis2dw12_wakeup_attribute[] = { &dev_attr_enable.attr, NULL, };可以看到,所有 inputX 的 attrib enable 都共用 function : lis2dw12_set_enable( )
7 6 5 4 3 2 1 0 ------------------------------------------------------------------------------------------------ | INT1_6D | INT1_SINGLE_TAP | INT1_WU | INT1_FF | INT1_TAP | INT1_DIFF5 | INT1_FTH | INT1_DRDY | ------------------------------------------------------------------------------------------------其中,INT1_WU 就是 wake up
static int lis2dw12_update_drdy_irq(struct lis2dw12_sensor_data *sdata) { u8 reg_addr = LIS2DW12_CTRL4_INT1_PAD_ADDR, reg_val, reg_mask; switch (sdata->sindex) { case LIS2DW12_FF: case LIS2DW12_TAP: case LIS2DW12_DOUBLE_TAP: case LIS2DW12_WAKEUP: reg_val = lis2dw12_event_irq1_value(sdata->cdata); reg_mask = LIS2DW12_INT1_EVENTS_MASK; break; case LIS2DW12_ACCEL: return 0; default: return -EINVAL; } return lis2dw12_write_data_with_mask(sdata->cdata, reg_addr, reg_mask, reg_val >> __ffs(reg_mask), true); }所以driver 中,Wakeup 的 threshold, duration 都是hard-code,不是 configurable.
#define LIS2DW12_WAKE_UP_THS_WU_MASK 0x3f #define LIS2DW12_WAKE_UP_THS_WU_DEFAULT 0x02 static int lis2dw12_init_sensors(struct lis2dw12_data *cdata) { ... err = lis2dw12_write_data_with_mask(sdata->cdata, LIS2DW12_WAKE_UP_THS_ADDR, LIS2DW12_WAKE_UP_THS_WU_MASK, LIS2DW12_WAKE_UP_THS_WU_DEFAULT, true);這個 write_data_with_mask( )就是 read, mask, update 的動作。
All the embedded function interrupt signals are subordinate to the INTERRUPTS_ENABLE bit in register CTRL7. If this bit is set, the embedded functions are enabled and the interrupts signals can be routed to the INT1 and/or INT2 pins; otherwise, if this bit is not set, the embedded functions are disabled可是 source code 中沒有看到CTRL7 的宣告,也沒有設定。(除非 reset value 是 SET)