ご無沙汰していますが、MANOMAネタで書きます。
前回記事ではAIホームゲートウェイ「MANOMA NCP-HG100」で開示されているLinuxのソースを使用して armhf な Debian を起動してみた、といった内容を書きました。
今回はその前回執筆時には使用できなかったネットワークインタフェースにドライバを当てることでネットワークを使える Debian にしていきます。
まずはどうなっているのか見る
困ったときの デバイスツリー の確認です。MANOMAをいじり始めてその存在を知ったんですが、ARM系のデバイスはどこに何がつながっているのかをデバイスツリーという形式で定義しておくらしいです。
arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1-c4.dts
というファイルが NCP-HG100 のデバイスツリーのソースファイルです。依存する qcom-ipq4019.dtsi
, qcom-ipq4019-ap.dk04.1.dtsi
, qcom-iqp4019-audio.dtsi
, qcom-ipq4019-mhi.dtsi
あたりも参照する必要があります。
ネットワークインタフェースの定義は qcom-ipq4019.dtsi
の 843行目あたりの
edma@c080000 { compatible = "qcom,ess-edma"; reg = <0xc080000 0x8000>;
とあります。
ここで重要なのが qcom,ess-edma
という compatible
の値です。この値でドライバはデバイスを見つけにいくので(ここの表現あってるかはわからない)、この値を見つけにいくドライバがカーネルに含まれていなければドライバが当たらず使用できない、という事象が発生します。
結論から言ってしまうと、配布されている linux-4.4
には含まれていませんでした。つまり、カーネルのビルドとは別にビルドされている可能性が高そうです。
ここで、QSDK を見てみますと…
qca/src/qca-edma/edma_aci.c
static const struct of_device_id edma_of_mtable[] = { {.compatible = "qcom,ess-edma" }, {} };
ありますねえ!!
つまり、QSDKでビルドしたものでは、ビルドされたこの qca-edma
を modprobe しているからネットワークが使えるんですね。ということでビルドして使えるようにしていきましょう。
と言いたいところですが、実際にmodprobe している順番をみてみると↓のように
- qrfs
- qca-ssdk
- qca-edma
の順番でロードしているようです。今回はこの3つをビルドします。
手順
というわけで、ビルド手順です。
必要なもの
それぞれ QSDK と同じリポジトリからダウンロードします。
在り処と使用されているブランチを確認するにはマニフェストファイルを確認すればいいのですが、NCP-HG100 で使用されたマニフェストは不明なのでエイヤでこれを使います↓
https://source.codeaurora.org/quic/qsdk/releases/manifest/qstak/tree/caf_AU_LINUX_QSDK_DATE_4.4_TARGET_ALL.10.0.3019.xml?h=release
上記URLより一部抜粋したものが下記。
<project name="quic/qsdk/oss/lklm/qca-edma" path="qsdk/qca/src/qca-edma" revision="e0efb01b44d45a6dff5f944238f6de3255afcc1b" upstream="nss"/> <project name="quic/qsdk/oss/lklm/qca-rfs" path="qsdk/qca/src/qca-rfs" revision="709b93474e60aaf4d884d3d16c1435d8b5f0f90b" upstream="nss"/> <project name="quic/qsdk/oss/lklm/qca-ssdk" path="qsdk/qca/src/qca-ssdk" revision="d84da8955bc4eecbb164bdd729b7862a89523bcb" upstream="master"/>
上記を参考に
git clone https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-edma -b nss git clone https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-rfs -b nss git clone https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-ssdk -b master
としてソースコードをクローンしてきます。
qca-edma, qca-rfs のビルド
qca-edma, qca-rfs のビルドは比較的かんたんです。
qca-edma のビルド
cd qca-edma make -C $LINUX_SOURCE_DIR M=$PWD ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
$LINUX_SOURCE_DIR
にはソニーが公開している linux-4.4 を展開したディレクトリを指定します。
ここでエラーが出るんですが、
if (res < 0)
となっているかしょを
if(false) //if (res < 0)
とすることで回避可能です。(これ本来ビルドのオプションで殺すべきかもしれませんが、詳しくないのでよくわかりません)
ビルドして出てきた essedma.ko
を取っておきます。
qca-rfs
cd qca-rfs make -C $LINUX_SOURCE_DIR M=$PWD ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
同じです。
今回もエラーになるので、下記のように修正しました。(いいのか
/* * rfs_rule_exit() */ void rfs_rule_exit(void) { // struct rfs_rule *rr = &__rr; RFS_DEBUG("RFS Rule exit\n"); // if (rr->proc_rule); remove_proc_entry("rule", rfs_proc_entry); rfs_rule_destroy_all(); }
出てきた qrfs.ko
を取っておきます。
qca-ssdk のビルド
これが鬼門です。
まずはソースコードを修正します。
src/init/ref_port_ctrl.c の修正。90行目、Linuxのバージョンが4.4.60以降は~という条件分が入っていますが、配布されているlinux-4.4ではFAL_SPEED_2500が未定義というエラーが出るので4.4.61以降に書き換えます(この修正が必要なのはわけがわからん。)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,61))
次に、 src/init/ssdk_dts.c。ssdk_dts.c:320:13: error: ‘ssdk_dt_parse_uniphy’ defined but not used [-Werror=unused-function]
というエラーが出てしまうので、もう含めないようにしてしまいます。319行目の定数に_A
を付け加えて別物に変えてしまいます。
#ifdef IN_UNIPHY_A
最後に、 config
を修正します。 -fno-pic
が指定されずにビルドされるとビルドはできるものの動かない代物ができあがるので付けます。
117行目の CPU_CFLAG
に -fno-pic
を追加します。
ifeq ($(KVER),$(filter 4.9% 4.4% 5.4%,$(KVER))) CPU_CFLAG= -fno-pic -DMODULE -nostdinc -D$(BOARD_NAME) -mlittle-endian -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=2048 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(mem)" endif
で、いざビルド
make -f Makefile M=$PWD ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- TOOL_PATH=$PWD/tos/bin SYS_PATH=$LINUX_SOURCE_DIR KVER=4.4.60 TOOLPREFIX=arm-linux-gnueabihf- TARGET_NAME=arm-linux-gnueabihf
で、ここでさらに困ったことに、Makefile はクロスコンパイルへの配慮がなく、死ぬので、クロスコンパイルする際は
ln -s /usr/lib/gcc-cross/arm-linux-gnueabihf /usr/lib/gcc/arm-linux-gnueabihf
として、シンボリックリンクを張るといいのではないかなと思います。なんとかする方法あれば教えていただきたいです。
で、できあがった build/bin/qca-ssdk.ko
を取っておきます。
使ってみる
上記の手順でできあがった
- qrfs.ko
- qca-ssdk.ko
- essedma.ko
をUSBメモリなどでMANOMA側で読み取って使ってみます。
modprobe nf_nat insmod qrfs.ko insmod qca-ssdk.ko insmod essedma.ko
依存関係があるので、正しい順序で読み込まなければなりません。
ここまで行えば、普段どおり使用することができるようになるので、/etc/network/interfaces
を書くなどしてセットアップします。
DHCPのクライアントもちゃんと動いてハッピー。apt-get
もできました。
例によってパーミッションがぐちゃぐちゃになってますが、、、(debootstrap の使い方ちゃんと勉強しよう・・・)
終わりに
以上、NCP-HG100でネットワークを使用可能にする方法でした。良いお年を!