組込みOS自作入門【Windows11, WSL2】(再開方法・自分なりの進め方解説 編)
書籍『12ステップで作る 組込みOS自作入門』を読み進めています。
一度環境構築をした後、PCの再起動によりUSBシリアルのアタッチがなくなった場合や、暫くやらずに久しぶりに再開する場合を想定してやり方をまとめます。
以下、過去の記事です。
- 環境構築(1/2 - USBシリアル編):
- 環境構築(2/2 - ツールインストール、Hello World! 編):
- 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> ~.
リモートデスクトップ接続しているWindowsでネットワークドライブの割り当てができない
タイトルの通りです。
Windows11からファイルサーバを指定してネットワークドライブを割り当てる操作をしようとすると、うまくいかないことが度々ありました。
失敗する時と成功する時で以下のような再現性があったので書き残しておきます。
失敗する操作:
Macからリモートデスクトップ接続でWindowsを操作して割り当てる(割り当てようとする)。
成功する操作:
Windows機にマウスとキーボードを接続して(リモートデスクトップ接続せずに)操作して割り当てる。
残念ながら、上記のようになる理由は私にはわかりませんでした。
以下、使用環境です。
- Mac (リモートデスクトップ接続元)
- Windows (リモートデスクトップ接続先)
- Windows11 Pro 24H2
- Ubuntu (ファイルサーバ)
普段と異なるネット環境からSSH接続できなくなった場合の解決法
お題の通り、普段はある拠点からSSH接続ができているのに、拠点を移したら接続できなくなったということがありました。
これはルーティングテーブルをリセットしたら解決できました。
PCスペック
- MacOS Sonoma 14.3
ターミナルで次のコマンドを実行してルーティングテーブルをリセットします。
$ sudo ifconfig en0 down $ sudo route flush $ sudo ifconfig en0 up
すると、SSH接続できるようになりました。
見る必要はないですが、次のコマンドでルーティングテーブルの情報を確認できます。
netstat -rn
追記
ある日、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追記)自分で見返すためにステップごとにコメントもつけました。
目次
環境
- Windows11 Pro
- WSL2
- USB to シリアルケーブル
- ELECOM UC-SGT1 [ ELECOM USBtoシリアルケーブル モデム用 USBオス-RS-232C用 UC-SGT1 ]
- binutils-2.21
- gcc-3.4.6
- シリアル通信コマンド:cu (ver. 1.07)
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 インストール
- 2. gcc インストール
- 3. kz_h8write をmake
- 4. ソースコードをダウンロード、make
- 5. H8マイコンのフラッシュROMへの書き込み
- 6. フラッシュROMから起動、Hello World!
環境
前回の記事と同内容です。
- Windows11 Pro
- WSL2
- USB to シリアルケーブル
- ELECOM UC-SGT1 [ ELECOM USBtoシリアルケーブル モデム用 USBオス-RS-232C用 UC-SGT1 ]
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 install3. 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)を表示するまで、
次の記事で binutilsやgccのインストールから Hello World を出力するまでを扱いたいと思います。
次の記事:
hayariapp.hatenablog.com
目次
- 環境
- 1. USBシリアルをWindowsから認識させる
- 2. USBシリアルをWSLから認識させる
環境
- Windows11 Pro
- WSL2
- USB to シリアルケーブル
- ELECOM UC-SGT1 [ ELECOM USBtoシリアルケーブル モデム用 USBオス-RS-232C用 UC-SGT1 ]
- (2021年11月に1827円で購入しましたが、2024年7月現在で4280円になっています。高すぎますね...)
- ELECOM UC-SGT1 [ ELECOM USBtoシリアルケーブル モデム用 USBオス-RS-232C用 UC-SGT1 ]
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/002usbipのインストールに苦戦しました。
参考記事:WSL2のUbuntuにperfをインストールする #WSL2 - Qiita
当記事の記載順に実行されている場合は、2-2で既にWSL2-Linux-Kernelをクローンしていると思います。
usbipは以下のパスにあります。
WSL2-Linux-Kernel/tools/usb/usbip/
READMEに次の記載があります。
[Install]
0. Generate configuration scripts.
$ ./autogen.sh1. 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_normalafter
$ 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
原因
原因は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-FiのIPアドレスを固定化するため、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」の項目も表示されないままです。

