この手順の目次
ここでは純正ソースの調査と無送信probeのビルドを具体化します。純正SH-02Eにはモジュール許可制限があり、作った.koを通常のadb shellからinsmodするだけでは動きません。実験で使った特権初期化ツールは未配布です。
1. 対応する純正ソースを取得する
SHARPのSH-02Eソース公開ページで、build 02.00.06に対応する公開物を選ぶ。取得したアーカイブのハッシュを記録する。この実験で保存したkernel.tar.gzのSHA-256は次の値だった。ローカルの同一性確認値であり、メーカーの署名ではない。
e9602a325fc9c59099e71cdc73849fdd3fb9d802247ba3cab40f5ed1b7e39ae9# ダウンロード済みのファイルを確認。展開先は新しい作業ディレクトリにする
sha256sum kernel.tar.gz
tar -tzf kernel.tar.gz | head -30
mkdir -p kernel-source
tar -xzf kernel.tar.gz -C kernel-source
# Makefileとarch/を持つカーネルのルートを指定する
read -rp 'Extracted kernel source root: ' KERNEL_SRC
KERNEL_SRC=$(realpath "$KERNEL_SRC")
export KERNEL_SRC
find "$KERNEL_SRC" -name '*lynx*defconfig' -print取得元がHTTPに誘導する場合は通信経路も記録する。証明書エラーを無効化してHTTPSの検証を迂回しない。アーカイブの中身やバージョンが変わった場合は、以前のハッシュ値だけを信じて処理を続けない。
2. IR端子とロード制限をソースで確認する
rg -n 'GPIO|gpio|shutdown|SHUTDOWN' \
"$KERNEL_SRC/drivers/sharp/shirda"
rg -n 'shirda|GSBI4|IRDA' \
"$KERNEL_SRC/arch/arm/mach-msm"
rg -n 'sha256|SHA256|shexfat|hash' \
"$KERNEL_SRC/kernel/module.c"
rg -n 'CONFIG_MODULES|CONFIG_MODVERSIONS' \
"$KERNEL_SRC/arch/arm/configs/lynx_dl20_defconfig"調査で確認したTX / RX / shutdownはGPIO 10 / 11 / 81。純正ゲートは/dev/msm_shirda、UART経路は/dev/ttyHS0だった。ソースの定数と実機のバイナリ・端子状態を照合する。公開ソースをビルドしたSystem.mapと実機Imageの関数位置が一致しない例もあった。
3. カーネルのビルド条件を合わせる
カーネル用はARM EABI 4.6系のツールチェーンを使用した。APK用のNDK clangとは別物である。次は作業の順序を示すテンプレートで、古いカーネルを現在のホストでビルドするための互換修正一式まで提供するものではない。
# arm-eabi-gcc等を導入した場所の「接頭辞」を入力する
# 例: /path/to/toolchain/bin/arm-eabi-
read -rp 'ARM EABI toolchain prefix: ' CROSS_COMPILE
export CROSS_COMPILE
"${CROSS_COMPILE}gcc" --version
KERNEL_OUT="$PWD/kernel-build"
mkdir -p "$KERNEL_OUT"
make -C "$KERNEL_SRC" O="$KERNEL_OUT" ARCH=arm \
CROSS_COMPILE="$CROSS_COMPILE" lynx_dl20_defconfig
# defconfigは出発点。実機の構成と差分を照合してから続ける
rg 'CONFIG_MODULES=|CONFIG_MODVERSIONS=' "$KERNEL_OUT/.config"
# 完全ビルドでModule.symversも生成する
make -C "$KERNEL_SRC" O="$KERNEL_OUT" ARCH=arm \
CROSS_COMPILE="$CROSS_COMPILE" -j2 zImage modules
test -s "$KERNEL_OUT/Module.symvers"
rg 'module_layout' "$KERNEL_OUT/Module.symvers"CONFIG_MODVERSIONS=yの場合、modules_prepareだけでは必要なModule.symversが揃わない。Linuxの外部モジュール用ビルド資料も参照する。実験では純正モジュールとmodule_layout CRC 0xdce5b579を照合した。CRCが一つ一致することだけで、全シンボル・ABIの互換性が保証されるわけではない。
4. まず無送信probeをビルドする
以下は読み込まれたことをログへ書くだけの小さなモジュール。GPIOやタイマーには触らない。このサンプルはビルド対象を示すためのもので、送信ドライバではない。
mkdir -p probe
cat > probe/ir_probe.c <<'C'
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/module.h>
#include <linux/init.h>
static int __init ir_probe_init(void)
{
pr_info("ir_probe: loaded; no hardware access\n");
return 0;
}
static void __exit ir_probe_exit(void)
{
pr_info("ir_probe: unloaded\n");
}
module_init(ir_probe_init);
module_exit(ir_probe_exit);
MODULE_LICENSE("GPL");
C
printf 'obj-m += ir_probe.o\n' > probe/Makefile
make -C "$KERNEL_SRC" O="$KERNEL_OUT" ARCH=arm \
CROSS_COMPILE="$CROSS_COMPILE" M="$PWD/probe" modules
file probe/ir_probe.ko
modinfo -F vermagic probe/ir_probe.ko
sha256sum probe/ir_probe.koロードは、特権取得・モジュール許可値の照合と一時変更・復元を確立してから行う。rootを取得できたことだけでは許可ハッシュ制限を通過できない。この記事は汎用のinsmodコマンドやboot書き換えで、この工程を省略できるとは案内しない。
5. 送信準備を状態読み出しで確かめる
独自の送信モジュールとアプリを初期化できた場合の確認コマンド。PHONE_ADBは環境準備ページで設定した対象端末を指す。
adb -s "$PHONE_ADB" shell cat /proc/modules
adb -s "$PHONE_ADB" shell ls -l \
/dev/msm_shirda /dev/ttyHS0 /dev/sh02e_ir
adb -s "$PHONE_ADB" shell cat /dev/sh02e_ir| 確認点 | 期待する内容 |
|---|---|
| モジュール | sh02e_gpio_irがロードされている。 |
| 状態出力 | api=3、タイマー進行がある。初期化直後はframes=0でよい。 |
| /dev/msm_shirda | infrared : アプリの実GID、0660。 |
| /dev/ttyHS0 | infrared : infrared、0660。 |
| /dev/sh02e_ir | root : アプリの実GID、0664。 |
アプリUIDは個体・インストール状態に依存する。固定番号やchmod 777で合わせない。初期化後の通常設定ではADB shellから直接送信する書き込みは許可していない。純正ゲートも必要なので、単純なechoで/dev/sh02e_irへ書けばよいわけではない。
6. 信号を採って照合する
物理リモコンから同じボタンを複数回採取し、完全な同一フレームを2件以上得る。受信ツールは別途必要。UARTのchunkを光のエッジとして扱わず、leader・bit数・区間長・反転値を確認する。
NECバイト列の照合スクリプトを用意した。これは既にデコードされた4-byteフレームの反転値と一致数を検査するだけで、波形のデコードや家電の反応を検証するツールではない。
curl -fSLo nec-check.py \
https://hacks.hacci.dev/sh-02e-ir-remote/examples/nec-check.py
# 内容を読んでから使う
less nec-check.py
# 合成した教材データ。家電へ送信するためのコードではない
cat > samples.txt <<'DATA'
00 FF 12 ED
00 FF 12 ED
DATA
python3 nec-check.py samples.txt期待する表示は00 FF 12 ED: 2 frame(s); repeated=True。1件だけならrepeated=False、4 bytesでなければエラー、コマンド反転値が違えばエラーになる。2件の一致もタイミング精度や有効な家電コードである証明にはならない。