目次を開く
「電子辞書でLinuxが動く」と聞いて、microSDを1枚用意した。
起動はすぐにできた。そこから先、音が出ない、. が止まらない、突然固まる、ブラウザーが重い、といった問題に1つずつ当たった。直せたものと、直せていないものを残す。
01
何ができて、何が残ったか
SHARPの電子辞書 Brain PW-SH3 で、Debianベースの Brainux を日常的に触れる状態にした。OSの導入そのものは公式の手順どおりで、この記事では導入後に独自に行ったことだけを書く。
| 項目 | 結果 |
|---|---|
| 内蔵スピーカー / マイク | 動作。音声IC(ROHM BU26154)のLinuxドライバが無かったので書いた。スピーカー再生は耳で、録音はデータの解析で確認。 |
記号キーで . や / が連続入力される | 修正。キーボードドライバがキーの「離した」を通知し忘れるバグだった。 |
| USB Wi-Fi | 動作。公式イメージには wpasupplicant とファームウェアが無く、追加が必要だった。 |
| Bluetooth / WireGuard | カーネルを再ビルドして有効化。ビルドと起動は確認、実際の接続は未確認。 |
| 固まる問題 | 原因はメモリ不足(OOM)。512 MBのスワップで解消。 |
| microSDからの直接起動 | 動作。辞書の画面を経由せずにLinuxが起動する。 |
| WebブラウザーとAIアプリ | 本体では実用にならない。PCで動かしてVNCで映す方法が実用的だった。 |
| 電源オフ | 未解決。シャットダウン後に自動で起動し直す。 |
02
対象と前提
| 項目 | 内容 |
|---|---|
| 本体 | SHARP Brain PW-SH3(2016年のモデル。Brainuxでの呼び方は Sx3) |
| SoC / RAM | NXP i.MX283(ARM926EJ-S、454 MHz)/ 128 MB(Linuxから見えるのは約111 MB) |
| 画面 | 854×480、16ビットカラー(RGB565) |
| Brainux | 2026-03-25 のリリース。Debian 13(trixie)、armel、カーネル 6.1.70 |
| 内蔵ストレージ | eMMC 8 GB。Linuxでは mmcblk0。辞書のシステムが入っているので触らない |
| microSD | 32 GB。Linuxでは mmcblk1 |
| USB | Micro-Bが1つ。BrainuxではUSBホストとして動く(OTGアダプタで機器を挿す) |
| ビルド用PC | Linux、Docker。buildbrain のDockerイメージを使用 |

イメージの書き込み、起動の仕組み、対応機種は公式に任せる。Brainuxの公式サイトとbuildbrainを先に読んでほしい。
初期ユーザーのパスワードは公開されている値なので、すぐ変える。SSHのホスト鍵も配布イメージに含まれているものは全員共通なので、作り直す。本体で鍵を作るときは Ed25519 と ECDSA だけにする。RSA鍵の生成は、この本体では何分待っても終わらなかった。
# 本体で実行(root)。RSAは作らない
rm -f /etc/ssh/ssh_host_*
ssh-keygen -q -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key
ssh-keygen -q -t ecdsa -N "" -f /etc/ssh/ssh_host_ecdsa_key
systemctl restart ssh03
カーネルを作り直す
公式のカーネルには Bluetooth も WireGuard も入っていない。buildbrain のツリーで、設定の断片を足して作り直した。組み込み(=y)にしておくと、差し替えるのは zImage だけで済む。
- bluetooth.config:Bluetooth本体、USBドングル(btusb)、HID、RFCOMM、BNEP、RFKILL
- wireguard.config:WireGuard、ポリシールーティング、nftables(
wg-quickで全通信をVPNに流すときに要る)
# PC で実行。buildbrain を clone し、linux-brain のサブモジュールを取得済みとする
cd buildbrain
make docker-build
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD/..":/w -w /w/buildbrain buildbrain-builder:local bash -lc '
make ldefconfig &&
cd linux-brain &&
scripts/kconfig/merge_config.sh -m .config ../../bluetooth.config ../../wireguard.config &&
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- olddefconfig &&
cd .. && make lbuild'
# できたもの: linux-brain/arch/arm/boot/zImage と dts/imx28-pwsh3.dtbリリース名を変えない
ソースに手を入れてビルドすると、カーネルのリリース名の末尾に -dirty が付く。名前が変わると /lib/modules/ の場所がずれて、モジュールが読み込めなくなる。ツリーの直下に .scmversion を置くと、名前を固定できる。
# linux-brain の直下で。値は元のリリース名の末尾に合わせる
printf -- '-ga9f534c7f53e' > .scmversion
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -s kernelrelease # 6.1.70-ga9f534c7f53e本体に入れる
起動用の領域(/boot、FAT)は読み取り専用でマウントされている。書き込むときだけ書き込み可能にする。元のファイルは残しておく。
# 本体で実行(root)。zImage.new は scp などで /tmp に置いたもの
mount -o remount,rw /boot
[ -e /boot/zImage.bak ] || cp /boot/zImage /boot/zImage.bak
cp /tmp/zImage.new /boot/zImage.new && sync && mv /boot/zImage.new /boot/zImage && sync
mount -o remount,ro /boot公式イメージには /lib/modules が入っていない。モジュールを使うなら、modules_install で作った一式も本体に置く。
04
キーボード:連続入力のバグと、足りないキー
. や / が止まらない
記号キーを押しながら M を押すと . が入る。ところが、入力が止まらず、同じ文字が連続で入り続けることがあった。/(記号+−)、,(記号+N)、4(記号+R)、=(記号+F)でも起きる。
原因は、キーボードドライバ drivers/input/keyboard/brain-kbd-gpio.c にあった。このドライバはキーを7つのグループ(バンク)に分けて読む。あるバンクの中でキーを離したとき、同じバンクの別のキーがまだ押されていると、「離した」をLinuxに通知しない。記号キーは R・F・N・M・− と同じバンクにあるので、記号を押したまま文字キーを離すと、その文字が押されたままの扱いになり、キーリピートが止まらなくなる。
/* 修正前(要点): バンクに押されたキーが残っている間は、状態を消すだけで通知しない */
if ((in[j] & bank) == 0) {
/* 押された → input_report_key(..., 1) */
kbd->pressed[i][j] = true;
} else {
kbd->pressed[i][j] = false; /* ← 離したことが伝わらない */
}
/* 修正後: 押したときに送ったキーコードを覚えておき、離したら同じコードを離す */
} else {
if (kbd->pressed[i][j])
bk_gpio_release(kbd, inputdev, i, j);
kbd->pressed[i][j] = false;
}修正の全体は kbd-release-fix.patch。押したときのキーコードをキーごとに記録し、離すときは必ず同じコードを離す。記号キーを先に離しても、文字キーを先に離しても、取り残しが出ない。カーネルを作り直して入れ替えたあと、連続入力が起きなくなったことを実機で確認した。
/dev/input/event0 を直接読むと、ウィンドウマネージャーが横取りするキーも含めて、本体のキーが実際に何を送っているかが分かる。逆に、同じファイルにイベントを書き込むと、キー入力を外から送り込める。ただし書き込んだイベントはドライバを通らないので、今回のようなドライバのバグは再現しない。
足りないキーを割り当てる
PW-SH3用のデバイスツリー(imx28-pwsh3.dts)では、いくつかのキーが未割り当てだった。使いやすいように割り当てた。変更は keymap-pwsh3.patch。
| 本体のキー | 送るキー | 用途 |
|---|---|---|
| ホーム | Super | ウィンドウマネージャーのショートカット用 |
| ツール | F12 | Window Makerのメニュー |
| 次ページ | F11 | Window Makerのウィンドウ一覧 |
| 履歴・しおり | 半角/全角 | VNC越しにPCの日本語入力を切り替える |
| 記号+ツール / 記号+次ページ | F1 / F2 | ログイン画面(ly)の電源オフ / 再起動 |
もとからの割り当てのうち、よく使うものは次のとおり。国語=Tab、検索・戻る=Esc、前ページ=Ctrl、文字切替=Alt、英和・和英=Page Up、マイ辞書=Page Down。数字は記号+Q〜P。
キーの名前はデバイスツリーのコメントから読み取った。実機で押して確かめたのは、文字切替・前ページ・次ページ・ホーム・ツール・国語・↑ の7つ。
05
内蔵スピーカーとマイクを鳴らす
公式のBrainuxは、内蔵の音声に対応していない。起動ログには sgtl5000 0-000a: Error reading chip id -6 と出る。これは評価ボード用の定義が残っているだけで、Brainにそのチップは載っていない。
基板を見ると、音声ICは ROHM BU26154MUV だった。Linuxのドライバは見つからなかったので、データシートを読んで書いた。

MPWSA300031001G)。中央がi.MX283(U101)、左上が音声IC(U601)、右上がSamsungのeMMC(U404)。下の辺に、Micro-B、イヤホン端子、microSDのスロットが並ぶ。基板の管理ラベルは隠してある。
BU26154。40ピンの6 mm角で、スピーカーアンプとマイクアンプも入っている。| 項目 | 内容 | 確かめ方 |
|---|---|---|
| 制御線 | I2Cバス0、アドレス 0x1a | レジスタを読み、初期値がデータシートと一致 |
| クロック | SAIF0のMCLK・LRCLK・BITCLK。i.MX283がマスター | 再生と録音が動いたことから |
| 再生データ | SAIF0_SDATA0 → ICのSAI_SDIN | 再生音を耳で確認 |
| 録音データ | ICのSAI_SDOUT → SAIF1_SDATA0 | 録音データの解析 |
| スピーカー | ICのスピーカー出力に直結。外付けアンプなし | 再生音を耳で確認 |
| リセット線 | 起動時点で解除済み。GPIOの操作は不要 | I2Cが最初から応答 |
データシートの入手
ICの型番は、基板の刻印(BU26154)から分かる。正式な型番は BU26154MUV-E2。データシートは公開されていて、次のところから無料で入手できる。
- ROHMの製品ページ:「ドキュメント」の欄にデータシートがある。製品は「最終販売」(製造中止を申請中)の扱いなので、ページが無くなる前に手元に保存しておくとよい。
- 部品の販売店の製品ページ:LCSC(部品番号 C4991521)などに、同じデータシートが置かれている。今回使ったのは、ここにあった Rev.002(2015年10月26日付、89ページ)。
- 見つからないときは、型番
BU26154MUV-E2と「datasheet」で検索する。データシートをまとめたサイトにも写しがある。
ドライバを書くときに主に読んだのは、レジスタの一覧(37〜44ページ)、Clock EnableとPLLOEの説明(45ページ)、音量の設定範囲(52ページ)。版によってページ番号がずれることがある。データシート自体は再配布せず、リンクだけを載せる。
ドライバの構成
- bu26154.c:コーデックのドライバ。I2CでICを設定する
- mxs-bu26154.c:サウンドカードのドライバ。SAIF0 / SAIF1 とICを結び付ける
- Makefile:カーネルツリーの外でビルドするためのもの(
Makefileという名前で置く)
どちらもカーネルモジュールで、カーネルの入れ替えもデバイスツリーの変更も要らない。I2Cのデバイスとサウンドカードのデバイスは、モジュールが自分で作る。
# PC で実行。カーネルをビルドしたツリーとリリース名が実機と一致していること
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD":/w -w /w/buildbrain/linux-brain buildbrain-builder:local \
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- M=/w/audio-driver modules
# 本体で実行(root)。2つの .ko を置いて、起動時に読み込ませる
d=/lib/modules/$(uname -r)/extra
mkdir -p "$d"
cp bu26154.ko mxs-bu26154.ko "$d"/
depmod -a
printf 'bu26154\nmxs-bu26154\n' > /etc/modules-load.d/brain-audio.conf
modprobe bu26154 && modprobe mxs-bu26154amixer -c 0 sset Master 236 # デジタル音量。最大は 254
amixer -c 0 sset Speaker 10 on # 0〜25。10 が 0 dB
aplay -D hw:0,0 music.wav # 16ビット・ステレオ
arecord -D hw:0,1 -f S16_LE -r 44100 -c 2 rec.wavはまったところ
| 症状 | 原因と対処 |
|---|---|
I2Cは応答し、aplay もエラーなく終わるのに無音 | Clock Enableレジスタ(0x0c)の PLLOE ビットを立てていなかった。PLLを使わなくても1にしないと、ICの内部にクロックが回らない。データシートには1行しか書かれていない。0x0c = 0x05 で解決。 |
arecord が I/O エラーになる | SAIF1は、SAIF0のクロックを借りて動く。HW_DIGCTL_CTRL の SAIF_CLKMUX を 2(EXTMSTR0)にする必要があるが、Brain用の初期化では設定されていない。モジュールの読み込み時に設定するようにした。 |
| regmapのI2C実装が使えない | このICは、読み出しが偶数番地、書き込みがその+1の奇数番地。レジスタは3面あり、0x1c / 0x1d で切り替える。読み書きの関数を自前で書いた。 |
| 音量を最大にすると動作が保証されない | デジタル音量(0x3e)は初期値が 0xff なのに、表では 0xff が設定禁止。上限は 0xfe。 |
| モジュールを外すとカーネルが不安定になる | rmmod の直後に BUG: Bad rss-counter state が出ることを2回確認した。原因は未特定。入れ替えるときは、ファイルを置き換えて再起動する。 |
耳を使わずに確かめる
スピーカーで既知の周波数を鳴らしながら、マイクで録音する。録音に同じ周波数が現れれば、再生と録音の両方が生きている。今回は 880 Hz を鳴らしている間だけ、録音に 880 Hz の成分が現れた。録音が全部 0 なら、ICにクロックが回っていない。
arecord -q -D hw:0,1 -f S16_LE -r 44100 -c 2 -d 5 rec.wav &
sleep 1; aplay -q -D hw:0,0 tone.wav; wait対応するサンプリングレートは 8〜48 kHz、形式は16ビットのステレオだけ。録音は左チャンネルにだけ音が入る(ICのADCがモノラルのため)。
分かっていないこと:イヤホンは未確認。挿抜の検出も未対応で、挿してもスピーカーは切れない。音割れは、スピーカーアンプをD級にすると減ったが、残っている。省電力は未対応で、アナログ部に常時通電している。ほかの機種(Yamaha系の音声ICを載せたもの)には使えない。
06
固まる原因はメモリだった
パッケージをまとめて入れたり、SSHの鍵を作ったりすると、本体がまったく応答しなくなることが何度かあった。pingには応答するのに、SSHは接続の途中でタイムアウトする。最初はmicroSDの不調を疑ったが、カーネルのログに答えがあった。
Out of memory: Killed process ... (apt-get)
Out of memory: Killed process ... (systemd-hwdb)RAMは実質111 MBで、公式イメージにはスワップが無い。メモリが足りなくなると、システムは同じデータをmicroSDから何度も読み直す状態になり、負荷(ロードアベレージ)が13を超えて、ほぼ止まる。
# 本体で実行(root)。512 MB のスワップファイル
fallocate -l 512M /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
echo 'vm.swappiness=30' > /etc/sysctl.d/90-swap.conf && sysctl -p /etc/sysctl.d/90-swap.confスワップを足したあと、151個のパッケージ(482 MB分)を入れ終えるまでに、メモリ不足による強制終了は起きなかった。スワップの使用は最大で約37 MBだった。
パッケージは少しずつ入れる
本体で apt update を回すのは重い。PCで必要な .deb を集めてから本体に送り、数個ずつ入れると安定した。lex01-install-batches は、ライブラリを先に、6個ずつ、優先度を下げて入れる。空きメモリが20 MBを切るか、負荷が4以上の間は待つ。
PC側では、本体の /var/lib/dpkg/status を取り寄せ、それを基準に apt-get install --download-only を実行すると、本体に足りないパッケージだけを依存関係つきで集められる。
# PC で実行(Debian trixie のコンテナの中など)。status は本体から取り寄せたもの
O="-o APT::Architecture=armel -o APT::Architectures::=armel
-o Dir::State::status=$PWD/status -o Dir::State::Lists=$PWD/lists
-o Dir::Cache::Archives=$PWD/debs -o Dir::Etc::SourceList=$PWD/sources.list
-o Dir::Etc::SourceParts=/nonexistent"
mkdir -p lists/partial debs/partial
apt-get $O update
apt-get $O install -y --download-only --no-install-recommends gphoto2 gtkamそのほか、microSDの空き領域は自動では広がらない。動かしたまま sfdisk で第2パーティションを広げ、partx -u と resize2fs を実行すると、再起動なしで32 GBいっぱいまで使えるようになった。対象は mmcblk1。mmcblk0 は辞書の本体なので、間違えないこと。
07
Wi-FiとBluetooth
USBのWi-Fiドングル用のドライバは、公式のカーネルに最初から入っている(Realtekの rtl8xxxu、Ralinkの rt2800usb、Atherosの ath9k_htc、MediaTekの mt76 系など)。ところが、公式イメージには次の2つが入っていないので、そのままではつながらない。
wpasupplicant:無いと、NetworkManagerがWi-Fiを「unavailable」と表示する- ファームウェア:
firmware-realtek、firmware-misc-nonfree(Ralink)、firmware-atheros、firmware-mediatek。/lib/firmwareは空で、aptの設定にもnon-free-firmwareが無い
本体はネットにつながっていないので、PCで .deb を集めてmicroSDに入れておき、本体で dpkg -i する。確認したドングルは BUFFALO WLI-UC-GNM(Ralink RT8070)。
nmcli device # wifi の行が disconnected になっていればよい
nmcli device wifi connect "SSID" --ask802-11-wireless-security.key-mgmt: property is missing というエラーが出たら、失敗した接続設定が残っている。nmcli connection delete で消して、nmcli device wifi rescan のあとにつなぎ直す。
USB端子は1つしかない。Wi-Fiドングルを挿すと、ほかのUSB機器は同時に使えない。Bluetoothは、カーネル側の準備までで、ドングルを挿しての確認はしていない。
08
microSDからの直接起動と、電源オフの問題
公式イメージの起動用の領域には、nk/ というフォルダがある。その中の機種別のファイルを領域の一番上にコピーしておくと、リセット時に辞書のシステムを経由せず、U-BootからLinuxが直接起動する。PW-SH3 用は edsa3exe.bin。
# microSD の第1パーティションをマウントした場所で
cp nk/edsa3exe.bin ./edsa3exe.bin内蔵の起動プログラムが、辞書のシステムを読み込む前にmicroSDを調べる仕組みを使っている。内蔵ストレージは書き換えない。microSDを抜くか、このファイルを消せば、元の電子辞書に戻る。再起動の指示から約85〜105秒で、SSHに応答するようになった。
電源オフが再起動になる(未解決)
systemctl poweroff は最後まで進む。しかし、その直後に本体が自動で起動し直す。電源レジスタ(HW_POWER_STS)を読むと、5 Vの入力ありと検出されていた。i.MX28は、5 Vが入っている状態で電源を切ると、すぐに起動し直す。USBのコントローラーを止めても、5 Vの検出は消えなかった。出どころは特定できていない。
起動の途中、U-Bootがカーネルを読み込んだ直後で止まったことも1回あった。OSが動いていないので、電源ボタンは効かない。microSDを抜いてからリセットすると辞書が起動し、そこで電源を切れる。
09
854×480でデスクトップを使う
公式イメージには、X11・JWM・ログイン画面(ly)が入っている。今回はウィンドウマネージャーを Window Maker にした。ユーザーの ~/.xsession に exec wmaker と書くだけで切り替わる。パッケージを入れると、システム全体の標準まで Window Maker に変わるので、ほかのユーザーをJWMのままにしたいなら update-alternatives --set x-window-manager /usr/bin/jwm で戻す。
| 困ったこと | 対処 |
|---|---|
| ウィンドウが画面からはみ出す。スクロールバーが画面の外に出る | Window Makerには、ウィンドウを画面に収める機能が無い。アプリごとに「最初から最大化」を設定する(下のコマンド)。 |
| 最大化するとDockの下に隠れる | NoWindowOverDock = YES。 |
| メニューを開けない(右クリックもF12も無い) | キーボード側でツール=F12、次ページ=F11を割り当てた。 |
| タッチでダブルクリックが効かない | DoubleClickDelay を250から600 msに延ばした。 |
| Dockの設定ファイルを書き換えても元に戻る | Window Makerは、終了時に WMState を上書きする。書き換えたら chattr +i で保護し、SIGUSR1 で再読み込みさせてから、保護を外す。 |
| 標準の端末がgnome-terminalで、起動しない | update-alternatives --set x-terminal-emulator /usr/bin/lxterminal。 |
| ログイン画面にカーネルのメッセージが重なる | kernel.printk = 3 4 1 3 を /etc/sysctl.d/ に置く。 |
| NetSurfでキーを押してもスクロールしない | 開いた直後は、入力がアドレス欄に向いている。Tab(国語キー)を1回押してから ↑↓。 |
wdwrite WindowMaker NoWindowOverDock YES
wdwrite WMGLOBAL DoubleClickDelay 600
wdwrite WMWindowAttributes lxterminal.Lxterminal '{StartMaximized = Yes;}'
wdwrite WMWindowAttributes netsurf-gtk.Netsurf-gtk '{StartMaximized = Yes;}'
wdwrite WindowMaker MaximizeKey '"Mod1+Up"' # 文字切替 + ↑画面の内容は、SSH越しにフレームバッファを読むだけで取り出せる。追加のソフトは要らない。遠隔で作業するとき、今の画面を確かめるのに使った。
# PC で実行。1708 = 854 ピクセル × 2 バイト
ssh -l root brain.local 'head -c $((1708*480)) /dev/fb0' > fb.raw
ffmpeg -f rawvideo -pixel_format rgb565le -video_size 854x480 -i fb.raw -frames:v 1 screen.pngPython 3は最初から入っている。python3-tk を足すと、tkinterで自作の画面を作れる。ただし、ウィンドウが出るまでに約5秒、少し部品の多いアプリだと約20秒かかる。色数は16ビットが最も軽く、減らす設定は無い。
10
WebとAIアプリは、PCで動かしてVNCで映す
本体でJavaScriptの動くブラウザーを使うのは、現実的ではなかった。FirefoxとChromiumは、armel向けのパッケージが無い。WebKit系は、エンジンだけで約88 MBあり、メモリが足りない。そこで、重い処理はPCに任せ、Brainは画面とキーボードだけを受け持つ形にした。
VNCをLANに開かない
VNCは暗号化されない。PC側のVNCサーバーは localhost だけで待ち受けさせ、PCからBrainへのSSH接続に乗せて届ける。Brainから見ると、自分の localhost にVNCサーバーがあるように見える。BrainからPCへ入る経路は作らない。
# PC で実行。5905 = 仮想デスクトップ、5906 = 実画面の共有
ssh -N -R 5905:localhost:5905 -R 5906:localhost:5906 -l root brain.local方法1:仮想デスクトップでブラウザーを動かす
PCに、Brainの画面に合わせた小さな仮想デスクトップを作り、そこでFirefoxを動かす。大きさは 786×446、色は16ビット。Brain側のウィンドウにちょうど収まり、色の変換も要らない。
# PC で実行
Xtigervnc :5 -geometry 786x446 -depth 16 -rfbport 5905 -localhost \
-SecurityTypes None -AlwaysShared -nolisten tcp &
DISPLAY=:5 marco &
DISPLAY=:5 firefox --no-remote --profile "$HOME/.config/brain-vnc/firefox" --width 786 --height 446 &
# Brain で実行
xtightvncviewer -encodings "tight copyrect hextile" -compresslevel 6 -quality 5 localhost:5速度は、使った本人の感想で「割と実用的」。ページの表示やスクロールは、本体のNetSurfより快適だった。
方法2:動いているアプリのウィンドウを、そのまま映す
AIのデスクトップアプリのように、同時に1つしか起動できず、実行中の作業を止めたくないものは、起動し直さずに映す。PCの実際の画面のうち、そのウィンドウの範囲だけを x11vnc -clip で配る。
- ウィンドウを、Brainに合う大きさ(786×446)にして、最前面に固定する。
- その範囲だけを
x11vncで localhost に配る。 - Brainのビューアを閉じたら、ウィンドウを元の位置と大きさに戻す。
# PC で実行(要点)。id はウィンドウのID、X Y は移動先の左上
wmctrl -i -r "$id" -b remove,maximized_vert,maximized_horz
wmctrl -i -r "$id" -e "0,$X,$Y,786,446"
wmctrl -i -r "$id" -b add,above
x11vnc -display :0 -localhost -rfbport 5906 -nopw -shared -forever \
-clip "786x446+$X+$Y" -noxdamage -repeat -quiet -bgスクリプトの全体は share.sh(PC側)と pcapp(Brain側)。作ってみて分かったことを挙げる。
| 分かったこと | 対処 |
|---|---|
| GTKのアプリは、ウィンドウの周りに見えない影の領域を持つ | _GTK_FRAME_EXTENTS を読み、その分を引いて位置と大きさを決める。 |
| 半透明のウィンドウだと、後ろのウィンドウが透けて映る | 共有中だけ _NET_WM_WINDOW_OPACITY を不透明にして、終わったら戻す。 |
| 最小サイズが大きくて、446の高さにできないアプリがある | 少し大きく(1058×600)取り、x11vnc -scale 786x446 で縮めて配る。文字は約74%になるが読める。 |
| 画面の半分に寄せたウィンドウを戻すと、全画面になってしまう | 最大化の状態を、縦と横で別々に記録して戻す。 |
| PCがロックされると、操作できなくなる | 映す範囲を、ロック画面の中央(パスワードの入力欄)に切り替える。Brainのキーボードでパスワードを入れると、PC本来のロック画面が確認する。パスワードなしで解除する仕組みは作らない。 |
| 日本語が打てない | 本体のキーに半角/全角を割り当てる。PCの日本語入力が、そのまま使える。 |
映しているのは1つのウィンドウでも、Brainからのキー操作はPCのデスクトップ全体に届く。Brainにログインできる人は、PCを操作できることになる。Brain側のアカウントのパスワードは、推測されにくいものにする。
うまくいかなかった方法もある。アプリを一度終了し、仮想デスクトップ側で起動し直す方式は、動きはするが、実行中の作業が止まる。アプリの環境変数(/proc/PID/environ)から表示先を調べようとしたが、アプリが起動後にその領域を書き換えていて、読めなかった。
11
うまくいっていないこと
| 項目 | 状況 |
|---|---|
| 電源オフ | シャットダウン後に自動で起動し直す。5 Vの検出の出どころが不明。 |
| Bluetooth / WireGuard | カーネルに入れただけ。接続は未確認。 |
| イヤホン | 未確認。挿抜の検出なし。 |
| バッテリーの充電 | Brainuxは充電回路を止めたまま動く。回路をオンにする試験では、電池に電流が流れなかった。原因は未切り分け。 |
| microSDの読み取りエラー | PCのカードリーダーで、読み取りエラーが散発した。読み直すと正常で、ファイルは壊れていない。カードかリーダーかは未切り分け。 |
| Wi-Fiの接続 | 同じ名前のアクセスポイントが2台あり、起動時につなぎ直す。IPアドレスが変わることがある。 |
キーボードの修正と音声のドライバは、ほかのBrainの利用者にも役に立つはずだが、まだ本家には送っていない。
12
参照資料と公開範囲
- Brainux導入手順、対応機種、起動の仕組み。まずここを読む。
- brain-hackers/buildbrainカーネル、U-Boot、イメージのビルド環境。リリースのイメージもここにある。
- brain-hackers/linux-brainBrain用のカーネル。キーボードドライバとデバイスツリーはここ。
- ROHM BU26154MUV 製品ページ音声ICのデータシート。レジスタと、クロックの条件。
- x11vnc / TigerVNC画面の一部を配る
-clipと、仮想デスクトップ。
本文は2026年10月2日〜5日の実機での作業記録をもとに編集。家庭内のアドレス、無線LANの名前、アカウント名、認証情報、機器の名前、私用の画面は掲載していません。写真は撮影情報を取り除き、基板の管理ラベルを隠しています。掲載したファイルは、カーネルへの変更(GPL-2.0)と、作業用のスクリプトです。動作は PW-SH3 の1台で確かめた範囲に限ります。