MINI NVR(hi3515)を軽くハックした話

imag1487

一年ほど前に無料でネットワークビデオレコーダを手に入れてちょっとだけハックしてたのですが、最近また再開した話です。

ネットワークビデオレコーダというのは、ネットワークカメラを録画したりモニタするのに使われるSTBのようなものです。国内ではあまり知られていませんが、Aliexpressではメジャーな製品で、$20程度でたくさん見つけることが出来ます。

構成としてはこんな感じです

  • SoC: Hi3515 (ARM Cortex A9, H.264 encoding/decoding)
  • RAM: 142MB
  • SPI Flash: 32MB (MX25L25635E/735E/635F)
  • U-boot 2010.06
  • Linux 3.0
  • 有線LAN、USB2.0x2、RTC、HDMI、eSATA

まずはシリアル=UARTピンをはんだ付けします。UARTは3.3Vレベルと5Vレベルがありますが、常時どちらかが印加されていて、起動時に電圧が振れるピンがあれば、TX(送信)の可能性があります。UART-USBはAmazonで数百円で買えます。TX,RX,GNDの3ピンのランドがあれば正解なので、ピンをはんだ付けしてしまいましょう。

U-Boot 2010.06 (Dec 05 2013 - 16:53:16)

Check spi flash controller v350... Found
Spi(cs1) ID: 0xC2 0x20 0x19 0xC2 0x20 0x19
Spi(cs1): Block:64KB Chip:32MB Name:"MX25L25635E/735E/635F"
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
32768 KiB hi_sfc at 0:0 is now current device

mmu_enable

のように出てきたら当たりです。そのままLinuxのシェルに入りましょう。今回はたしかシリアルにはパスワードが設定されていなかったのでヌルゲーです。設定されていた場合は、別のrootfsを使用するなど一気にハードルが上がります。

次に調査をします。u-bootでprintenvをします。これで色々な情報が得られます

hisilicon # printenv
bootargs=mem=142M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=squashfs mtdparts=hi_sfc:320K(uboot),1536K(kernel),4M(rfs),25792K(app),768K(config),256K(logo)
bootcmd=sf probe 0;sf read 0x82000000 0x50000 0x180000;bootm 0x82000000
bootdelay=1
baudrate=115200
ethaddr=00:00:23:34:45:66
uboot_postfix=.bin.3520d
kernel_postfix=.img.3520d
rfs_postfix=.squashfs.3520d
cfg_postfix=.jffs2.3520d
logo_postfix=.jpeg.3520d
ipaddr=192.168.1.10
serverip=192.168.1.2
netmask=255.255.254.0
bootfile="uImage"
stdin=serial
stdout=serial
stderr=serial
verify=n
jpeg_addr=809ce458
jpeg_size=0x40000
vobuf=80838200
ver=U-Boot 2010.06 (Dec 05 2013 - 16:53:16)

Environment size: 649/65532 bytes
# cat /proc/mtd            
dev:    size   erasesize  name
mtd0: 00050000 00010000 "uboot"
mtd1: 00180000 00010000 "kernel"
mtd2: 00400000 00010000 "rfs"
mtd3: 01930000 00010000 "app"
mtd4: 000c0000 00010000 "config"
mtd5: 00040000 00010000 "logo"
#cat /etc/init.d/S03ants
#!/bin/sh
/usr/sbin/hotplug &

#insmod /ko_hi3521/extdrv/mtdram.ko total_size=15360  erase_size=64
#dd if=/dev/mtdblock3 of=/dev/mtdblock6
#mount -o loop -t cramfs /dev/mtdblock6 /root/
mount -t jffs2 /dev/mtdblock3 /root/
mount -t jffs2 /dev/mtdblock3 /update

cd /ko
./load3520D -i

cd /root/ko_app
insmod usb_wwan.ko
insmod option.ko
#insmod sd_mod.ko
insmod jbd.ko
insmod mbcache.ko
insmod ext3.ko
insmod gpioi2c.ko
insmod rt5370sta.ko
insmod slhc.ko
insmod ppp_generic.ko
insmod ppp_synctty.ko
insmod ppp_async.ko

mount -t jffs2 /dev/mtdblock4 /usr/etc
updateclear
mkdir /usr/etc/tmp
mkdir /usr/etc/var
mkdir /usr/etc/var/run
mkdir /usr/etc/var/lock
mkdir /usr/etc/ppp
mkdir /usr/etc/ppp/peers
rm /usr/etc/tmp/qtembedded-0/fonts/fontdb

ln -s /root/web /usr/etc/web


cp /usr/sbin/ppp-off                            /etc/ppp/peers/
cp /usr/sbin/wcdma-chat-disconnect              /etc/ppp/peers/

ifconfig eth0 192.168.1.188
hwclock -s
telnetd &
mount -t usbfs usbfs /proc/bus/usb/
export LD_LIBRARY_PATH="/usr/local/lib:/usr/lib:/root:/root/host_libs:/root/ipc_libs:/mnt"
export TERMINFO=/usr/local/share/terminfo
export QWS_KEYBOARD=tty:/dev/ttyS2
export QWS_KEYBOARD_TYPE=3520chpd
export QWS_MOUSE_PROTO=auto:/dev/mouse0

sysinit &
sleep 1
cd /root
/etc/startusb
./ants_dvr -qws &




# cat /etc/init.d/rcS
#! /bin/sh

/bin/mount -a

echo "
            _ _ _ _ _ _ _ _ _ _ _ _
            \  _  _   _  _ _ ___
            / /__/ \ |_/
           / __   /  -  _ ___
          / /  / /  / /
  _ _ _ _/ /  /  \_/  \_ ______
___________\___\__________________
"
for initscript in /etc/init.d/S[0-9][0-9]*
do
        if [ -x $initscript ] ;
        then
                echo "[RCS]: $initscript"
                $initscript
        fi
done


# cat /etc/init.d/S80network 
#!/bin/sh

ifconfig lo 127.0.0.1

echo "1048576" > /proc/sys/net/core/rmem_default
echo "4048576" > /proc/sys/net/core/rmem_max
echo "2048576" > /proc/sys/net/core/wmem_max
#echo 2000 > /proc/sys/vm/min_free_kbytes
# mount
rootfs on / type rootfs (rw)
/dev/root on / type squashfs (ro,relatime)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/mtdblock3 on /root type jffs2 (rw,relatime)
/dev/mtdblock3 on /update type jffs2 (rw,relatime)
/dev/mtdblock4 on /usr/etc type jffs2 (rw,relatime)
usbfs on /proc/bus/usb type usbfs (rw,relatime)

こんな感じです。このあと、なぜかrootfsをふっ飛ばしてしまい、1年ほど放置してました。

久々に触ろうと思ったのは、会社に組み込みに強い方が入ってきたので雑談したところ、rootfsを簡単に作れるBuildrootというソフトウェアを教えてもらったのがきっかけでした。これはとても強力なツールで、menuconfigで設定するだけで開発環境の構築からrootfsの構築、イメージ化まですべてをやってくれます。

buildrootで作ったsquashfsのrootfsイメージをu-bootでSPI Flashに書き込みます。

fatload usb 0:1 0x80000000 rootfs.squashfs
sf erase 0x1d0000 0x1f0000
sf write 0x80000000 0x1d0000 0x1f0000
sf read 0x80000000 0x1d0000 0xf0
md 0x80000000

最後のreadとmdは確認用です。0x80000000からが自由に使える領域なので、そこにUSBメモリからファイルを読み込み、Flashの該当領域を消して(必須)、書き込みました。アラインメントが64KiBなので領域はぴったりにalignしないと怒られるので注意が必要です。電卓で計算しました。

これで無事boot成功…とはいかず、複数の穴にハマりました。ここまでもはまってますが、省略しています。

JFFS2はkernel versionが古い(Linux 3.0)せいかjffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00270000: 0x1105 insteadというのが大量に出るので、元と同じsquashfsにしました。

getty: can’t open ‘/dev/null’: No such file or directory
というのが定期的に出る上、ttyにもアクセスできない状態でしたが、/devをstatic device tableにしたところ、正常に動作するようになりました。これはkernelのコンパイルオプションが原因のようですが、今回はカーネルは触らないつもりなのでどうしようもありません。

これでログインプロンプトに入れました。

Welcome to Buildroot
buildroot login: root
# 

まずはネットワーク設定をします。

ip a
ip link set dev eth0 up
ip a 192.168.1.123/24 dev eth0
ip route add 192.168.1.0/24 dev eth0

これでpingも通るようになりました。今度はX.orgを使えるようにします。

広告
カテゴリー: コンピュータ パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中