PQI Air Cardをタニタの体重計で動かそうとして失敗し悲しみに暮れているところ。
ふと、ダイナミックDNSサービスの設定を変更する自作Pythonスクリプトの存在を思い出した。
ルータのWeb画面に表示されるグローバルIPアドレスの変更を検知する簡単なもの。
今も実家の古いPCで動いているがいつ壊れるか分からない。
その程度の処理であればPQI Air Cardの組み込みLinuxでも十分可能だろうと考えたのでやってみた。
いざ動作させようと思ってはみたものの、Pythonスクリプトの動作環境が無ければ話が始まらない。
PQI Air Cardは純正でCGI動作用のPerlが入っているが、Pythonは入っていない模様。
有志によりRubyはビルドされているようだが、Pythonは存在しないので自前でビルドせざるを得ない。
以下は手元のLinux PC (Ubuntu)の作業メモ
PQI Air Cardの環境を確認する
CPU
# cat /proc/cpuinfo Processor : ARM926EJ-S rev 5 (v5l) BogoMIPS : 25.24 Features : swp half fastmult edsp java CPU implementer : 0x41 CPU architecture: 5TEJ CPU variant : 0x0 CPU part : 0x926 CPU revision : 5 Hardware : KeyASIC Ka2000 EVM Revision : 0000 Serial : 0000000000000000
arm926ej-s(arm v5l)らしい
起動パラメータ
# cat /proc/cmdline root=/dev/ram0 rw console=ttyS0,38400n8 mem=32M initrd=0x500000,3M
メモリ
32MBなので大事に使おう。
# cat /proc/meminfo MemTotal: 29652 kB MemFree: 11196 kB Buffers: 732 kB Cached: 13896 kB
クロスコンパイル環境の構築
ARM向けGNU Toolchainを入手する
CodeSourceryのARM向けSourcery CodeBench Liteを選択するが、今は公開を停止している。
検索すれば見つかりそうだけど・・・Sourcery CodeBench Lite releases for ARM EABI, ARM GNU/Linux, ARM AARCH64-Linux, IA32/IA64 GNU/Linux and ELF are no longer available.
LauchpadのToolchainはsys/dirent.hがnot supportedでエラーになる。
展開してパスを通す
クロスコンパイル環境を使えるようにする。
$ tar xf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ mv arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu ~/arm-dev-sc $ ln -s ~/arm-dev{-sc,} $ echo 'export PATH=$PATH:~/arm-dev/bin' >> ~/.bashrc $ . ~/.bashrc
パスが通ると、補完が効くようになっているはず。
$ arm-<TAB> arm-none-linux-gnueabi-addr2line arm-none-linux-gnueabi-gcc-ranlib arm-none-linux-gnueabi-ar arm-none-linux-gnueabi-gcov arm-none-linux-gnueabi-as arm-none-linux-gnueabi-gdb arm-none-linux-gnueabi-c++ arm-none-linux-gnueabi-gprof arm-none-linux-gnueabi-c++filt arm-none-linux-gnueabi-ld arm-none-linux-gnueabi-cpp arm-none-linux-gnueabi-nm arm-none-linux-gnueabi-cs arm-none-linux-gnueabi-objcopy arm-none-linux-gnueabi-cs-daemon arm-none-linux-gnueabi-objdump arm-none-linux-gnueabi-elfedit arm-none-linux-gnueabi-ranlib arm-none-linux-gnueabi-g++ arm-none-linux-gnueabi-readelf arm-none-linux-gnueabi-gcc arm-none-linux-gnueabi-size arm-none-linux-gnueabi-gcc-4.8.3 arm-none-linux-gnueabi-strings arm-none-linux-gnueabi-gcc-ar arm-none-linux-gnueabi-strip arm-none-linux-gnueabi-gcc-nm
ビルド
Pythonソースコードとパッチの準備
クロスコンパイル環境を整えたPCにPythonソースコードとクロスコンパイル用パッチをダウンロードする。
動かしたいスクリプトはPython2向けに書いたので、Pythonのバージョンはパッチに合わせて2.7.3にする。$ wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2 $ wget http://randomsplat.com/wp-content/uploads/2012/10/Python-2.7.3-xcompile.patch
ホスト用Pythonの準備
クロスコンパイルで使うPython(buildpython,buildpgen)をビルドする。
$ tar xf Python-2.7.3.tar.bz2 && cd Python-2.7.3 $ ./configure $ make python Parser/pgen $ mv python buildpython $ mv Parser/pgen buildpgen $ make distclean
クロスコンパイル用パッチを適用
$ patch -p1 < ../Python-2.7.3-xcompile.patch patching file configure patching file Makefile.pre.in patching file setup.py
ARM向けにconfigure
$ CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ AR=arm-none-linux-gnueabi-ar RANLIB=arm-none-linux-gnueabi-ranlib BASECFLAGS=-mcpu=arm926ej-s \ ./configure --host=arm-none-linux-gnueabi --build=x86_64-linux-gnu --prefix=/usr
ARM向けにmake
$ make HOSTPYTHON=./buildpython HOSTPGEN=./buildpgen CROSS_COMPILE=arm-none-linux-gnueabi- CROSS_COMPILE_TARGET=yes HOSTARCH=arm-none-linux-gnueabi BUILDARCH=x86_64-linux-gnu
一部のモジュールは外部のライブラリとリンクできないので使えないらしい。
Python build finished, but the necessary bits to build these modules were not found: _bsddb _curses _curses_panel _sqlite3 _ssl _tkinter bsddb185 bz2 dbm dl gdbm imageop nis readline sunaudiodev zlib To find the necessary bits, look in setup.py in detect_modules() for the module's name.
圧縮アルゴリズムや簡易データベース接続など、機能の一部を外部に求めるモジュールは使用できない。
ビルドされたpythonバイナリにreadelfしてみた。
$ arm-none-linux-gnueabi-readelf -a ./python | grep 'Shared library' 0x00000001 (NEEDED) Shared library: [libpthread.so.0] 0x00000001 (NEEDED) Shared library: [libdl.so.2] 0x00000001 (NEEDED) Shared library: [libutil.so.1] 0x00000001 (NEEDED) Shared library: [libm.so.6] 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x00000001 (NEEDED) Shared library: [libc.so.6]
リンクされているのはPQI Air Cardにも存在するライブラリ類のみだった。
実行時のメモリ節減のためスタティックリンクはやめておいた。rootfsに転送するファイルをまとめる
$ make install HOSTPYTHON=./buildpython CROSS_COMPILE=arm-none-linux-gnueabi- CROSS_COMPILE_TARGET=yes prefix=`pwd`/_install
stripして縮める
$ cp -rf _install{,_strip} $ ls -1 _install_strip/lib/python2.7/lib-dynload/*.so | xargs -n1 arm-none-linux-gnueabi-strip
FATのファイルシステムではsymlinkを使えないので、実体を使うように変更するとか細かい部分は適宜調整する。
PQI Air Cardに転送
追加コマンド類の整備
せっかくなので、@tonsuke85氏、@osakanataro氏の成果物を利用する。
Flucard向けに纏められているdeploy_20120420.zipが、PQI Air Cardでも利用可能なので導入する。autorun.shを自分向けに改変する。
#!/bin/sh ln -s /mnt/sd/DCIM/122_TREK/bin/* /bin/ ln -s /mnt/sd/DCIM/122_TREK/usr/bin/* /usr/bin/ ln -s /mnt/sd/DCIM/122_TREK/usr/local /usr/local ln -s /mnt/sd/DCIM/122_TREK/usr/lib /usr/lib ln -s /mnt/sd/DCIM/122_TREK/usr/include /usr/include ln -s /mnt/sd/DCIM/122_TREK/usr/libexec /usr/libexec ln -s /mnt/sd/DCIM/122_TREK/sbin/* /sbin/ rm /lib/libpthread.so.0 ln -s /mnt/sd/DCIM/122_TREK/lib/* /lib/ ln -s /mnt/sd/DCIM/122_TREK/etc/* /etc/ ln -s /mnt/sd/DCIM/122_TREK/www/cgi-bin/connect2hotspot.cgi /www/cgi-bin/ rm /bin/vi ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/vi ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/top ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/awk ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/dd rm /usr/bin/hexdump ln -s /mnt/sd/DCIM/122_TREK/busybox /usr/bin/hexdump ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/killall ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/less ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/passwd ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/sed ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/tar rm /usr/bin/telnet ln -s /mnt/sd/DCIM/122_TREK/busybox /usr/bin/telnet ln -s /mnt/sd/DCIM/122_TREK/busybox /bin/whoami if [ -e /mnt/sd/enable_sshd ]; then if [ -s /mnt/sd/enable_sshd ]; then dropbear -A -N root -C '-' -U 0 -G 0 -R /mnt/sd/DCIM/122_TREK/authorized_keys -s else dropbear -A -N root -C password -U 0 -G 0 fi fi if [ -e /mnt/sd/disable_telnetd ]; then killall telnetd fi if [ -e /mnt/sd/enable_ftpd ]; then killall tcpsvd tcpsvd 0 21 ftpd -w / & fi if [ -e /mnt/sd/enable_cron ]; then ln -s /mnt/sd/DCIM/122_TREK/busybox /usr/sbin/crond ln -s /mnt/sd/DCIM/122_TREK/busybox /usr/bin/crontab touch /etc/crontab mkdir -p /var/spool/cron/crontabs touch /var/spool/cron/crontabs/root /usr/sbin/crond -L /dev/null fi if [ -e /mnt/sd/enable_wifista ]; then sleep 5 /usr/bin/w2 & fi
/mnt/sd以下に特定の名前のファイルを設置すると、動作が変わるようにした。
- /mnt/sd/enable_sshdファイルがあればsshdを起動する
- /mnt/sd/enable_sshdファイルのファイルサイズが1以上なら公開鍵認証モード
(鍵は/mnt/sd/DCIM/122_TREK/authorized_keys) - /mnt/sd/enable_sshdファイルのファイルサイズが0ならパスワード認証モード
(パスワードはpassword)
- /mnt/sd/enable_sshdファイルのファイルサイズが1以上なら公開鍵認証モード
- /mnt/sd/disable_telnetdファイルがあればtelnetdを止める
- /mnt/sd/enable_ftpdファイルがあればルートディレクトリにアクセスできるftpdを起動する
- /mnt/sd/enable_cronファイルがあればcrondとcrontabを有効にして、crondを起動する
- /mnt/sd/enable_wifistaファイルがあればWi-FiをSTAモード(クライアントモード)で起動する
- /mnt/sd/enable_sshdファイルがあればsshdを起動する
ビルドしたPythonを導入
_install_strip以下のbin/とlib/を上記で展開したDCIM/122_TREK/usr以下にコピーする。
DCIMディレクトリごとPQI Air CardのSDカードに転送する。
動作確認
# /mnt/sd/DCIM/122_TREK/busybox uname -a
Linux (none) 2.6.32.28 #4 PREEMPT Thu Jul 11 15:51:47 JST 2013 armv5tejl GNU/Linux
# python
Python 2.7.3 (default, Mar 1 2015, 19:57:36)
[GCC 4.8.3 20140320 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.uname()
('Linux', '(none)', '2.6.32.28', '#4 PREEMPT Thu Jul 11 15:51:47 JST 2013', 'armv5tejl', '')
>>> platform.version()
'#4 PREEMPT Thu Jul 11 15:51:47 JST 2013'
>>> platform.machine()
'armv5tejl'
>>>
件のスクリプトはcronで動かす。
*/5 * * * * root /mnt/sd/ddnsup/ddns_update.sh
参考文献
- CloudFlash(arm926ej-s)でPythonを動かす
- Cross Compiling Python for Embedded Linux
- デジカメ内部でRubyを動かす狂気!無線LAN内蔵SDカードアダプタPQI Air Cardの間違った使い方
- FlucardでプログラムとかCGIとか
おわり
PQI Air Card Wi-Fi内蔵SDカードアダプタ (アダプタのみモデル) 6W21-0000R1 PQI 2012-10-01 売り上げランキング : 6934 Amazonで詳しく見る by G-Tools |
コメント