[Steam Deck]Windows環境で、Ext4パーティションを含むSDカードのデータを読み書きする方法

Steam DeckでWindowsとのデュアルブート環境を構築してる方も多いだろうけど、SDカードを挿し替えるのが面倒だし、なによりSDカードを買い足す費用がかかるから、なんとかできないかともがいてみた。

WindowsでExt4パーティションを扱う方法を色々調べたところ、専用のドライバーはありそうだけど、有償だったり、メンテナンスされてなかったり、怪しい所だったり…で使う気がしなかった。そんな中、WSL2を経由すればext4がWindowsでも扱えるという情報を発見。

極力オープンソース技術を使い、かつ比較的安全と思われる方法が見つかったので記録しておく。

先に書いておくと手順が結構くどい。あとLinuxのカーネルモジュールをビルドする関係で時間がかかる。上級者向けかも。オープンソースアプリをソースからビルドした経験があると楽かも。

Steam Deckに搭載されているSDカードリーダーは、SCSI接続の模様。検証始めるまでUSBだと思ってた。

  • 簡単に言うと、WindowsからiSCSIを経由してWSLにマウントして、WSL上に立てたSambaサーバーからまたWindowsへ戻す、というループバックを行う。
  • Windows 11 Home (22H2)で検証。多分Windows 10でもできる。
  • WSL2 / Ubuntu 22.04.1 LTSを利用
  • Windows 11(10) ProだとクライアントHyper-Vが使えるので、うまくデバイスのパススルーができれば、もう少し手順が簡単になる可能性があるかも。
  • Steam Deckの内蔵カードリーダー以外にも応用可能。PCのUSBメモリ等のマスストレージデバイスでも使える。
    • USBだけ使えればいいやという方は、usbipd-winで検索すると幸せになれるかも。
  • 手順はUSB Storage Device Access on WSL2をベースに、パッケージや選択項目の不足をなど細部手順を補完したもの。

前提条件

[WSL側]カーネルモジュールのビルドとインストール

$sudo apt update

ビルドに必要なパッケージをインストール

$ sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses5-dev git bc dwarves
$ mkdir src
$ cd src

WSL2用のLinuxカーネルソースをダウンロードする

$ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
$ cd WSL2-Linux-Kernel
$ export KCONFIG_CONFIG=Microsoft/config-wsl
$ make menuconfig

コンフィグ画面が出るので、下記の項目にチェックを入れる。

[*] Enable loadable module support

General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Device Drivers --->
    [*] Multiple devices driver support (RAID and LVM) --->
        <*> Device mapper support
    [*] Block Devices ---> 
        <*> Loopback device support 
    SCSI device support  --->
        <*> SCSI disk support
        <*> SCSI generic support
        SCSI Transports --->
            <M> iSCSI Transport Attributes
            [*] SCSI low-level drivers  --->
                <M> iSCSI Initiator over TCP/IP     

File systems ---> 
     <*> FUSE (Filesystem in Userspace) support
     [*] UTF-8 nomalization and casefolding support
      ↑忘れずに!この機能が無いとマウントの所でエラーになる
      
[*] Networking support  --->
   Networking options  --->
      [*] TCP/IP networking 

ビルド開始。Steam Deckで30~40分程度かかる。もしエラーになった場合は、不足しているパッケージが無いか再確認する。

$ sudo make KCONFIG_CONFIG=Microsoft/config-wsl

できたモジュールをインストールする

$ sudo make modules_install

新しく作ったカーネルイメージをWindowsのユーザーディレクトリに配置

$ cp ./arch/x86_64/boot/bzImage /mnt/c/Users/(Windowsのユーザー名)/
nano /mnt/c/Users/(ユーザー名)/.wslconfig

/mnt/c/Users/(ユーザー名)/.wslconfig

[wsl2]
kernel=C:\\Users\\(ユーザー名)\\bzImage
swap=0
localhostForwarding=true

Ctrl+oで書き込みメニューを開き、Alt+dでDos Formatを選択、Enterで保存。Ctrl+xで閉じる。

PowerShellからWSLを再起動

PS > wsl --shutdown

再びWSLのコンソールを開き、モジュールをロード

$ sudo modprobe -v libiscsi
$ sudo modprobe -v scsi_transport_iscsi
$ sudo modprobe -v iscsi_tcp
$ sudo modprobe -v libiscsi_tcp

[WSL側]Systemd有効化

$ sudo nano /etc/wsl.conf

/etc/wsl.conf

[boot]
systemd=true

Ctrl+oで書き込みメニューを開き、Enterで保存。Ctrl+xで閉じる。

PowerShellからWSLを再起動。

PS > wsl --shutdown

再びWSLのコンソールを開いて起動しておく。

[Windows側]iSCSIターゲットのセットアップ

iSCSI Consoleを用いる。

https://github.com/TalAloni/iSCSIConsole

画面右側のReleasesからバイナリーのzipをダウンロードする。

zipを展開すると3つフォルダーがあるが、多分どれを選んでも同じ。(対応している.netのバージョンの違いだと思われる)

管理者権限でiSCSIConsole.exeを起動する。

SmartScreenの警告画面が出た場合は、詳細情報→実行をクリック

起動したらAdd Targetをクリック。

Add Physical Diskをクリック。

一覧にSDXCが表示されるので、それを選択してOKをクリック

ドライブをオフラインにする旨の確認画面が出るのでOKをクリック

Disksの欄にSDカードドライブが追加されるので、OKを押して閉じる

StartをクリックしてiSCSIターゲットを起動する。

ファイアーウォールの確認画面が出た場合は許可する。

[WSL側]iSCSIイニシエーターの設定

open-iscsiのインストール

$ sudo apt install open-iscsi

iSCSIターゲットとの疎通確認をする。

$ export WSLHOSTIP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
$ sudo iscsiadm -m discovery -t st -p $WSLHOSTIP

172.26.240.1:3260,-1 iqn.1991-05.com.microsoft:target1

$ sudo iscsiadm -m node

172.26.240.1:3260,-1 iqn.1991-05.com.microsoft:target1

この時点で相手が表示されない場合は、iSCSI ConsoleのStartボタンの押し忘れがないか、ファイアーウォールなどでトラフィックが遮断されていないか確認する。

iSCSIターゲットへ接続。successfulが出ていれば成功

$ sudo iscsiadm -m node --targetname "iqn.1991-05.com.microsoft:target1" --portal "$WSLHOSTIP:3260" --login

Logging in to [iface: default, target: iqn.1991-05.com.microsoft:target1, portal: 172.26.240.1,3260] (multiple)
Login to [iface: default, target: iqn.1991-05.com.microsoft:target1, portal: 172.26.240.1,3260] successful.

新しくブロックデバイスが出現していることを確認

$ lsblk

SDカードのマウントを行う

$ sudo mkdir -p /mnt/sdcard/SteamLibrary

$ sudo mount /dev/sdc1 /mnt/sdcard/SteamLibrary
(↑/dev/sdc1の部分はlsblkを確認して適宜変更する)

[WSL側]Sambaサーバーのセットアップ

$ sudo apt install samba
$ sudo nano /etc/samba/smb.conf

/etc/samba/smb.confの最下行に下記を追加

[sdcard]
   path = /mnt/sdcard
   read only = no
sudo systemctl restart smbd

Samba用のパスワードを設定。

ここではSambaログイン時に利用するLinuxユーザーアカウント名を指定する。ここではdeckとしている。
必要に応じてsudo smbpasswd -a の部分は変更する

パスワードは空白でも怒られなかった。

sudo smbpasswd -a deck
New SMB Password:(そのままEnter)
Retype new SMB password:(そのままEnter) 

WSLのIPアドレスを確認しておく

$ ip addr

[Windows側]ネットワークドライブとして接続

エクスプローラーを開き、PCの所で「・・・」をクリックし、「ネットワークドライブの割り当て」をクリック

ドライブはお好みで。

フォルダーは、\\(WSLのIPアドレス)\sdcardとする

サインイン時に再接続にチェック、別の資格情報を使用して接続するにチェック。

完了をクリック。

アカウントを尋ねられるので、ユーザー:deck、パスワード:(smbpasswdで設定したパスワード)を入力

SDカードの中身が表示されていれば成功。

Steamライブラリフォルダーに追加

設定→ダウンロード→Steamライブラリフォルダーを開く。

ドライブ一覧の右にある(+)ボタンをクリック

「新しいSTEAMライブラリフォルダーを追加」のダイアログが出るので、先程追加したネットワークドライブを選択

※ネットワークドライブが一覧にない場合は、「別の場所を選択」を選び、「追加」をクリックした後、フォルダ選択画面でネットワークドライブを選択し、その配下にある「SteamLibrary」を選択した状態でOKをクリック。

最後に

これによってSteamOSでインストールしたライブラリーの共有ができると思うけど、心配なのは、Windows/Linuxの両方に対応したゲームで、かつ各プラットフォームによって配信されるファイルの内容が分かれているもの。ファイルが上書きされてうまくゲームが動かなくなったりするかも。

安全にライブラリーを共有したいという方は、フォルダを分ける(といっても歪な構造になりそう)か、事前にSDカードのバックアップをとっておくとよいでしょう。

参考

コメントを残す

メールアドレスは公開されません


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。