おはよう君需要なし

求不得苦な日々

SONY NCP-HG100 のネットワーク用のドライバをビルドする

ご無沙汰していますが、MANOMAネタで書きます。

nodemand.hatenablog.com

前回記事では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 している順番をみてみると↓のように

  1. qrfs
  2. qca-ssdk
  3. 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 を取っておきます。

使ってみる

上記の手順でできあがった

  1. qrfs.ko
  2. qca-ssdk.ko
  3. essedma.ko

USBメモリなどでMANOMA側で読み取って使ってみます。

modprobe nf_nat
insmod qrfs.ko
insmod qca-ssdk.ko
insmod essedma.ko

依存関係があるので、正しい順序で読み込まなければなりません。

ここまで行えば、普段どおり使用することができるようになるので、/etc/network/interfaces を書くなどしてセットアップします。

f:id:yoh_mar28:20201231235718p:plain
使えるようになったぞ

DHCPのクライアントもちゃんと動いてハッピー。apt-get もできました。

f:id:yoh_mar28:20201231235832p:plain
apt-get

例によってパーミッションがぐちゃぐちゃになってますが、、、(debootstrap の使い方ちゃんと勉強しよう・・・)

終わりに

以上、NCP-HG100でネットワークを使用可能にする方法でした。良いお年を!