組込みOS自作入門【Windows11, WSL2】(再開方法・自分なりの進め方解説 編)

書籍『12ステップで作る 組込みOS自作入門』を読み進めています。

一度環境構築をした後、PCの再起動によりUSBシリアルのアタッチがなくなった場合や、暫くやらずに久しぶりに再開する場合を想定してやり方をまとめます。

以下、過去の記事です。

  1. 環境構築(1/2 - USBシリアル編):
  2. 環境構築(2/2 - ツールインストール、Hello World! 編):
  3. 2ndステップ以降(詰まる可能性のある点など):



目次


USBシリアル設定(PCを再起動したとき)

USBシリアルをWSLから認識させる

一度Windowsをシャットダウンor再起動するとWSLからUSBシリアルを認識できない状態になると思うので、再びアタッチします。
参照:過去の記事1 「2-1. USBシリアルをWSLにアタッチする」

USBシリアルをWindows機に接続します。

PowerShellを立ち上げて接続されているデバイスを確認します。
初回ではないので、USBシリアルはこの時点で共有状態になっています。

PS > usbipd list
Connected:
BUSID  VID:PID    DEVICE                                              STATE
1-3    0d8c:0014  USB Audio Device, USB 入力デバイス                  Not shared
1-4    8087:0029  インテル(R) ワイヤレス Bluetooth(R)                 Not shared
2-2    056e:5004  Elecom USB-Serial Converter (COM3)                  Shared
2-3    0411:0338  USB 大容量記憶装置                                  Not shared
2-4    0250:3412  USB 入力デバイス                                    Not shared

Persisted:
GUID                                  DEVICE
6724xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  Elecom USB-Serial Converter (COM4)


WSLにアタッチします。
1度目でエラーになったら同じコマンド2度連続で実行するとアタッチできるケースが多いです。

PS > usbipd attach --wsl --busid 2-2
usbipd: info: Using WSL distribution 'Ubuntu' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address 172.31.176.1 to reach the host.
PS > usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
(略)
2-2    056e:5004  Elecom USB-Serial Converter (COM3)                            Attached
(略)

WSL側から確認します。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 056e:5004 Elecom Co., Ltd UC-SGT
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Elecom製のUSBシリアルケーブル UC-SGT が表示されました。

実行ファイルの作成・書込み・実行

ソースコードをダウンロードしてある前提で進めます。

参照:過去の記事2 項目4-6

1st ~ 12th ステップ共通(bootloadのコンパイルから起動・実行)

WSLのターミナルで実行したいStepのbootloadディレクトリをカレントディレクトリとします。

$ cd ~/12step_emb_os/osbook_03/01/bootload

(もしも以前に.motファイルまで作成したことがある場合は make image の実行まで省略できます。むしろ「make: 'all' に対して行うべき事はありません.」のような警告が表示されます。)

Makefile内のデバイスファイル(/dev/tty*)を変更します。
私の環境では /dev/ttyUSB0 のため、以下のようにして変更箇所(cuad0)を置換します。

$ sed -i 's/cuad0/ttyUSB0/g' Makefile

実行形式ファイル(ファームウェア)を作成し、それをモトローラSレコード・フォーマットに変換します。

$ make
$ make image

(この後にファイルに変更を加えた場合は以下のコマンドでクリーンをしてから上記のmake, make imageをやり直します。)

$ make clean

H8マイコンのディップスイッチを ON, ON, OFF, ON に合わせて電源を入れ直したら、フラッシュROMに kzload.mot を書き込みます。

$ sudo make write

続いて、マイコンのディップスイッチを ON, OFF, ON, OFF に合わせて電源を入れ直し、cuコマンドでシリアル接続します。
「Connected.」と表示されたら、リセットボタンを押す度に「Hello World!」が出力されます。
接続を終了するには「~」「.」を入力します。

$ cu -s 9600 -l /dev/ttyUSB0
Connected.
Hello World!
Hello World!
Hello World!
~[(PC名)].
Disconnected.
4th・5th ステップ(ファイル転送・ダンプ)

マイコン起動後にloadコマンドでファイル転送します。

$ sudo cu -s 9600 -l /dev/ttyUSB0
kzload> load
~+sx (ファイル名)
kzload> dump
kzload> ~.
6th ステップ以降

6th ステップからosディレクトリが追加されます。
bootloadディレクトリでmake write(プログラムのダウンロード)まで実行してから、
osディレクトリに遷移してmake(kozosを作成)した後、cuで接続してマイコンを起動します。



〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
中途半端ですが、一旦記事を公開します。気が向いたらまた更新します。
9th ステップ以降はbootloadの更新がなくなるので少し手数が減ります。

リモートデスクトップ接続しているWindowsでネットワークドライブの割り当てができない

タイトルの通りです。

Windows11からファイルサーバを指定してネットワークドライブを割り当てる操作をしようとすると、うまくいかないことが度々ありました。
失敗する時と成功する時で以下のような再現性があったので書き残しておきます。

失敗する操作:
Macからリモートデスクトップ接続でWindowsを操作して割り当てる(割り当てようとする)。

成功する操作:
Windows機にマウスとキーボードを接続して(リモートデスクトップ接続せずに)操作して割り当てる。

残念ながら、上記のようになる理由は私にはわかりませんでした。


以下、使用環境です。

普段と異なるネット環境からSSH接続できなくなった場合の解決法

お題の通り、普段はある拠点からSSH接続ができているのに、拠点を移したら接続できなくなったということがありました。
これはルーティングテーブルをリセットしたら解決できました。

PCスペック


ターミナルで次のコマンドを実行してルーティングテーブルをリセットします。

$ sudo ifconfig en0 down
$ sudo route flush
$ sudo ifconfig en0 up

すると、SSH接続できるようになりました。

見る必要はないですが、次のコマンドでルーティングテーブルの情報を確認できます。

netstat -rn
参考ページ

blog.katsubemakito.net


追記

ある日、SSH接続できなくなったのでルーティングテーブルをリセットしたのですが接続できないままでした。
これは凡ミスで、引越してルータ設定を変えた際にポートマッピングSSH用のポートを開放し忘れていたというオチでした。

その際、route flushコマンドを実行したら次のようなメッセージが出ていました。

$ sudo route flush
default              192.168.XX.1         done
route: write to routing socket: No such process
got only -1 for rlen

ポートマッピング設定後は出なくなりましたが、どういう意味のメッセージなのか理解できないままです。
ご存知の方がいらしたら下のコメントにてご教示いただきたいです。

組込みOS自作入門【Windows11, WSL2】(2nd ステップ以降)

書籍『12ステップで作る 組込みOS自作入門』を読みながらWindows11のWSL2環境でOS自作を進めています。

先日、環境構築をしてHello Worldするまでの方法を記事にしました。

環境構築(1/2 - USBシリアル編):
組込みOS自作入門 環境構築 【Windows11, WSL2】(1/2 - USBシリアル編) - ちょっとした公開めも

環境構築(2/2 - ツールインストール、Hello World! 編):
組込みOS自作入門 環境構築 【Windows11, WSL2】(2/2 - ツールインストール、Hello World! 編) - ちょっとした公開めも


今回は、2ndステップ以降で環境による差異がありそうなところや少し詰まるかもしれないところだけをピックアップして書き残しておきたいと思います。
(2025/3/15追記)自分で見返すためにステップごとにコメントもつけました。



目次


環境


2nd ステップ

書籍の通りに進めて、特に問題なく完了できました。

コメント
1st ステップでは環境構築とHello Worldの出力までを行いました。
2nd ステップでは各種ライブラリ関数の追加と数値の出力を行いました。
この時点では自動変数の書き換えはできますが静的変数の書き換えができません。


3rd ステップ

書籍の通りに進めて、特に問題なく完了できました。

コメント
1st, 2nd ステップではプログラムをフラッシュROMに書き込み、そのままROM上で実行していたため静的変数の書き換えができませんでした。
3rd ステップではこれを改善するために、プログラム起動時にROM上の変数の初期値をRAM上にコピーし(②)、プログラムから変数へのアクセスはコピーしたRAM上のアドレスに対して行いました(①)。

実装では以下の対応をしています。
①リンカ・スクリプトに「VA ≠ PA」対応、つまり仮想アドレスをRAMに、物理アドレスをROMに割り当てる対応
 ・MEMORYコマンドで各メモリの領域(先頭アドレスとサイズ)を定義
 ・SECTIONSコマンドで各セクションをMEMORYコマンドで定義したどの領域に配置するか指定
   「> data AT > rom」:.dataセクションをRAM上のdata領域のアドレスをベースにリンク。物理アドレスをrom領域上に設定。(つまりROM上にロードするということ)

②main.cにデータ領域とBSS領域を初期化する処理を追加(これを行わないと初期値が未設定になる)
 ・データ領域はmemcpyで初期値をコピー
   コピー元:.rodataセクションの終端(ROM上の.dataセクションの先頭アドレス)
   コピー先:RAM上の.dataセクションの先頭アドレス
 ・BSS領域はmemsetでRAM上の.bssセクションの先頭アドレスから0で初期化

そもそもリンクとは...
main.cなどをmakeの実行によりコンパイルして生成したオブジェクトファイル(main.oなど)は、機械語の実行コードを持つが静的変数や関数のアドレスは決定されていない。オブジェクトファイルをリンクすることでそれらのアドレスを決定して最終的な実行形式ファイルが生成される。(p39参照)

ロードとは...
プログラム実行時にセグメント情報を参照してメモリ上に展開する処理のこと。



4th ステップ

ファイル転送アプリをインストール

最初は sx も lsx も入っていませんでした。

$ sx --version
コマンド 'sx' が見つかりません。次の方法でインストールできます:
sudo apt install lrzsz

lrzsz をインストールします。

$ sudo apt install lrzsz
$ sx --version
sx (lrzsz) 0.12.21rc
ファイル転送

lrzsz をインストールしても lsx はインストールされないため、sx を使用します。
書籍と同様、defines.h を転送します。

書籍に記載の通りに「~C」と入力しても子プロセスの起動に移ることはできません。

kzload> load
~C[Unrecognized.  Use ~~ to send ~]

(こうなると何を押しても反応しなくなると思います。H8のリセットボタンを押しましょう。)

参考記事に倣って、「~+」を入力します。
私の環境では、「~」を入力して1秒ほどで[PC名]が表示されます。間髪入れずに「+」を入力すると表示されないのですが...
表示されてもされなくても挙動は変わらないので気にしなくて良いです。

「load」をプロンプトに入力 & Enter すると約8秒に1回の頻度で文字化けしたお豆腐が表示されますが、これも気にしなくて良いです。(スクショを載せておきます)

$ sudo cu -s 9600 -l /dev/ttyUSB0
Connected.
kzload (kozos boot loader) started.
kzload> load
~[(PC名)]+sx defines.h
Sending defines.h, 1 blocks: Give your local XMODEM receive command now.
Bytes Sent:    256   BPS:37

Transfer complete

XMODEM receive succeeded.

dump は書籍の通りです。

kzload> dump
size: 100
23 69 66 6e 64 65 66 20  5f 44 45 46 49 4e 45 53
5f 48 5f 49 4e 43 4c 55  44 45 44 5f 0a 23 64 65
66 69 6e 65 20 5f 44 45  46 49 4e 45 53 5f 48 5f
49 4e 43 4c 55 44 45 44  5f 0a 0a 23 64 65 66 69
6e 65 20 4e 55 4c 4c 20  28 28 76 6f 69 64 20 2a
29 30 29 0a 23 64 65 66  69 6e 65 20 53 45 52 49
41 4c 5f 44 45 46 41 55  4c 54 5f 44 45 56 49 43
45 20 31 0a 0a 74 79 70  65 64 65 66 20 75 6e 73
69 67 6e 65 64 20 63 68  61 72 20 20 75 69 6e 74
38 3b 0a 74 79 70 65 64  65 66 20 75 6e 73 69 67
6e 65 64 20 73 68 6f 72  74 20 75 69 6e 74 31 36
3b 0a 74 79 70 65 64 65  66 20 75 6e 73 69 67 6e
65 64 20 6c 6f 6e 67 20  20 75 69 6e 74 33 32 3b
0a 0a 23 65 6e 64 69 66  0a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a

kzload> ~[(PC名)].
Disconnected.

参考記事:
「12 ステップで作る 組込み OS 自作入門」の開発環境を揃えてみる

5th ステップ以降も順次更新していく予定です。(2024/7/20)

コメント
3rd ステップまではプログラムを修正する度にフラッシュROMに書き込んで動作させていましたが、ROMに上書きできる回数は有限のため、今後はPCでコンパイルした実行ファイル(OS)をH8のRAM上にシリアル転送する方針で準備を進めていきます。

ブート・ローダー:「OSの実行形式ファイルをシリアル経由でダウンロードし、それをRAM上に展開して起動するプログラムをフラッシュROMに書き込む」ようなプログラム。
ブート・ストラップ:電源ONでブート・ローダーを起動し、ブート・ローダーでOSをダウンロードして起動するようなOSの起動手順。

4~6th ステップでブート・ローダーを作成していきますが、4th ステップではファイルをシリアル経由でダウンロードして、その内容を16進ダンプできるようにするところまで実装しました。
ロードする際はリンカ・スクリプトを変更してRAM上に確保した.bufferセクションにロードするようにしています。


5th ステップ

書籍の通り、問題なくできました。

ただ、4th ステップの kzload.elf をそのまま5th ステップにコピーすると5th ステップの kzload.elf とファイル名が一致してしまうため、kzload04.elf にファイル名を変更する変更だけしました。

$ sudo cu -s 9600 -l /dev/ttyUSB0
Connected.
kzload (kozos boot loader) started.
kzload> load
~+sx kzload04.elf
Sending kzload04.elf, 38 blocks: Give your local XMODEM receive command now.
Bytes Sent:   4992   BPS:354

Transfer complete

XMODEM receive succeeded.
kzload> dump
size: 1380
7f 45 4c 46 01 02 01 00  00 00 00 00 00 00 00 00
00 02 00 2e 00 00 00 01  00 00 01 00 00 00 00 34
00 00 08 d0 00 81 00 00  00 34 00 20 00 03 00 28
(略)
69 61 6c 5f 73 65 6e 64  5f 62 79 74 65 00 5f 73
74 61 63 6b 00 5f 6d 61  69 6e 00 5f 65 72 6f 64
61 74 61 00 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a

kzload> run
000094 00000000 00000000 00100 00100 06 01
000194 00000100 00000100 006ec 006ec 05 01
000880 00fffc20 000007ec 00010 00024 06 01
kzload> ~.
Disconnected.

(2024/7/22)

コメント
4th ステップに続いてブート・ローダーの作成中です。5th ステップではダウンロードしたELFファイルを解析してセグメント情報を表示する処理を追加しました。



6th ステップ

書籍の通り、問題なくできました。

kozos.elf ファイルの中身を観察
$ cd ~/12step_emb_os/osbook_03/06/os
$ make
$ readelf -a kozos.elf > kozos_elf.txt
bootload ファイル書き込み
$ cd ../bootload/
$ make
$ make image
$ sudo make write
load, run, echo
$ cd ../os
$ sudo cu -s 9600 -l /dev/ttyUSB0
Connected.
kzload (kozos boot loader) started.
kzload> load
~+sx kozos
Sending kozos, 11 blocks: Give your local XMODEM receive command now.
Bytes Sent:   1536   BPS:334

Transfer complete

XMODEM receive succeeded.
kzload> run
starting from entry point: ffc020
Hello World!
> echo 1234567890
 1234567890
> echo123
123
> exit
~.
Disconnected.

(2024/7/24)

コメント
6th ステップでブート・ローダーを完成させました。
解析したセグメント情報を参照して、セグメントをメモリに展開(コピー)する処理とエントリ・ポイントを取得する処理を加えました。

組込みOS自作入門 環境構築 【Windows11, WSL2】(2/2 - ツールインストール、Hello World! 編)

書籍『12ステップで作る 組込みOS自作入門』をWSL2で環境構築。
長くなったので記事を2つに分けています。
前回の記事ではUSBシリアルをWSLにアタッチして、デバイスファイル(/dev/ttyUSB0)を表示するところまで行いました。


前回の記事:
hayariapp.hatenablog.com

2年前にVirtualBoxで環境構築を行なったときの記事:
hayariapp.hatenablog.com

書籍の公式サポートページ:
kozos.jp



目次


環境

前回の記事と同内容です。


1. binutils インストール

作業用ディレクトリを作成

$ mkdir ~/12step_emb_os

2年前、VirtualBoxで環境構築した際は以下コマンドで binutils 2.19.1をダウンロードしましたが、今回はmakeでエラーが出ました。

$ wget https://ftp.gnu.org/gnu/binutils/binutils-2.19.1.tar.bz2

代わりに binutils 2.21 をダウンロードしたところ、make install まで問題なく実行できました。

$ cd ~/12step_emb_os
$ wget https://kozos.jp/books/makeos/binutils-2.21.tar.gz
$ tar xvf binutils-2.21.tar.gz
$ cd binutils-2.21
$ mkdir build
$ cd build
$ ../configure --target=h8300-elf --disable-nls --disable-werror
$ make
$ sudo make install



2. gcc インストール

gcc 3.4.6をインストールします。

binutils同様、2年前と同じリンクからダウンロードしたところ、makeに失敗しました。

$ wget http://core.ring.gr.jp/pub/GNU/gcc/gcc-3.4.6/gcc-3.4.6.tar.gz

書籍のサポートページに掲載されているリンクからダウンロードすると成功しました。
もしかしたらbinutilsもサポートページからダウンロードすればバージョン2.19.1でも問題なくmakeできたのかもしれません。

$ cd ~/12step_emb_os
$ wget https://kozos.jp/books/makeos/gcc-3.4.6.tar.gz
$ tar xvzf gcc-3.4.6.tar.gz
$ cd gcc-3.4.6
$ nano gcc/collect2.c
(書籍にある通りにcollect2.cを修正)
 L1537, redir_handle= open(...); → open (... , 0755);

$ grep "redir_handle = open" gcc/collect2.c
      redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0755);

$ wget http://kozos.jp/books/makeos/patch-gcc-3.4.6-x64-h8300.txt
$ patch -p0 < patch-gcc-3.4.6-x64-h8300.txt
$ ./configure --target=h8300-elf --disable-nls --disable-threads --disable-shared --enable-languages=c --disable-werror
$ make
$ sudo make install


3. kz_h8write をmake

$ cd ~/12step_emb_os
$ wget https://cubeatsystems.com/kz_h8write/resources/kz_h8write-v0.2.1.zip
$ unzip kz_h8write-v0.2.1.zip
$ cd PackageFiles/src/
$ make


4. ソースコードをダウンロード、make

ソースコードは手打ちしても良いですが、今回はダウンロードします。

$ cd ~/12step_emb_os
$ wget https://kozos.jp/kozos/osbook/osbook_03.zip
$ unzip osbook_03.zip

kz_h8write を書籍に記載のあるディレクトリにコピーしつつ、ファイル名を h8write に変更します。

$ mkdir -p osbook_03/tools/h8write
$ cp PackageFiles/src/kz_h8write osbook_03/tools/h8write/h8write
$ cp PackageFiles/src/kz_h8write.c osbook_03/tools/h8write/h8write.c

Makefileを以下のように書き換えてmakeします。
H8WRITE_SERDEV = [デバイスファイル]

$ cd osbook_03/01/bootload/
$ nano Makefile
$ grep ttyUSB0 Makefile
H8WRITE_SERDEV = /dev/ttyUSB0
$ make
$ make image


5. H8マイコンのフラッシュROMへの書き込み

バイスファイルの権限を変更しておきます。

sudo chmod 666 /dev/ttyUSB0

H8マイコンのディップスイッチを ON, ON, OFF, ON に合わせて電源とPCに接続したら、フラッシュROMに kzload.mot を書き込みます。

$ sudo make write


6. フラッシュROMから起動、Hello World!

今回、シリアル通信にはcuコマンドを使用するためインストールしておきます。

$ sudo apt install cu

マイコンのディップスイッチを ON, OFF, ON, OFF に合わせて電源とPCに接続し、cuコマンドでシリアル接続します。

$ cu -s 9600 -l /dev/ttyUSB0
Connected.
Hello World!
Hello World!
Hello World!
~[(PC名)].
Disconnected.

「Connected.」と表示されたら、リセットボタンを押す度に「Hello World!」が出力されます。
接続を終了するには「~」「.」を入力します。
(私は癖でよくCtrl+Cをしてしまいますが、これでは何も起こりません。)



以上、組込みOS自作入門の 1st ステップの確認でした。



次回の記事:
hayariapp.hatenablog.com

組込みOS自作入門 環境構築 【Windows11, WSL2】(1/2 - USBシリアル編)

書籍『12ステップで作る 組込みOS自作入門』をWSL2で環境構築しようとしたところ、詰まったところがいくつかあったので手順を書き残しておこうと思います。

以下は2年ほど前にVirtualBoxを使って環境構築をした際の記事ですが、全く同じコマンドでできた訳ではありませんでした。
今回は特にUSBシリアルの認識に手こずりました。
hayariapp.hatenablog.com


長くなったため、記事を2つに分けました。
この記事ではUSBシリアルを認識させてデバイスファイル(/dev/ttyUSB0)を表示するまで、
次の記事で binutilsgccのインストールから Hello World を出力するまでを扱いたいと思います。

次の記事:
hayariapp.hatenablog.com



目次

環境


1. USBシリアルをWindowsから認識させる

USBシリアルケーブルをWindowsに挿してデバイスマネージャを開きます。
すると、
ほかのデバイス > USB-Serial Controller
と表示されました。
(COM1には別のデバイスを接続しています)


ドライバーが入っていないせいでこのような表示になります。

製品名などがわからない場合は以下の手順でVIDとPIDを確認してググるとわかると思います。
バイスマネージャでUSB-Serial Controllerを右クリック
> プロパティ > 詳細 > ハードウェアID

私の場合は ELECOM製 USBtoSerial変換ケーブル UC-SGT1 です。
まずはWindowsUpdateでドライバをインストールできないか確認します。

WindowsUpdate > 詳細オブション > オプションの更新プログラム

運良く「ELECOM CO., LTD. - Ports - 10/18/2013」が見つかりました。
これをインストール。

「Elecom USB-Serial Converter (COM3)」と認識されました。



2. USBシリアルをWSLから認識させる

2-1. USBシリアルをWSLにアタッチする

参考記事
ascii.jp

PowerShellでusbipd-winをインストール

PS > winget install usbipd-win

PowerShellを立ち上げ直してから接続されているデバイスを確認。

PS > usbipd list
Connected:
BUSID  VID:PID    DEVICE                                              STATE
1-2    056e:5004  Elecom USB-Serial Converter (COM3)               Not shared
1-3    0411:0338  USB 大容量記憶装置                                  Not shared
2-3    0d8c:0014  USB Audio Device, USB 入力デバイス                  Not shared
2-4    8087:0029  インテル(R) ワイヤレス Bluetooth(R)                Not shared

Persisted:
GUID                                  DEVICE


BUSID 1-2 を共有可能状態にします。

PS > Start-Process usbipd.exe "bind --busid 1-2" -Verb runas
PS > usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-2    056e:5004  Elecom USB-Serial Converter (COM3)                  Shared
(略)

WSLにアタッチ。
私の環境では1度目はエラー、同じコマンド2度連続で実行するとアタッチできるというケースが多いです。

PS > usbipd attach --wsl --busid 1-2
usbipd: info: Using WSL distribution 'Ubuntu' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Using IP address XXX.XX.XXX.X to reach the host.
PS > usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-2    056e:5004  Elecom USB-Serial Converter (COM3)                  Attached

WSL側から確認。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 056e:5004 Elecom Co., Ltd UC-SGT
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Elecom製のUSBシリアルケーブル UC-SGT が表示されました。

2-2. デバイスファイル(/dev/ttyUSB0)を表示する

step1でHello WorldするにはUSBシリアルに対応するデバイスファイル(/dev/tty*)の特定が必須ですが、ここでハマりました。「lsusbには表示されるがデバイスファイルが表示されない」という状況でした。
結論から言うとUSBシリアルのドライバーが入っていないせいでした。
Windows側にドライバを入れて認識したらもうドライバの心配はなし、ではないんですね。WSL側にもドライバが必要になります。

参考記事
qiita.com


PL2303というドライバを入れます。このドライバを入れる根拠は次の項に書きました。あまり役に立たない内容ですが...

参考記事の通りに進めます。

私は libncurses-dev をインストールしたか定かでないです。(この作業の前にも色々とコマンドを試したのですが、途中でコマンドの履歴が消えて辿れなくなったため)

$ sudo apt install build-essential flex bison libssl-dev libelf-dev dwarves libncurses-dev

$ git clone https://github.com/microsoft/WSL2-Linux-Kernel --depth 1
$ cd WSL2-Linux-Kernel


menuconfigを開いてインストールするドライバを選択する。

$ make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl


チェックは[M]ではなく[*]にするように注意してください。
(私は最初間違えて[M]で進めてしまい、デバイスファイルを表示できませんでした。)
スペースキーで[ ] [M] [*] 切り替え、Enter で選択します。




最後に→で移動して < Save > を選択。

$ make -j4 KCONFIG_CONFIG=Microsoft/config-wsl
$ sudo cp arch/x86/boot/bzImage /mnt/c/Users/[ユーザ名]/wsl_kernel
$ nano /mnt/c/Users/[ユーザ名]/.wslconfig
$ cat /mnt/c/Users/[ユーザ名]/.wslconfig
[wsl2]
kernel = C:\\Users\\[ユーザ名]\\wsl_kernel
$ history -a

Power Shell からシャットダウンします。これやったら最近のhistoryが消えてしまいました。
消したくない場合は history -a して.bash_historyにコマンド履歴を残しましょう。

Power Shell

PS > wsl --shutdown


CONFIG_USB_SERIAL_PL2303が有効になっていることを確認。

$ zcat /proc/config.gz | grep 2303
CONFIG_USB_SERIAL_PL2303=y

バイスファイルを確認。

$ dmesg | grep tty
[   45.330524] usb 1-1: pl2303 converter now attached to ttyUSB0
$ ll /dev/ttyU*
crw-rw-rw- 1 root dialout 188, 0  7月  7 23:25 /dev/ttyUSB0


2-3. ドライバに行き着く方法

私がどうやってドライバを入れる必要があると気付いたか、そしてどのドライバを入れる必要があるかわかったかというと、自宅にUbuntuを入れたPCがあるためです。
(そもそもそれならUbuntu機で環境構築しなさいよという話ではあるのですが......)

WSLでどうしてもデバイスファイルを表示できないため、Ubuntu機にUSBシリアルケーブルを繋いで様子を見ました。

lsusbにデバイスを表示でき、/dev/にデバイスファイルも表示できています。

$$ lsusb
(抜粋)
Bus 001 Device 005: ID 056e:5004 Elecom Co., Ltd UC-SGT

$$ ll /dev/ttyUSB*
crw-rw----   1 root dialout 188,     0  7月  7 01:50 ttyUSB0

dmesgを表示するとpl2303というドライバを使用していることがわかりました。

$$ sudo dmesg | grep usb
(抜粋)
[186993.823724] usb 1-5: new full-speed USB device number 4 using xhci_hcd
[186993.972598] usb 1-5: New USB device found, idVendor=056e, idProduct=5004, bcdDevice= 3.00
[186993.972604] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[186993.972606] usb 1-5: Product: USB-Serial Controller
[186993.972608] usb 1-5: Manufacturer: Prolific Technology Inc.
[186994.053257] usbcore: registered new interface driver usbserial_generic
[186994.053270] usbserial: USB Serial support registered for generic
[186994.057230] usbcore: registered new interface driver pl2303
[186994.057248] usbserial: USB Serial support registered for pl2303
[186994.058394] usb 1-5: pl2303 converter now attached to ttyUSB0
[187112.762898] usb 1-5: USB disconnect, device number 4
[238693.541633] usb 1-5: new full-speed USB device number 5 using xhci_hcd
[238693.690784] usb 1-5: New USB device found, idVendor=056e, idProduct=5004, bcdDevice= 3.00
[238693.690804] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[238693.690811] usb 1-5: Product: USB-Serial Controller
[238693.690817] usb 1-5: Manufacturer: Prolific Technology Inc.
[238693.696024] usb 1-5: pl2303 converter now attached to ttyUSB0

Ubuntu機がない場合はどうやって対応するドライバを見つけるのかというと、それは私にはわかりませんでした。
Elecom UC-SGT のドライバをググるWindows用のドライバの記事ばかり出てきます。
どうしても見つけられないなら、正解のUSBシリアルドライバを見つけられるまで手当たり次第にドライバをインストールして確認、正解のドライバ以外は後でアンインストールする、という策でもいいかもしれませんね。
それか、WSLでの環境構築は諦めてVMなどでやることになると思います。


2-4. USBシリアル関連の情報確認のためのコマンドなど(before/after)

USBシリアルのデバイスファイルを表示するために色々と探っていた時に試したことを紹介します。
バイスファイルを表示できる前後の比較をしました。


(1) $ brltty アンインストール

brlttyをアンインストールすると良いと書いている記事がありましたが、元々インストールされておらず空振りでした。

$ sudo apt autoremove brltty
(抜粋)
パッケージ 'brltty' はインストールされていないため削除もされません


(2) $ python3 -m serial.tools.list_ports -v

before

$ python3 -m serial.tools.list_ports -v
no ports found

after

$ python3 -m serial.tools.list_ports -v
/dev/ttyUSB0
    desc: USB-Serial Controller
    hwid: USB VID:PID=056E:5004 LOCATION=1-1
1 ports found


(3) $ usbip port

ドライバインストールの前後で出力に変化はありませんでした。

$ usbip port
Imported USB devices
====================
Port 00: <Port in Use> at Full Speed(12Mbps)
       Elecom Co., Ltd : UC-SGT (056e:5004)
       1-1 -> usbip://172.31.176.1:3240/2-2
           -> remote bus/dev 002/002

usbipのインストールに苦戦しました。
参考記事:WSL2のUbuntuにperfをインストールする #WSL2 - Qiita

当記事の記載順に実行されている場合は、2-2で既にWSL2-Linux-Kernelをクローンしていると思います。
usbipは以下のパスにあります。
WSL2-Linux-Kernel/tools/usb/usbip/

READMEに次の記載があります。

[Install]
0. Generate configuration scripts.
$ ./autogen.sh

1. Compile & install the userspace utilities.
$ ./configure [--with-tcp-wrappers=no] [--with-usbids-dir=

] $ make install 2. Compile & install USB/IP drivers.

記載の通りに ./autogen.sh, ./configure, make install を実行します。
途中でコマンドが足りなくてエラーが出る場合は足りないものをインストール、./cleanup.sh を実行して ./autogen.sh からやり直します。
私の環境では autoconf, automake, libtool, libudev-dev が足りなかったため、追加でインストールしました。


(4) $ setserial

ドライバインストール前は ttyS* を、インストール後は ttyUSB0 の結果を表示しています。

before

$ setserial -g /dev/ttyS*
/dev/ttyS0, UART: unknown, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: unknown, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3
$ setserial -a /dev/ttyS3
/dev/ttyS3, Line 3, UART: unknown, Port: 0x02e8, IRQ: 3
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal

after

$ setserial -v /dev/ttyUSB0
/dev/ttyUSB0, UART: unknown, Port: 0x0000, IRQ: 0
$ setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
        Baud_base: 0, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal


(5) $ lsusb -v

ドライバインストールの前後でMaxPowerだけ変化がありました。
before: MaxPower 500mA
after: MaxPower 100mA

ちなみにUbuntu機との差異はbmAttributesのみでした。
bmAttributes 0xa0
MaxPower 500mA

ドライバインストール後のコマンド実行結果は以下の通りです。

$ lsusb -v
(抜粋)
Bus 001 Device 002: ID 056e:5004 Elecom Co., Ltd UC-SGT
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x056e Elecom Co., Ltd
  idProduct          0x5004 UC-SGT
  bcdDevice            3.00
  iManufacturer           1 Prolific Technology Inc.
  iProduct                2 USB-Serial Controller
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0027
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x000a  1x 10 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
  (Bus Powered)


(6) ダウンロード済みドライバ(?)の確認

before

$  ls /lib/modules/5.15.153.1-microsoft-standard-WSL2/kernel/drivers/usb/serial/
ch341.ko  cp210x.ko  ftdi_sio.ko  usbserial.ko

after
/lib/modules/ 以下が消失。原因・解決方法不明。


2-5. デバイスファイルの表示に失敗した方法

成功例としている記事があるものの、私の環境ではデバイスファイルの表示ができなかった例を紹介します。

(1) 「Windows側の COM1 はWSL側の /dev/ttyS1 に対応」

私の環境では ttyS0,1,2,3 がデバイスファイルとして存在しますが、そのいずれを指定してもH8マイコンにデータを書き込むことはできませんでした。

$ ll /dev/ttyS*
crw-rw---- 1 root dialout 4, 64  7月  4 23:21 /dev/ttyS0
crw-rw---- 1 root dialout 4, 65  7月  4 23:21 /dev/ttyS1
crw-rw---- 1 root dialout 4, 66  7月  4 23:21 /dev/ttyS2
crw-rw---- 1 root dialout 4, 67  7月  4 23:21 /dev/ttyS3

出典:
2020年4月、Ubuntu18.04だったので古い情報だったようです。
WSLで「12ステップで作る組み込みOS自作入門」の環境構築をしてHello World!してみる - Toson blog


(2) /dev/ttyS* のパーミッション変更

/lib/udev/rules.d/50-udev-default.rules 内の

KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"

の末尾に

, MODE="0666"

をつけてパーミッション変更しようというもの。

実行したものの変化なしでした。

記事内で紹介されている記事には自らをdialoutグループに入れる手順も記載されていましたが、私の環境ではデフォルトでdialoutグループに入っていました。

出典:
2022年8月、Ubuntu16.04、WSLではなくVirtualBox
12ステップで作る組込みOS自作入門 環境構築 後編(2022年8月) #自作OS - Qiita

上記記事内で紹介されている記事:
Ubuntuでminicom起動すると/dev/ttyUSB0のパーミッションがないと言われる - kinneko@転職先募集中の日記


ちなみに以下のアクセス権変更も効果なしでした。

sudo chmod 666 /dev/ttyS0


(3) mknodコマンドで /dev/ttyUSB0 を作成
$ sudo mknod /dev/ttyUSB0 c 188 0

上記のコマンドでデバイスファイルを作成します。
参考記事には次のように記載されています。

標準状態でのパリティやボーレートの変更はsttyコマンドなどを使用してください。

しかし、やり方がわかりませんでした。

$ stty -F /dev/ttyUSB0
stty: /dev/ttyUSB0: そのようなデバイスやアドレスはありません

出典:
2010年8月
シリアルUSBアダプターをLinuxで使うには | 近藤科学



〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

以上がUSBシリアル接続とデバイスファイルの表示までの確認でした。

次の記事ではSTEP1で Hello World を出力するまでを記載しようと思います。

次の記事:
hayariapp.hatenablog.com

Ubuntuがネットワーク接続できなくなった(解決済み)

(1年半前の情報ですが、下書きに入れたままのだったので投稿します)

2022年の年末に突如としてUbuntuを入れているPCがWi-Fi、有線LAN共にネットワーク接続できなくなりました。
解決に時間がかかったので、書き残しておきます。

環境

Ubuntu 22.04 LTS

症状

無線、有線共に通信できなくなる。

  • GUIで設定を開くとWi-Fi設定に「Wi-Fiアダプターが見つかりませんでした」と表示される。


  • ネットワーク設定に「Ethernet」の項目が表示されない。


原因

原因はnetplanのyamlファイルにありました。
IPアドレスを固定化する際にWi-Fiを使用しているにもかかわらず、ethernets: に記載していました。

数ヶ月間はその記載で問題なく固定化できていましたし、通信も正常にできていました。しかし、きっかけが何だったのかわかりませんある日突如として通信できなくなりました。

しかし、ログを見たところnetplan apply で警告が出ていますし、正常に通信できていたことがおかしかったのでしょう。

当時のログ

~$ sudo cat /etc/netplan/02-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: networkd
  ethernets:
    wlp3s0:
      dhcp4: false
      addresses: [192.168.10.10/24]
      routes:
      -  to: default
         via: 192.168.10.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
~$ sudo netplan apply
WARNING: systemd-networkd is not running, output will be incomplete.


解決策

Wi-FiIPアドレスを固定化するため、wifis: に情報を記載しました。

~$ sudo cat /etc/netplan/02-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0:
      dhcp4: true
    enp2s0:
      dhcp4: true
  wifis:
    wlp3s0:
      optional: false
      dhcp4: false
      dhcp6: false
      addresses: [192.168.10.10/24]
      routes:
      -  to: default
         via: 192.168.10.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
      access-points:
        "aterm-xxxxxx-a":
          password: "xxxxxxxxxxxx"

なお、解決後もGUIの設定画面は変わりません。
Wi-Fiなら「Wi-Fiアダプターが見つかりませんでした」と表示されてアクセスポイントの一覧は表示されませんし、ネットワーク設定の「Ethernet」の項目も表示されないままです。