2021年10月24日日曜日

WSL2 の Ubuntu 18.04 で WSL2 カーネルをビルドして差し替える

Windows -> WSL2 Ubuntu への USB カメラパススルーを行う前準備として、 USB/V4L2 関連の機能を有効にしたカーネルをビルドし、差し替える方法をまとめた。

現時点で USB カメラへの接続まで確認できていないが、とりあえず作業記録を残す。

前提

  • ホスト OS: Windows 11 Pro 21H2
  • ゲスト OS: Ubuntu 18.04(WSL2)

検証環境の準備

以前使っていた環境が残っていたので、 Ubuntu 環境を削除して作り直す

PS C:\Users\mikoto> wsl -l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-18.04 (既定)
docker-desktop-data
docker-desktop
PS C:\Users\mikoto> wsl --unregister Ubuntu-18.04
登録を解除しています...
PS C:\Users\mikoto> wsl -l
Linux 用 Windows サブシステム ディストリビューション:
docker-desktop-data (既定)
docker-desktop
PS C:\Users\mikoto> wsl --install -d Ubuntu-18.04
Ubuntu 18.04 LTS は既にインストールされています
Ubuntu 18.04 LTS を起動しています...

この流れで Ubuntu が起動するので、続けて作業していく。

パッケージアップグレードと必要パッケージのインストール

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool

カーネル更新

現在のカーネルバージョンを確認

mikoto@DESKTOP-CO13JB2:~$ uname -r
5.4.91-microsoft-standard-WSL2

カーネルバージョンにあったカーネルをチェックアウト

sudo git clone --depth 1 https://github.com/microsoft/WSL2-Linux-Kernel -b linux-msft-5.4.91 /usr/src/5.4.91-microsoft-standard

念のためチェックアウトしたブランチを確認。

mikoto@DESKTOP-CO13JB2:~$ cd /usr/src/5.4.91-microsoft-standard/
mikoto@DESKTOP-CO13JB2:/usr/src/5.4.91-microsoft-standard$ git log
commit 807335635710b9038f2bb95019878d846130501a (grafted, HEAD, tag: linux-msft-5.4.91)
Author: Vivek Yadav <vyadav@microsoft.com>
Date:   Wed Jan 20 18:25:17 2021 +0000

    Merge remote-tracking branch 'msft/linux-msft-wsl-5.4.y' into linux-msft-wsl-5.4.y
mikoto@DESKTOP-CO13JB2:/usr/src/5.4.91-microsoft-standard$ cd -
/home/mikoto

linux-msft-5.4.91 のタグがチェックアウトされているのを確認できる。

現在のカーネル設定をコピー

cd /usr/src/5.4.91-microsoft-standard/
sudo cp /proc/config.gz config.gz
sudo gunzip config.gz
sudo mv config .config

カーネルモジュール設定

make menuconfig で、カーネルモジュールの設定を行う。

sudo make menuconfig

以下に今回変更したものだけ記載する。環境によって差があるかも…。

■ USB 関連

Device Drivers
    +- [*] USB support
        +- <M> Support for Host-side USB
        +- <M> USB Modem (CDC ACM) support
        +- <M> USB Mass Storage support
        +- <M> USB/IP support
        |   +- <M> VHCI hcd
        +- <M> USB Serial Converter support
        |   +- <M> USB FTDI Single Port Serial Driver
        +- USB Physical Layer drivers
        |   +- <M> NOP USB Transceiver Driver
        +- Network device support
            +- <M> USB Network Adapters
                +- <M> Multi-purpose USB Networking Framework
                |   +- <M> Host for RNDIS and ActiveSync devices
                +- <M> Multi-purpose USB Networking Framework

■ V4L2 関連

Device Drivers
    +- <M> Multimedia support
        +- [*] Cameras/video grabbers support
        +- [*] Media USB Adapters
            +- <M> USB Video Class (UVC)

カーネルのビルドとインストール

gcc 8 以上でないとコンパイルできないコードがあるため、 gcc のバージョンを上げて make する。

sudo apt-get install -y gcc-8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
sudo make -j 12 && sudo make modules_install -j 12 && sudo make install -j 12

カーネルを Windows から見られる場所へコピー

sudo mkdir /mnt/c/Users/mikoto/.wsl
sudo cp /usr/src/5.4.91-microsoft-standard/vmlinux /mnt/c/Users/mikoto/.wsl/

新カーネルで WSL 起動

起動カーネル設定

~/.wslconfig で、使用するカーネルを指定する。

[WSL2]
kernel=C:\\Users\\mikoto\\.wsl\\vmlinux

WSL 再起動

wsl --shutdown
wsl -d Ubuntu-18.04

uname で確認すると、新しいカーネルで起動しているのがわかる。

mikoto@DESKTOP-CO13JB2:/mnt/c/Users/mikoto$ uname -a -r
Linux DESKTOP-CO13JB2 5.4.91-microsoft-standard-WSL2+ #1 SMP Sun Oct 24 09:46:32 JST 2021 x86_64 x86_64 x86_64 GNU/Linux

ここから Windows -> Ubuntu への USB カメラパススルーまでもっていきたかったけど、 IP 経由でやり取りするためにアプリインストールとかあるらしくめげた。今日はここまで。

以上。

参考資料

QEMU + aarch64 版 Ubuntu 18.04 で USB パススルーして V4L2 を試す

aarch64 のプラットフォームで Web カメラを使う機会があるので、エミュレーターで何とかできないか試してみた。

前提

Windows 11 Pro -> x86_64 Ubuntu 18.04 on VirtualBox -> aarch64 Ubuntu 18.04 on QEMU という感じに重ねて、 USB パススルーで Windows から QEMU まで Web カメラを繋げていく。

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04
  • QEMU: QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.38)
  • 各 Ubuntu のインストール手順は省略。最小構成でインストールしている。

VirtualBox のゲストに、ホストの USB を繋げる方法は、Windows 11 上の VirtualBox で、 Ubuntu 18.04 に Web カメラを繋げる - mikoto2000 の日記 の記事参照。

aarch64 版 Ubuntu 18.04 の準備

cortex-a57 の virt VM を作る。

QEMU のインストール

sudo apt-get install -y qemu

これで、 QEMU の VM を作成・実行するためのコマンド一式がインストールされる。

aarch64 Ubuntu 18.04 ネットブート ISO イメージのダウンロード

arm64 版 Ubuntu のネットブートインストーラーのダウンロードページ から、 mini.iso をダウンロード。

wget http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/installer-arm64/current/images/netboot/mini.iso

aarch64 VM 用のディスクイメージ生成

qemu-img コマンドでディスクイメージを作成する。

qemu-img create -f qcow2 storage.qcow2 50G

QEMU 用 UEFI イメージの取得

QEMU 用の UEFI イメージを、 Linaro が公開しているのでそれをダウンロード。

wget https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd

USB パススルーのための情報取得

lsusb で、 Web カメラの Vendor ID, Product ID を特定する。

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 019: ID 1bcf:2281 Sunplus Innovation Technology Inc.
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

今回の場合、 Vendor ID: 0x1bcf, Product ID: 2281 のものが Web カメラ。

USB パススルーをするときに使うので、それぞれをメモ。

aarch64 の QEMU で Ubuntu 18.04 をインストール

ここまでで調達した、インストーラー、UEFI, ディスクイメージを使って QEMU を起動。

sudo qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -m 4096 \
    -bios ./QEMU_EFI.fd \
    -drive if=none,file=storage.qcow2,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -cdrom ./mini.iso \
    -nographic

aarch64 の QEMU で Ubuntu 18.04 を実行

インストールが完了したら、 VirtualBox にパススルーした USB カメラを、 QEMU にパススルーしながら実行する。

sudo qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -m 4096 \
    -bios ./QEMU_EFI.fd \
    -drive if=none,file=storage.qcow2,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -device nec-usb-xhci,id=usb \
    -device usb-host,bus=usb.0,vendorid=0x1bcf,productid=0x2281 \
    -nographic

aarch64 版 Ubuntu で USB が認識されていることを確認

ここでもやはり lsusb で確認。

mikoto@ubuntu:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1bcf:2281 Sunplus Innovation Technology Inc.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Vendor ID: 0x1bcf, Product ID: 0x2281 の、 Web カメラが認識されていることがわかる。

V4L2 の動作確認

ffmpeg を使って、 Web カメラの画像を録画できることを確認する。

aarch64 版 Ubuntu 18.04 に ffmpeg をインストール

sudo apt-get install -y ffmpeg

ffmpeg でカメラから画像生成

sudo ffmpeg -f v4l2 -s 352x288 -i /dev/video0 -f image2 ./output-%6d.jpeg

q で録画を停止して、 ls すると、 jpeg 画像が大量に吐き出されている。

QEMU 上の ffmpeg で生成したファイルを抽出

QEMU を停止し、 x86_64 Ubuntu 上で以下コマンドを実行

# qcow2 ファイルをマウント
sudo modprobe nbd
sudo mkdir /mnt/tmp
sudo qemu-nbd -c /dev/nbd0 ./storage.qcow2
sudo mount -o ro /dev/nbd0p2 /mnt/tmp/

/mnt/tmp に aarch64 Ubuntu のディスクがマウントされるので、 吐き出された jpeg を回収、 Windows と共有しているディレクトリへコピーして Windows 上で jpeg ファイルを確認。

OK.

ディレクトリの共有方法は Windows 11 上の VirtualBox で、 Ubuntu 18.04 とフォルダー共有を行う - mikoto2000 の日記 参照。

# 後始末
sudo umount /mnt/tmp/
sudo killall qemu-nbd

こんな画像が大量に吐き出されていた。

以上。

参考資料

2021年10月22日金曜日

Ubuntu 18.04 で BLE iBeacon の内容を確認する

前提

Windows 11 Pro 上の VirtualBox に立てた Ubuntu 18.04 VM に、 USB ドングルを繋げて確認した。

使用した USB ドングルとビーコンは 今回使ったハード類 を参照。

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04

Bluetooth の環境構築

Bluetooth 通信スタックのインストール

sudo apt-get install -y bluez bluez-hcidump
  • bluez : Bluetooth 通信スタック
  • bluez-hcidump : Bluetooth 通信のパケットをダンプするためのパッケージ。今回は iBeacon の通信内容を確認するために使う。

USB ドングルの認識確認

hciconfig で、 USB ドングルの情報が確認できる。

以下のような形でもろもろの情報が取得できる。

LMP Version4.0 以上になっていれば BLE(iBeacon) できるはず…。

$ hciconfig -a
hci0:   Type: Primary  Bus: USB
        BD Address: 00:1A:7D:DA:71:15  ACL MTU: 310:10  SCO MTU: 64:8
        UP RUNNING
        RX bytes:4238 acl:0 sco:0 events:147 errors:0
        TX bytes:2189 acl:0 sco:0 commands:44 errors:0
        Features: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87
        Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
        Link policy: RSWITCH HOLD SNIFF PARK
        Link mode: SLAVE ACCEPT
        Name: 'ubuntu'
        Class: 0x000000
        Service Classes: Unspecified
        Device Class: Miscellaneous,
        HCI Version: 4.0 (0x6)  Revision: 0x22bb
        LMP Version: 4.0 (0x6)  Subversion: 0x22bb
        Manufacturer: Cambridge Silicon Radio (10)

iBeacon を受信できるかの確認

BLE アドバータイズ検索

hcitool lescan で、 BLE のアドバータイズを検索できる。

以下コマンドで、ビーコンの MAC が表示されることを確認。

$ sudo hcitool lescan
...(snip)
AC:23:3F:26:2C:DE (unknown)
...(snip)

ビーコンとの通信

簡単に iBeacon の内容を確認するコマンドは無いようだ。

hcidumphcitool lescan の合わせ技で UUIDMajor, Minor を取得している方法が見つかる。

$ sudo hcidump -R & sudo hcitool lescan
...(snip)
AC:23:3F:26:2C:DE (unknown)
> 04 3E 2B 02 01 00 00 DE 2C 26 3F 23 AC 1F 02 01 06 03 03 F1
  FF 17 16 E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 00
  0C 00 22 00 64 C7
...(snip)
<C-c>
$ fg
<C-c>

ダンプされたバイナリの中に、今回使ったビーコンで設定した UUID, Major, Minor が含まれていることを確認できた。

バイナリの読み方は Raspberry piでiBeacon受信 | TomoSoft を参照のこと。

iBeacon 受信プログラムを nodejs で作る

あまりに読みずらいので、 nodejs のビーコンライブラリを使って受信と情報表示を行う。

Raspberry PiでiBeaconを受信する(Node.js + bleacon) - Qiita に記述されている beacon_discover.js をそのまま利用する。

必要パッケージのインストール

sudo apt-get install -y nodejs npm libbluetooth-dev vim
  • nodejs : ビーコン受信プログラムのランタイム
  • npm : nodejs のパッケージ管理システム
  • libbluetooth-dev : nodejs のビーコンライブラリのビルドに必要なパッケージ
  • vim : プログラム作成のため
mkdir ibeaconreceiver
cd ibeaconreceiver
npm init
npm install bleacon
  • bleacon : nodejs のビーコンライブラリ

iBeacon 受信プログラム作成

Raspberry PiでiBeaconを受信する(Node.js + bleacon) - Qiita に記述されている beacon_discover.js の通りにファイルを作成する。

名前だけ、 npm デフォルトの index.js にした。

var Bleacon = require("bleacon");
Bleacon.startScanning();
Bleacon.on("discover", function(bleacon) {
  console.dir(bleacon);
});

iBeacon 受信プログラム実行

$ sudo nodejs ./index.js
{ uuid: 'e2c56db5dffb48d2b060d0f5a71096e0',
  major: 12,
  minor: 34,
  measuredPower: 0,
  rssi: -62,
  accuracy: 0,
  proximity: 'immediate' }
{ uuid: 'e2c56db5dffb48d2b060d0f5a71096e0',
...(snip)

hcidump より大分わかりやすく情報が表示されている。

後は uuid, major, minor, rssi あたりを見たり見なかったりしながら所望の処理を実装していけばいい感じですかね。

以上。

今回使ったハード類

Bluetooth ドングルは、家に転がっていた 2 つで試して、どちらでも OK だった。

ビーコン発信側は、サンワダイレクトのビーコンを使った。

参考資料

Ubuntu 18.04 で h264 対応の ffmpeg をビルドする

Ubuntu 18.04 の、 apt-get install ffmpeg でインストールされる ffmpeg が h264 に対応していないと勘違いしてビルド方法を調べてしまった。

基本的に CompilationGuide/Ubuntu – FFmpeg の手順にのっとって進めるだけ。

前提

VirtualBox 上の Ubuntu で実施。

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04

手順

必要パッケージのインストール

sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libmp3lame-dev \
  libsdl2-dev \
  libtool \
  libunistring-dev \
  libva-dev \
  libvdpau-dev \
  libvorbis-dev \
  libx264-dev \
  libxcb-shm0-dev \
  libxcb-xfixes0-dev \
  libxcb1-dev \
  meson \
  nasm \
  ninja-build \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

ソースコード取得

cd ~/project
git clone https://github.com/FFmpeg/FFmpeg.git

ビルド

cd ~/project/FFmpeg

./configure \
  --pkg-config-flags="--static" \
  --extra-libs="-lpthread -lm" \
  --ld="g++" \
  --enable-gpl \
  --enable-gnutls \
  --enable-libx264 \
  --enable-nonfree

make

ビルドしたバイナリがカレントディレクトリへ配置される。

./ffmpeg -codecs で、 h264 のコーデックが入っていることを確認できる。

参考資料

おまけ

本題とは関係ないが、 VirtualBox 上の CLI Ubuntu に、コマンドコピペできなくて辛かったので SSH 接続するようにした。

VirtualBox 上の CentOS に ssh 接続する [ Windows 編] - Resty’s log:手取り15万円の日常

Windows 11 上の VirtualBox で、 Ubuntu 18.04 に Web カメラを繋げる

前提

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04

手順

Oracle VM VirtualBox Extension Pack のインストール

1.Downloads – Oracle VM VirtualBox の見出し VirtualBox 6.1.28 Oracle VM VirtualBox Extension Pack の下のリンク All supported platforms から、 Extension Pack をダウンロードする 2. ダウンロードした Oracle_VM_VirtualBox_Extension_Pack-6.1.28.vbox-extpack をダブルクリックし、インストーラーの指示に従いインストール

USB カメラの設定

  1. 対象の Ubuntu VM を停止
  2. 対象の Ubuntu VM の 設定 -> USB を選択し、 USB 設定を行い、 OK ボタン押下
    • USB コントローラーを有効化(U) : チェックを入れる
    • USB 3.9 (xHCI) コントローラー にチェックを入れる
    • USB デバイスフィルター :
      • 右の USB デバイス追加ボタンを押下し、 Ubuntu VM に繋げたい Web カメラを選択

これで、 VM 起動後、 /dev/video* のデバイスが生えているはず。

ffmpeg で録画

/dev/video0 に生えた場合、以下コマンドで Web カメラの画像を avi で録画できる。

sudo ffmpeg -i /dev/video0 output.avi

参考資料

Windows 11 上の VirtualBox で、 Ubuntu 18.04 とフォルダー共有を行う

やっていきます。

前提

  • ホスト OS: Windows 11 Pro 21H2
  • VirtualBox: バージョン 6.1.28 r147628 (Qt5.6.2)
  • ゲスト OS: Ubuntu 18.04

手順

  1. virtualbox-guest-utils をインストール

    sudo apt install -y virtualbox-guest-utils
  2. 再起動

    sudo shutdown -r now
  3. ユーザーを vboxsf グループへ追加

    sudo adduser mikoto vboxsf
  4. ログアウトしてログインしなおす

  5. 共有フォルダ設定

    1. メニューの 仮想マシン -> 設定 -> 共有フォルダ―
    2. 右上の 共有フォルダ―追加 アイコンをクリック
    3. 共有フォルダ―の追加 ダイアログが開くので、必要事項を記入
      • フォルダーのパス : ゲスト OS のフォルダー
      • フォルダー名 : 自動で入力される。フォルダー名を指定したい場合に修正
      • 自動マウント : ON
      • マウントポイント : ゲスト OS のどこにマウントするかを指定
  6. 再起動

    • 再起動後、指定のマウントポイントにマウントされる
    • マウントポイントが指定されなかった場合、 /media/sf_<フォルダー名> のフォルダにマウントされる

参考資料