Vaibhav Singh

Blog - vaibhavsingh.com

Embedded Linux on my consumer grade IP CAM

Lately I have been messing around with tiny devices that have a SoC with embedded Linux on them typically equipped with an ARM processor or similar. Such a new toy in my collection to tinker with is a cheap IP Camera that I bought from Thailand.

Steps

  1. Disassembling the outer case
  2. Soldering USB TTL cable onto the RX and TX pins of the board
  3. Getting console serial access
  4. Capture boot sequence
  5. Make a backup of device’s flash and firmware

First I copied a compiled busybox binary that could run on the device. The inbuilt busybox didn’t have ‘dd’ applet on it. The fully functional one was downloaded from https://busybox.net/downloads/binaries/latest/busybox-mipsel and copied on to the SD card that goes into the IP camera.

Commands

First step is to see what are the commands and utilities provided by the onboard busybox.

# /mnt/busybox-mipsel

BusyBox v1.16.1 (2010-03-29 11:52:23 CDT) multi-call binary.
Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.
Usage: busybox [function] [arguments]...
   or: function [arguments]...
        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.
Currently defined functions:
        [, [[, acpid, addgroup, adduser, adjtimex, arp, arping, ash, awk,
        basename, bbconfig, beep, blkid, brctl, bunzip2, bzcat, bzip2, cal,
        cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot,
        chrt, chvt, cksum, clear, cmp, comm, cp, cpio, crond, crontab, cryptpw,
        cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod,
        devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,
        dos2unix, dpkg, dpkg-deb, du, dumpkmap, dumpleases, echo, ed, egrep,
        eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd,
        false, fbset, fbsplash, fdflush, fdformat, fdisk, fgrep, find, findfs,
        flashcp, fold, free, freeramdisk, fsck, fsck.minix, fsync, ftpd,
        ftpget, ftpput, fuser, getopt, getty, grep, gunzip, gzip, halt, hd,
        hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id,
        ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, insmod,
        install, ionice, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute,
        iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, lash, last,
        length, less, linux32, linux64, linuxrc, ln, loadfont, loadkmap,
        logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr,
        lsmod, lspci, lsusb, lzmacat, lzop, lzopcat, makedevs, makemime, man,
        md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mkfifo, mkfs.minix,
        mkfs.reiser, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modprobe,
        more, mount, mountpoint, msh, mt, mv, nameif, nc, netstat, nice,
        nmeter, nohup, nslookup, ntpd, od, openvt, passwd, pgrep, pidof, ping,
        ping6, pipe_progress, pivot_root, pkill, popmaildir, poweroff,
        printenv, printf, ps, pscan, pwd, raidautorun, rdate, rdev, readahead,
        readlink, readprofile, realpath, reboot, reformime, renice, reset,
        resize, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-parts,
        runlevel, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail,
        seq, setarch, setconsole, setfont, setkeycodes, setlogcons, setsid,
        setuidgid, sh, sha1sum, sha256sum, sha512sum, showkey, slattach, sleep,
        softlimit, sort, split, start-stop-daemon, stat, strings, stty, su,
        sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl,
        syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test, tftp,
        tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true,
        tty, ttysize, tunctl, udhcpc, udhcpd, udpsvd, umount, uname,
        uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unzip, uptime,
        usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch,
        watchdog, wc, wget, which, who, whoami, xargs, yes, zcat, zcip

Check to see if dd works at all

# /mnt/busybox-mipsel dd --help

BusyBox v1.16.1 (2010-03-29 11:52:23 CDT) multi-call binary.
Usage: dd [if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N] [skip=N]
        [seek=N] [conv=notrunc|noerror|sync|fsync]
Copy a file with converting and formatting
Options:
        if=FILE         Read from FILE instead of stdin
        of=FILE         Write to FILE instead of stdout
        bs=N            Read and write N bytes at a time
        ibs=N           Read N bytes at a time
        obs=N           Write N bytes at a time
        count=N         Copy only N input blocks
        skip=N          Skip N input blocks
        seek=N          Skip N output blocks
        conv=notrunc    Don't truncate output file
        conv=noerror    Continue after read errors
        conv=sync       Pad blocks with zeros
        conv=fsync      Physically write data out before finishing
Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),
MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)

Figure out the mtd devices that need to be backed up. These are basically partitions or system spaces that have the operating system on them.

In the output below, the ones that say mtdblock are the ones we need.

# ls -l /dev/mtd*

brw-rw----    1 0        0         31,   7 /dev/mtdblock7
brw-rw----    1 0        0         31,   6 /dev/mtdblock6
brw-rw----    1 0        0         31,   5 /dev/mtdblock5
brw-rw----    1 0        0         31,   4 /dev/mtdblock4
brw-rw----    1 0        0         31,   3 /dev/mtdblock3
brw-rw----    1 0        0         31,   2 /dev/mtdblock2
brw-rw----    1 0        0         31,   1 /dev/mtdblock1
brw-rw----    1 0        0         31,   0 /dev/mtdblock0

crw-rw----    1 0        0         90,  15 /dev/mtd7ro
crw-rw----    1 0        0         90,  14 /dev/mtd7
crw-rw----    1 0        0         90,  13 /dev/mtd6ro
crw-rw----    1 0        0         90,  12 /dev/mtd6
crw-rw----    1 0        0         90,  11 /dev/mtd5ro
crw-rw----    1 0        0         90,  10 /dev/mtd5
crw-rw----    1 0        0         90,   9 /dev/mtd4ro
crw-rw----    1 0        0         90,   8 /dev/mtd4
crw-rw----    1 0        0         90,   7 /dev/mtd3ro
crw-rw----    1 0        0         90,   6 /dev/mtd3
crw-rw----    1 0        0         90,   5 /dev/mtd2ro
crw-rw----    1 0        0         90,   4 /dev/mtd2
crw-rw----    1 0        0         90,   3 /dev/mtd1ro
crw-rw----    1 0        0         90,   2 /dev/mtd1
crw-rw----    1 0        0         90,   1 /dev/mtd0ro
crw-rw----    1 0        0         90,   0 /dev/mtd0

# mkdir /mnt/nfs

Remount file system as read-only

 # mount -o remount,ro /

Start dd for each mtdblock

# /mnt/busybox-mipsel dd if=/dev/mtdblock0 of=/mnt/nfs/mtdblock0 bs=65536
128+0 records in
128+0 records out
8388608 bytes (8.0MB) copied, 11.386426 seconds, 719.5KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock1 of=/mnt/nfs/mtdblock1 bs=65536
3+0 records in
3+0 records out
196608 bytes (192.0KB) copied, 0.249387 seconds, 769.9KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock2 of=/mnt/nfs/mtdblock2 bs=65536
1+0 records in
1+0 records out
65536 bytes (64.0KB) copied, 0.089939 seconds, 711.6KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock3 of=/mnt/nfs/mtdblock3 bs=65536
1+0 records in
1+0 records out
65536 bytes (64.0KB) copied, 0.087424 seconds, 732.1KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock4 of=/mnt/nfs/mtdblock4 bs=65536
16+0 records in
16+0 records out
1048576 bytes (1.0MB) copied, 1.261511 seconds, 811.7KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock5 of=/mnt/nfs/mtdblock5 bs=65536
51+0 records in
51+0 records out
3342336 bytes (3.2MB) copied, 4.339971 seconds, 752.1KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock6 of=/mnt/nfs/mtdblock6 bs=65536
48+0 records in
48+0 records out
3145728 bytes (3.0MB) copied, 3.885347 seconds, 790.7KB/s

# /mnt/busybox-mipsel dd if=/dev/mtdblock7 of=/mnt/nfs/mtdblock7 bs=65536
8+0 records in
8+0 records out
524288 bytes (512.0KB) copied, 0.650801 seconds, 786.7KB/s

Verify that the backups have be written to disk

# ls /mnt/nfs
mtdblock7  mtdblock5  mtdblock3  mtdblock1
mtdblock6  mtdblock4  mtdblock2  mtdblock0

Conclusion

This is an example to demonstrate that we should backup the ROM before modifying or making possibly risky changes to any root filesystem. In case something goes wrong, the ROM can be essentially flashed back to restore the working state.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top