2025年1月31日金曜日

WSL Ubuntuのイメージを好きな場所に移動したときにrootでログインされてしまう問題

 

WSL Ubuntuのイメージを好きな場所に移動したときにrootでログインされてしまう問題


2025.02.01
WSLのUbuntuのバージョンを24.04にしたくて、これまで愛用してきた22.04のバックアップを取って24.04にした。その手順はおおむねこちら(WSLでもう一つのDebian)のとおり。
22.04を削除して
一旦24.04をStoreからインストールして
一旦起動してユーザー名とパスワードを入れて使える状態にして
バックアップ
cd C:\Users\hoge\Documents\wsl
wsl --export Ubuntu-24.04 Ubuntu-24_04_1LTS_justinstalled_20250201.tar
登録を解除
wsl --unregister Ubuntu-24.04
再登録
wsl --import Ubuntu-24.04 C:\Users\hoge\Documents\wsl C:\Users\hoge\Documents\wsl\Ubuntu-24_04_1LTS_justinstalled_20250201.tar
で、これでUbuntu-24.04のディスクイメージを見えやすい場所に移せた。
わけなんだけど、この後Windowsターミナルを起動して、タブの部分からUbuntu-24.04を起動すると、rootでログインした状態でUbuntuが起動しちゃう。これって既知なんだけど、この後、config --default-userをどうやればいいのか全然わからん。PSでUbuntu-24.04 config --default-user hogeでいけそうなのに。Ubuntu-24.04の部分をubuntuとかubuntu2404とか色々試したけどだめ。で、結局、Windows Terrminalの設定で
こんなことしちゃった。
だれかー正解を教えてほしい

Go言語入門(3)

 

興味本位でGo言語に触れてみようと思う。Linuxで32bit実行ファイルを生成して32bit shared libraryを呼び出すってしてみる。


まず32bit shared libraryを生成せんと動作確認できないので、32bit shared libraryつくる。まずは32bitでビルドできる環境を用意せんといかんのだが、
sudo apt-get install gcc-multilib
sudo apt-get install g++-multilib
でいいらしい。
で、コンパイルとリンク時に-m32をオプションとして与えんといかんので、Makefileをいじる
Makefile
  1. CC = gcc
  2. CFLAGS = -m32 -fPIC -O4 -Wall -I/usr/local/include
  3. LDFLAGS+= -m32 -shared -Wl,--version-script,libkeeloq.map
  4. #LDFLAGS= -shared -static-libgcc -static-libstdc++ -Wl,--version-script,libkeeloq.map -o libkeeloq.so
  5. libkeeloq.so: keeloq.o
  6.     $(CC) keeloq.o $(LDFLAGS) -o libkeeloq.so
  7.  
  8. keeloq.o: keeloq.c
  9.     $(CC) $(CFLAGS) keeloq.c -c -o keeloq.o
  10.  
  11. clean:
  12.     rm keeloq.o libkeeloq.so
で、make
make clean
make
で、テスト用コードをコンパイルして実行。
rm a.out
gcc -m32 keeloq_call.c
./a.out
と、こうなる
ので、実行できてるんやけど、これが本当に32bitかどうか、、、
file -e elf a.out
file -e elf libkeeloq.so
ってやればいいらしい。で、
こうなるので、うまくいっているはず。
で、Goで32ビットアプリを生成するには、、、これが、なかなかわからんかったけど、こうやる
CGO_ENABLED=1 GOOS=linux GOARCH=386 go run callshared32.go
GOOSとGOARCHを設定するってのはすぐに見つかるんだけど、CGO_ENABLEDはなかなか見つからんかった。これ指定しないと、
go: no Go source files
っていう本当に理解できないエラーが返される。、、、こんなんダメやろって思うんやけど、、、
で、こうなる。
buildもしてみる。
まぁ、うまくいっているね。
Goはクロスコンパイルが簡単だってどっかに書いてあったけど、なぞの呪文系は情報が錯綜しがちなのでやっかいなんよね、、、

そういっても、モノ相手なので、いつか解決してスッキリする。ヒト相手に困惑するのよりぜんぜん平気。エブリデーエンジニアになりたい。

Go言語入門(2)

 

興味本位でGo言語に触れてみようと思う。Linuxのshared libraryを呼び出してみる。


では、まずshared libraryを作るんだけど、以前作ったkeeloqでやってみる。こちら(https://sunday-engineer.jimdofree.com/2023/09/08/keeloq%E3%82%92%E9%A1%8C%E6%9D%90%E3%81%ABlinux%E5%85%B1%E6%9C%89%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA/)
まぁそれは出来るっていう体で
mkdir callshared
cd callshared
mkdir keeloq
cd keeloq
で、こちらにkeeloqのshared libraryを作って、で、念のため、Cからcallしてみる。

keeloq_call.c
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <dlfcn.h>
  4. typedef uint32_t (*keeloq_enc_type)(uint32_t pr,uint64_t kr);
  5. typedef uint32_t (*keeloq_dec_type)(uint32_t cr,uint64_t kr);
  6. void* dll;
  7. keeloq_enc_type keeloq_enc;
  8. keeloq_dec_type keeloq_dec;
  9.  
  10. int main(int argc,char** argv){
  11.     uint32_t pr=0xf741e2db;
  12.     uint64_t kr=0x5cec6701b79fd949;
  13.     uint32_t cr;
  14.     dll=dlopen("./libkeeloq.so",RTLD_LAZY);
  15.     keeloq_enc=(keeloq_enc_type)dlsym(dll,"keeloq_enc");
  16.     keeloq_dec=(keeloq_dec_type)dlsym(dll,"keeloq_dec");
  17.  
  18.     cr=keeloq_enc(pr,kr);
  19.     printf("%08X\n",cr);
  20.     pr=keeloq_dec(cr,kr);
  21.     printf("%08X\n",pr);
  22.     return 0;
  23. }
で、
gcc keeloq.c
./a.out
まぁ、うまくいきます。
では、
cd ..
で、Goのコードを書く。
ちなみに、treeするとこういう状態。(pythonのテストコードとかもあったりする;)

  • callshared
  • ├── callshared.go
  • └── keeloq
  •     ├── Makefile
  •     ├── a.out
  •     ├── keeloq.c
  •     ├── keeloq.o
  •     ├── keeloq_call.c
  •     ├── keeloq_call.py
  •     ├── libkeeloq.map
  •     └── libkeeloq.so

callshared.go
  1. package main
  2.  
  3. /*
  4. #cgo LDFLAGS: -ldl
  5. #include <dlfcn.h>
  6. #include <stdint.h>
  7. uint32_t call_func(void* p,uint32_t a,uint64_t b){
  8.     uint32_t (*func)(uint32_t a, uint64_t b) = p;
  9.     return func(a, b);
  10. }
  11. */
  12. import "C"
  13. import "fmt"
  14. func main() {
  15.     var pr C.uint32_t
  16.     var cr C.uint32_t
  17.     var kr C.uint64_t
  18.     pr = 0xf741e2db
  19.     kr = 0x5cec6701b79fd949
  20.     dll := C.dlopen(C.CString("./keeloq/libkeeloq.so"), C.RTLD_LAZY)
  21.     if dll == nil {
  22.         panic("Failed to open shared object.")
  23.     }
  24.     defer C.dlclose(dll) //<--これ意味わからんのよね
  25.     keeloq_enc := C.dlsym(dll, C.CString("keeloq_enc"))
  26.     if keeloq_enc == nil {
  27.         panic("Could not found function pointer.")
  28.     }
  29.     keeloq_dec := C.dlsym(dll, C.CString("keeloq_dec"))
  30.     if keeloq_dec == nil {
  31.         panic("Could not found function pointer.")
  32.     }
  33.     cr = C.call_func(keeloq_enc, pr, kr)
  34.     fmt.Printf("%08X\n", cr)
  35.     pr = C.call_func(keeloq_dec, cr, kr)
  36.     fmt.Printf("%08X\n", pr)
  37. }
これってcgoってのを利用しているらしい。コメントの中の記述に従って動作している。powershellがC#のコードを実行できるのと似ている。なんか変な感じだけどね。コメントの中のC記述とimport "C"は行をあけずにぴったりひっつけてないとダメらしい。コメントの中では関数ポインタとその関数の引数を引数として受け取って、関数ポインタで指示された関数を実行して結果を戻している。今回は2つの関数をcallしているけど、型が同じなので記述を共用している。
で、
go run callshared.go
って感じで、Cでやった結果とおんなじになりました。
いきなりshared libraryをcallするってGoやる気あるんか?って?、、、うむぅ

2025年1月30日木曜日

Go言語入門(1)

 

興味本位でGo言語に触れてみようと思う。Linuxへのインストールから複数ファイルのプロジェクトのビルドまで。

で、環境はUbuntuでやるけど、WSL Ubuntuでも同じかなと思う。インストールはここ(https://go.dev/doc/install)に書いてあるけど、まぁSynapticとかaptとかでやっちまっていいや。
sudo apt install golang
はい。超簡単。
で、フォルダ作って、
mkdir -p go/hello
cd go/hello

hello.go
  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main(){
  6.     fmt.Println("hello Go world")
  7. }
で、実行
go run hello.go
で、実行ファイル作るには
go build hello.go
って感じで、実行ファイルができて、ちゃんと実行できる。
で、余談というか、きっと後で苦しむこととして、複数ファイルのプロジェクトについて、情報が少ないので、まとめておく。
somefilesってフォルダをプロジェクトのフォルダとして、この下にいくつかのフォルダとコードを入れていくって考える。somefilesフォルダに移動して、go.modファイルを作る。
mkdir -p go/somefiles
cd go/somefiles
go mod init somefiles
フォルダ名と同じである必要があるかはわからん。で、go.modってファイルができる。これはこのまま。いじらなくていい。

go.mod
  1. module somefiles
  2.  
  3. go 1.22.2

で、サブフォルダにコードを作成する。subfolderフォルダにfile1.goを作るってことにする。

subfolder/file1.go
  1. package subfolder    //パッケージ名はフォルダ名と同じにする
  2.  
  3. import (
  4.     "fmt"
  5. )
  6.  
  7. func SayHello() {
  8.     fmt.Println("Hello from file1 in subfolder.")
  9. }
気をつけなきゃいけないことをソースコード内に記述してある。それと、publicな関数は関数名を大文字ではじめるらしい。

で、メインのコードmain.goはこうする。

main.go
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "somefiles/subfolder"    //現在のフォルダーからサブフォルダまでのパス
  6. )
  7.  
  8. func main() {
  9.     fmt.Println("Hello Go world!")
  10.     subfolder.SayHello()    //SayHello関数を定義しているファイルに記述されているパッケージ名
  11. }

で、今こんな感じになっている。
  • somefiles
  • ├── go.mod
  • ├── main.go
  • └── subfolder
  •     └── file1.go

で、実行する。
go run main.go
できた。
実行ファイルを作成してみる。
go build main.go
実行ファイルできて、実行できた。実行ファイル名はソースコード名になるっぽい。<--これをビルド時に強制的に変更する方法がわからん。ところで、go.modファイルって存在している意味が分からん。外部mod使う場合に必要になるっぽいけど、、、今回の例では、、、
ちなみに、同じmainパッケージでファイルを分割する場合は、もっと簡単で、これはwebのあちこちに記述があるので省略。

2025年1月24日金曜日

XIAO nRF52840で加速度センサデータを飛ばす(3)

加速度センサの計測結果をBLEで飛ばすっていう試み。XIAO nRF52840と秋月AE-ADXL367を使って。

 

で、nRF52840で飛ばしたデータをWindowsで受信する方法について考えてみる。
こちらのサイト(https://coskxlabsite.stars.ne.jp/html/for_students/iot/XIAOESP32S3/ESP32S3BLEServer_WinPC.html)に掲載のBLE_serial_terminalを使ってログ採って後でデータを解析するってんで十分なんだけど、データをすぐ見たい、とか、本当にリアルタイムでデータを収集しているのを見たいとか、いろんなことを要求されることあるよね、、、で、なんでWindowsなのかというと、AndroidでBLE受信とかはまぁまぁやってる人が多いので、まぁなんていうか、後で考えようって。で、まぁやってみるわけだよ、そすっと、
dotnet new console
で、Program.csに
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
って入れようもんなら、
ってな感じで、怒られちゃう( •̥ࡇ•̥ )で、こっから年をまたいだ格闘があったわけで(すまソ、ちょっとだらだらしてただけ)、で結局、 csprojファイルのTargetFrameworkを変えちゃえばいいっていう結論に達した、、、Visual Studio Community Edition入れてUWPアプリとして作るってのが正攻法っぽいけど、Visual Studio Community EditionのLicense Termsがいやだから使いたくないんよね、、、エンタープライズではほぼ教育以外の目的では使ってはいけないように読み取れる。つまりエンタープライズでは実用アプリをVisual Studio Community Editionで作ってはいけない<--これは明確に書いてある。こちら
こういうのがプログラミングの裾野の拡大を妨げていると思う。ちと考えろやB111 6A7E5 <(`^´)>
で、日曜技術者活動は完全に個人の趣味だけど、誠に勝手ながらエンタープライズの社員によるトレースをすら想定しています(’-’)なので、VS Community Editionは使わない。
本筋に戻ると、
    <targetframework>net8.0</targetframework>

    <targetframework>net6.0-windows10.0.22000.0</targetframework>
ってする。、、、様々な検討の結果がこれよ┐(´∀`)┌
んでもって、こんな感じにする。

study2.csproj
  1. <Project Sdk="Microsoft.NET.Sdk">
  2.  
  3.   <PropertyGroup>
  4.     <OutputType>Exe</OutputType>
  5.     <TargetFramework>net6.0-windows10.0.22000.0</TargetFramework>
  6.     <ImplicitUsings>enable</ImplicitUsings>
  7.     <Nullable>enable</Nullable>
  8.   </PropertyGroup>
  9.  
  10. </Project>

Program.cs
  1. //using System;
  2. //using System.Collections.Generic;
  3. //using System.Collections.ObjectModel;
  4. //using System.Linq;
  5. //using System.Threading.Tasks;
  6. using Windows.Devices.Bluetooth;
  7. using Windows.Devices.Bluetooth.Advertisement;
  8. using Windows.Devices.Bluetooth.GenericAttributeProfile;
  9.  
  10. namespace BLEScanner{
  11.     class Program{
  12.         static Dictionary<ulong, (string Name,string LocalName, string Uuid)> BleDevices = new Dictionary<ulong, (string Name, string LocalName,string Uuid)>();
  13.         static async Task Main(string[] args){
  14.             var watcher = new BluetoothLEAdvertisementWatcher();
  15.             watcher.Received += OnAdvertisementReceived;
  16.             watcher.ScanningMode = BluetoothLEScanningMode.Active;
  17.             watcher.Start();
  18.             //Console.WriteLine("Scanning for BLE devices... Press Enter to exit.");
  19.             //Console.ReadLine();
  20.             Console.WriteLine("Scanning for BLE devices in 30sec...");
  21.             await Task.Delay(30000);
  22.             watcher.Stop();
  23.  
  24.             foreach(var bledev in BleDevices){
  25.                 Console.WriteLine($"{bledev.Key} : {bledev.Value}");
  26.             }
  27.         }
  28.         private static async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args){
  29.             var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
  30.  
  31.             if (device != null){
  32.                 string deviceName = string.IsNullOrEmpty(device.Name) ? "Unknown" : device.Name;
  33.                 string deviceLocalName = string.IsNullOrEmpty(device.Name) ? "Unknown" : args.Advertisement.LocalName;
  34.                 string deviceUuid = await GetDeviceUuid(device);
  35.                 BleDevices.TryAdd(device.BluetoothAddress,(deviceName,deviceLocalName, deviceUuid));
  36.                 //Console.WriteLine($"Found device: {deviceName} -{deviceLocalName}- ({device.BluetoothAddress}) with UUID: {deviceUuid}");
  37.             }
  38.         }
  39.         private static async Task<string> GetDeviceUuid(BluetoothLEDevice device){
  40.             var services = await device.GetGattServicesAsync();
  41.             if (services.Status == GattCommunicationStatus.Success){
  42.                 var service = services.Services.FirstOrDefault();
  43.                 return service?.Uuid.ToString() ?? "UUID not found";
  44.             }
  45.             return "UUID not found";
  46.         }
  47.     }
  48. }
BLEをScanするのはもうあっちこっちに似たようなのがあって、どれを参考にしたのかわからなくなった。で、見つかったデバイスをリスト化するにあたってはDictionaryにBLE Address/Name/service uuidを追加していくってして、同じのがあったらはじかれるのを利用して重複を回避している。まぁ1つのデバイスで複数のservice uuidを持っていることもあるんだけど、そういうのは後で考える、、、
Bad programmers worry about the code. Good programmers worry about data structures and their relationships.(Linus Torvalds)
↑日曜技術者はプログラマーではないのでごめんなさい
んでもって、実行するとこうなる
たぶんうまくいっている。
そんでもって、じゃぁnRF52840が飛ばしているデータを取ろうじゃないか、、、ServiceUUIDとCharacteristicUUIDを指定してとるってなら簡単なんだけど、最終的には固定値で指定するとしても、こいつらをリストアップするのもできんといかんやん?で、ムズイていうよりクソメンドクサイ。
で、結局こんな感じ
  1. //using System;
  2. //using System.Collections.Generic;
  3. //using System.Collections.ObjectModel;
  4. //using System.Linq;
  5. //using System.Threading.Tasks;
  6.  
  7. using Windows.Devices.Bluetooth;
  8. using Windows.Devices.Bluetooth.Advertisement;
  9. using Windows.Devices.Bluetooth.GenericAttributeProfile;
  10.  
  11. namespace BLEScanner{
  12.     class Program{
  13.         static Dictionary<ulong, (ulong Address, string Name,string LocalName)> BleDevices = new Dictionary<ulong, (ulong Address, string Name, string LocalName)>();
  14.  
  15.         static async Task Main(string[] args){
  16.             string xiao_nrf52840_name="XIAO nRF52840";
  17.             ulong xiao_nrf52840_device_address=0;
  18.             var watcher = new BluetoothLEAdvertisementWatcher();
  19.             watcher.Received += OnAdvertisementReceived;
  20.             watcher.ScanningMode = BluetoothLEScanningMode.Active;
  21.  
  22.             watcher.Start();
  23.             //Console.WriteLine("Scanning for BLE devices... Press Enter to exit.");
  24.             //Console.ReadLine();
  25.             Console.WriteLine("Scanning for BLE devices in 30sec...");
  26.             await Task.Delay(30000);
  27.             watcher.Stop();
  28.   
  29.             foreach(var bledev in BleDevices){
  30.                 Console.WriteLine($"{bledev.Key} : {bledev.Value}");
  31.                 if(bledev.Value.Name.Contains(xiao_nrf52840_name)){
  32.                     xiao_nrf52840_device_address=bledev.Key;
  33.                 }
  34.             }
  35.             if(xiao_nrf52840_device_address>0){
  36.                 Console.WriteLine($"{xiao_nrf52840_name} was found.");
  37.                 Console.WriteLine($"Address : {xiao_nrf52840_device_address}");
  38.                 var xiao_nrf52840_device = await BluetoothLEDevice.FromBluetoothAddressAsync(xiao_nrf52840_device_address);
  39.                 var xiao_nrf52840_device_services=await xiao_nrf52840_device.GetGattServicesAsync();
  40.                 foreach(var serv in xiao_nrf52840_device_services.Services){
  41.                     Console.WriteLine($" service uuid: {serv.Uuid}");
  42.                     var xiao_nrf52840_device_characteristics=await serv.GetCharacteristicsAsync();
  43.                     foreach(var chr in xiao_nrf52840_device_characteristics.Characteristics){
  44.                         Console.WriteLine($" characterisitics uuid: {chr.Uuid}");
  45.                     }
  46.                 }
  47.                 var xiao_nrf52840_device_service=await xiao_nrf52840_device.GetGattServicesForUuidAsync(new Guid("6e400001-b5a3-f393-e0a9-e50e24dcca9e"));
  48.                 var xiao_nrf52840_device_char_uartrx=await xiao_nrf52840_device_service.Services[0].GetCharacteristicsForUuidAsync(new Guid("6e400003-b5a3-f393-e0a9-e50e24dcca9e"));
  49.                 var rx_characteristics=xiao_nrf52840_device_char_uartrx.Characteristics[0];
  50.                 rx_characteristics.ValueChanged += OnDataReceived;
  51.                 await rx_characteristics.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
  52.                 while (true){
  53.                     //
  54.                 }
  55.             }
  56.         }
  57.         static void OnDataReceived(GattCharacteristic sender, GattValueChangedEventArgs eventArgs) {
  58.             //Console.WriteLine(sender);
  59.             //Console.WriteLine(eventArgs);
  60.             byte[] data = new byte[eventArgs.CharacteristicValue.Length];
  61.             Windows.Storage.Streams.DataReader.FromBuffer(eventArgs.CharacteristicValue).ReadBytes(data);
  62.             var encoding = System.Text.Encoding.GetEncoding("UTF-8");
  63.             var text = encoding.GetString(data);
  64.             Console.WriteLine(text.TrimEnd());
  65.         }
  66.         private static async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args){
  67.             var device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
  68.             if (device != null){
  69.                 string deviceName = string.IsNullOrEmpty(device.Name) ? "Unknown" : device.Name;
  70.                 string deviceLocalName = string.IsNullOrEmpty(device.Name) ? "Unknown" : args.Advertisement.LocalName;
  71.                 BleDevices.TryAdd(device.BluetoothAddress,(device.BluetoothAddress,deviceName,deviceLocalName));
  72.                 //Console.WriteLine($"Found device: {deviceName} -{deviceLocalName}- ({device.BluetoothAddress}) with UUID: {deviceUuid}");
  73.             }
  74.         }
  75.     }
  76. }
BLEアドレスからServicesをとってひとつひとつのServiceでCharacteristicsをとって要素を表示している。この結果を制御に使ってるわけじゃないけど、こういうことができるってことを知っていると何かイイコトがあるかもしれない。
で、dotnet runするとこんな感じ
まぁうまくいったっしょ。
 
あぁ~だいぶさぼっちゃった( ˙꒳˙)
おっさんになると壁にぶつかってダウンしたときに起き上がるのに時間がかかっちゃう。pythonではbleakってライブラリ使って簡単にできるんだけどな、、、が、最近C#好きなんよね、、、なんとなく。