2022/9/29

Compile.h Error on building kernel w clang

./include/generated/compile.h:7:24: warning: missing terminating '"' character [-Winvalid-pp-token]
#define LINUX_COMPILER "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)
                       ^
./include/generated/compile.h:8:1: error: unknown type name 'Found'
去看 error source,是在 kernel source 里:
kernel-4.19/include/generated/compile.h
在產生 compile.h 的時候...
#define LINUX_COMPILER "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)
Found CUDA installation: /usr/local/cuda, version 11.0, LLD 12.0.5 (/buildbot/src/android/llvm-toolchain/out/llvm-project/lld c935d99d7cf2016289302412d708641d52d2f7ee)"
define 不支援斷行...

init/Makefile:
   $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@   \
    "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)"    \
    "$(CC) $(KBUILD_CFLAGS)" "$(LD)"
然後 mkcompile_h 中:
TARGET=$1
ARCH=$2
SMP=$3
PREEMPT=$4
CC=$5
LD=$6

..

( echo /\* This file is auto generated, version $VERSION \*/
  if [ -n "$CONFIG_FLAGS" ] ; then echo "/* $CONFIG_FLAGS */"; fi

  echo \#define UTS_MACHINE \"$ARCH\"

  echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"

  echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
  echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"

  CC_VERSION=$($CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//')
  LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \
              | sed 's/[[:space:]]*$//')
  printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION"
) > .tmpcompile
這個script 在 kernel 5.X 之後由 Kconfig 取代了。

測試一下 CC_VERSION 的產生: $CC -v
Android 這邊是用 prebuild 內的 clang。
執行結果:
prebuilts/clang/host/linux-x86/clang-3289846$ bin/clang -v
Android clang version 3.8.275480  (based on LLVM 3.8.275480)
Target: x86_64-unknown-linux
Thread model: posix
InstalledDir: /home/charles-chang/Android12/prebuilts/clang/host/linux-x86/clang-3289846/bin
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
Found CUDA installation: /usr/local/cuda, version unknown
果然出現 CUDA,因為也有 version 字樣,所以有出現在後面的 grep 結果。

所以把 grep ' version ' 改 'clang version ' 試試...
好像 OK, compile.h 有問題的部份變成...
#define LINUX_COMPILER "Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee), LLD 12.0.5 (/buildbot/src/android/llvm-toolchain/out/llvm-project/lld c935d99d7cf2016289302412d708641d52d2f7ee)"
--- 但是要是不是用 clang 就會 fail 吧...
改只取line 1 好了...
kernel-4.19$ git diff
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 19de4cdef1ec..b1e1d7540b9c 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -73,7 +73,7 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
   echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
   echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"
 
-  CC_VERSION=$($CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//')
+  CC_VERSION=$($CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//' | head -n 1)
   LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \
                      | sed 's/[[:space:]]*$//')
   printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION"

intel I219 NIC, ubuntu 20.04

這個 PCI NIC 要到 22.04 才有support,所以這版只能自己 build。
intel 官網有 source code,但是是手動,所以要是kernel 更新,就要手動 build 一次。
所以依照網路說,用dkms support 版
依照說明,copy source 到 /usr/src 後,用 dkms command 做
cp -r e1000e-dkms/usr/src/e1000e-3.8.7 /usr/src/
dkms add -m e1000e -v 3.8.7
dkms build -m e1000e -v 3.8.7
dkms install -m e1000e -v 3.8.7
這樣build 完,手動 modprobe e1000e,就可以用 dhcpclient 取得 IP

但是,開機後不會自動 load..
所以參考這一篇,新增:
$cat /etc/modoprobe.d/e1000e.conf
e1000e
這樣開機就會自動 load 了,
剩下不會自動取得 IP,所以參考這一篇,修改 /etc/netplan/00-instale-config.yaml
network:
 ethernets:
   eno1:
     dhcp4: true
   version: 2
這樣就 OK 了。


另外,這一篇 說明從 intel source code 改成 dkms 的方法。

2022/9/27

Dockerfile : FROM scratch

就是一個空的,什麼都沒有的 base image。
所以如果要用來 run 自己的 program,一定要是 static linked。
最好的說明就是docker 的hello-world image。
clone 下來以後,到 amd64/hello-world 看,就是做出 hello-world image 的 程式(hello) 和 Dockerfile。
用 file 來看 hello ,就是 statically linked, executable program

Dockerfile 就很簡單:
FROM scratch
COPY hello /
CMD ["/hello"]
然後 build image:
docker build -t myhello . --no-cache
run image:
docker run myhello

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
這個 image 很小,就跟 hello 一樣大:
docker images
EPOSITORY                              TAG                            IMAGE ID       CREATED          SIZE
myhello                                 latest                         03cc4ebe3142   48 seconds ago   13.3kB

ls -l hello 
-rwxrwxr-x 1 charles-chang charles-chang 13256 Sep 27 15:55 hello


另一個,簡單,用 go 做 example。一樣的 hello :building minimal docker image for go application

main.go:
package main

import (
	"fmt"
	"time"
)

func main() {
	for {
		fmt.Println("Hello World!")
		time.Sleep(1 * time.Second)
	}
}
build for static:
$CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main
然後Dockerfile 一樣:
FROM scratch
ADD main /
CMD ["/main"]
然後就跟上面一樣,build image, run ....


以前好像寫過,go cross build 好方便,上面那個 GOARCH=arm64 就是 build for aarch64

2022/9/13

create, mount veracrypt sd partition in device.

在 pi 上 build 好 static linked veracrypt 後,放到 target board 上 ,先測試 mount 已經 create 好的 partition:
# /data/veracrypt /dev/mmcblk1p1 /sd
Enter password for /dev/mmcblk1p1: 
Enter PIM for /dev/mmcblk1p1: 
Enter keyfile [none]: 
Protect hidden volume (if any)? (y=Yes/n=No) [No]: 
Error: No such file or directory:
dmsetup

VeraCrypt::Process::Execute:88
意思是需要 dmsetup 這個 tool。是 device-mapper tool

另外,這個 Error:
Error: /dev/mapper/control: open failed: No such device
Failure to communicate with kernel device-mapper driver.
Check that device-mapper is available in the kernel.
Incompatible libdevmapper 1.02.167 (2019-11-30) and kernel driver (unknown version).
Command failed.
是 kernel 沒有 DEVICE-MAPPER support
Device Driver -- Multiple device driver support(RAID and LVM) -- Device mapper support -- Crypt target support
mount OK. 做 dd test:
# dd if=/dev/zero of=./100M bs=1000000 count=100
100+0 records in
100+0 records out
100000000 bytes (95.4MB) copied, 19.239889 seconds, 5.0MB/s
和沒有用 veracrypt 的 sd card 比較:
# dd if=/dev/zero of=./100M bs=1000000 count=100
100+0 records in
100+0 records out
100000000 bytes (95.4MB) copied, 18.150534 seconds, 5.3MB/s
至於 cpu useage,用 uptime 來看,沒有差別。


Create encrypted partition
ref: command:
# /data/veracrypt -t -c --volume-type=normal /dev/mmcblk1p1 --encryption=aes --hash=sha-512 --filesystem=fat -p 12345 --pim=0 -k "" --random-source=/dev/urandom

Done: 100.000%  Speed: 5.3 MiB/s  Left: 0 s                

The VeraCrypt volume has been successfully created.
非常慢...2G 的 card 花了10 min..
查到有 --qick 做 quick format.. 測試..
# /data/veracrypt -t -c --volume-type=normal /dev/mmcblk1p1 --encryption=aes --hash=sha-512 --filesystem=fat -p 12345 --pim=0 -k "" --random-source=/dev/urandom --quick

Done: 100.000%  Speed: 115 MiB/s  Left: 0 s             

The VeraCrypt volume has been successfully created.
大概 15sec..

mount
# /data/veracrypt -p 12345 --pim=0 -k "" --protect-hidden=no /dev/mmcblk1p1 /sd
大概要 10sec.

這樣 create 出來的 disk 在 windows 系統,可以使用 veracrypt mount 起來。 read.write OK

2022/9/12

static build VeraCrypt for aarch64

用 cryptsetup 可以 open veracrypt disk/partiton,但是不能 create veracrypt disk/partition。
必須要安裝 veracrypt,但是 veracrypt 沒有在 distibution 中。
要加 ppa,或是 build from source..

需要 yasm, libfuse-dev,
在 aarch64 pi 上面 build 就跟在 x86 上 build 一樣。
就算是只要 console 板,也需要 wxWindows。
所以依照 官方說明,可以download wxWindows 3.0 (.5) source 下來,解開。veracrypt Makefile 會包含 build 他的 instruction。
所以先 build wxWindwos 再 build veracrypt 就可以:
cd src
make NOGUI=1 WXSTATIC=1 WX_ROOT=~/wxWidgets-3.0.5 wxbuild
make NOGUI=1 WXSTATIC=1
結果就會在 src/Main/veracrypt

如果要 build static linked program,可以修改 src/Makefile,在 一開始的 LFLAGS 加上 -static
export LFLAGS := -static
再 build 就可以。

要注意的是,因為 .gitignore 有把一些 build, config 的 file 加入 ignore。
但是make 得時候又會參考,
所以 change option 時,make clean 沒辦法完全清乾淨,導致會有make error。

test build Tag: VeraCrypt_1.25.9 OK

mount veracrypt partitoin in linux

因為 windows 沒有辦法 mount luks partition/disk。
在 windows 上做 disk /partition encryption 就只有 support truecrypt,對應的 application (open-sourced) 就是 veracrypt
反過來,在 linux 上mount veracrypt encrypt 的 sd card..

參考:
~$ sudo cryptsetup --type tcrypt --veracrypt open <device> <name> 
先把 sd card create 好 partition。

參考veracrypt 說明:
create Volume -- create none-system partition/drive -- standard veracrypt volume -- volume location (select sd card drive name) -- created encrypted volume and format it -- Encryption Algorithm AES, Hash Algorithm SHA-512 -- volume size -- password

這樣就 create 好了一個 trucrypted partition。
可以用 veracrypt -- Mount 功能,mount 進 windows driver。

在 linux 上,可以用上面的
cryptsetup --type tcypt --veracrypt open /dev/sdb1 mysd
輸入 password 後,會出現在 /dev/mapper/mysd
然後:
mount /dev/mapper/mysd /sd
就會在 /sd 下看到了。

mount luks disk in wsl

ref: 大概就是:
要 windows 11,先在 powershell 下把 volume mount bare 給 wsl,這樣wsl 就看得到partition/disk 了。
然後在 wsl 下用一般 mount command 來 mount (所以也可以用 cryptsetup..)

依照 ref:How to mount a LUKS encrypted drive in Windows:

在 powershell :
C:\Users\miguel> GET-WMIOBJECT -query "SELECT * from Win32_DiskDrive"
列出所有的 disk, partition.(的name),然後選要給 wsl 的,做:
PS C:\Users\miguel> wsl --mount \\.\PHYSICALDRIVE1 --bare
然後到 wsl 的 linux(debian, ubuntu) 下:
$ lsblk
就可以看到剛剛給 wsl 的 disk 了,之後就用一般 linux 的 command:
$ sudo cryptsetup luksOpen /dev/sdc1 TOSHIBA2TB
$ sudo mount /dev/mapper/TOSHIBA2TB /mnt/TOSHIBA2TB/