The good old DMP, 4305s, you may still seem them on their way to bins or E-Waste. Saw a couple of them few weeks ago in office and was fascinated about re purposing them, Why because they are small, compact, beautiful packing, and definitely runs Linux. Here is how its done. This experiment was done in collaboration with my friend Kris.
Disclaimer: No Cisco proprietary or confidential information was used or disclosed in this process, rather only general purpose, public information is used to decode/re purpose this product.
Apologies: This document does not cover OS Basics or Unix basics.
I assume the reader is familiar with Hardware and Linux /embedded systems and networking.
This is not really about what this can do, rather, how it is done, to help someone understand and hack in to embedded linux systems.
So Why a Personal NAS/IOT Appliance/Embedded Linux ?
Most of them time when you upgrade routers/switches, you need a FTP/SFTP/WEB Server to keep the upgrade images. We usually mess around with our own PC by installing FTP/SFTP/Web Servers in it, troubleshooting, eventually consuming more time setting up the File Server than performing actual upgrade.
Many times need a simple unix Box to run Shell Scripts to Fetch/Push data to/from your IOT Device, to run your own scripts/simple automation. Or Collect data to/from IOT to USB.
|What are the Uses?|
|Pocket NAS – FTP/SFTP/Web Server for Lab/Field Image Upgrades/Downgrade, on site PoC or PoVs|
|Personal Micro Web Server appliance|
|Personal Unix Server appliace – To learn Basic Shell Scripting and Unix|
|IoT Device to run your tiny IoT Programs|
|Collect/Provide Data to/from IoT Devices|
|Filer/Network Attached Storage Appliance for Personal/Home/Small sized Labs|
|Tiny Unix Box, to do automation/Scripting in very small footprint|
|Native ROMFS Based Unix, need not shutdown. Can survive hot plugs/pulls|
|Learn Behind the scenes of this Project and get know on Hacking Embedded Systems/Embedded Linux|
|How to use it?
Simple -Copy the Files you need to be hosted/for upgrade to a USB Stick. Attach USB To DMP. Power it UP. Your files on the USB can be accessed via ALL of the following means
|Web Server/HTTP – Download|
|Throughout – ~ 68Mbps on HTTP/FTP|
|SFTP – Upload AND Download.|
|Management Access – Telnet/SSH in to the DMP. Serial Console access available too.
Run scripts off USB if you wish to
|FTP – Upload AND Download.|
Here it is in Action
1. Copy the files you want to host in a USB Stick.
2. Attach the USB Stick to the DMP.
3. Connect the Ethernet port of the DMP to the router/switch management port or Network. DMP IP is 10.1.1.1/24. GW 10.1.1.254 by default.
4. Access the files on your USB Stick using ANY/ALL of the following
B. FTP – from classic IOS it is copy ftp://10.1.1.1/usb_2/filename.bin flash:
Here is the FTP access from standard FTP Client
C. Telnet/SSH Access – In case you want to change IP or Tweak anything
Lets see how its done-
First step, is to get in to the hardware. Of course open this fella up. I had no idea what was inside when I started, rather it was a curiosity which made me go in to it.
Here is what is inside –
okay, Another embedded board. NXP aka Motorola Aka dont know what is it called now CPU, MPC 8247. First piece of info. Now I see HDMI Controller, USB, RAM, UART, ethernet , Flash, and all other standard peripheral chips. There is one RS323 behind the box, but thats not spitting anything out while powering up.
Time to scan the board, there you go, you see this Unmarked header.
One of this has to be console/UART of the Processor. But what Signal, what encoding, standard. Checked the chips around, didnt find any RS323 driver. Time to get the heavy gear, DSO and put in in single sweep mode, store and check the waveform across all pins for voltage levels.
few minutes later, I know its a 3.3V RS323 signal. So to get console you need something to jack-up 3.3v to 15V RS323. What else other than the Raspberry-Pi Console cable. Use only ground and TX from the board to the PC to receive the console dump. Then run through all the Pins on the header with the TX from the PC to trace the RX of the DMP. Basically you try plugging in one pin, type enter on PC and check if DMP is responding on Console. Use a terminal emulator of course.
Remember, baud – you don’t know in board when you hack in, so start from 9600 all the way up to 115200, until you get lucky. Here it is 115200/8/1/No Parity
So here is the pin-out as decoded on the DMP Side-
2- TX, 3-RX, 4/5- Ground. Pin with White Square on PCB is #1.
So standard USB to Raspberry-PI Cable, Terminal Emulator, and here you go, you have the Console of this Embedded Board !!
U-Boot 1.0.0 (Jul 26 2006 - 18:32:38) MPC8272 Reset Status: Check Stop, External Soft, External Hard MPC8272 Clock Configuration - Bus-to-Core Mult 4x, VCO Div 2, 60x Bus Freq 25-75 , Core Freq 100-300 - dfbrg 1, corecnf 0x1a, busdf 3, cpmdf 1, plldf 0, pllmf 3 - vco_out 400000000, scc_clk 100000000, brg_clk 25000000 - cpu_clk 400000000, cpm_clk 200000000, bus_clk 100000000 CPU: MPC8272 (HiP7 Rev 14, Mask unknown [immr=0x0d10,k=0x00e1]) at 400 MHz Board: USI HMC Group PVR I2C: ready USI->DRAM: 128 MB FLASH: 32 MB pci init start-- HMC:Release PCI RST 00 16 1105 c621 0480 00 00 17 1033 0035 0c03 00 00 17 1033 0035 0c03 00 00 17 1033 00e0 0c03 00 ---pci init end In: serial Out: serial Err: serial Net: FCC1 ETHERNET Hit any key to stop autoboot: 0 ## Booting image at fe060000 ... Image Name: Linux-2.4.22 Image Type: PowerPC Linux Kernel Image (gzip compressed) Data Size: 972938 Bytes = 950.1 kB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK Begin Uncompressing Kernel Image ... OK ## Transferring control to Linux (at address 00000000) ... Memory BAT mapping: BAT2=128Mb, BAT3=0Mb, residual: 0Mb Linux version 2.4.22 (alexr@Haifa) (gcc version 3.3.2) #1 Wed Jan 10 23:01:23 IST 2007 USI:isa_io_base ioremap = a0000000 PVR:CONFIG_ATC not defined On node 0 totalpages: 32768 zone(0): 32768 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: root=/dev/mtdblock4 rw rootfstype=cramfs console=ttyS0,115200
..uBoot !!!..I can see uboot Console and Linux Bootup. We are in to the Board 🙂 .
uBoot can see two serial ports and one Ethernet Port. Makes life MUCH MUCH easy !
Lets screen through the Boot log, here you can see the Linux memory Map for the board.
Creating 5 MTD partitions on "Flash Chip": 0x00000000-0x00040000 : "u-boot" 0x00040000-0x00060000 : "u-boot env.var" 0x00060000-0x001c0000 : "kernel" 0x001c0000-0x01e80000 : "rootfs" 0x01e80000-0x02000000 : "jffs #1"
0x00000000-0x00040000 : “u-boot”. —> uBoot Microcode/BIOS
0x00040000-0x00060000 : “u-boot env.var” –> uBoot Variables
0x00060000-0x001c0000 : “kernel”. –Linux Kernel
0x001c0000-0x01e80000 : “rootfs” — Root FS
0x01e80000-0x02000000 : “jffs #1” — Not sure.
So basically if you want to really burn a new kernel, you need to place it between 0x00060000-0x001c0000 and if you want a new root FS, burn it in to 0x001c0000-0x01e80000
Lets start with a simple one as root FS, as compiling a kernel for this board might be challenging as the tool chain itself is too old. So what we will do first is to extract the root FS from the board to a PC and analyze it. Alter it if possible to make it as generic as possible.
There are multiple option here. Easiest one is to do a dd of the root FS to a usb stick mounted on the USB Port. Since they dont control the root access to the busybee shell, once you break the boot up with Control+C, you can get to # prompt. Here is the log..
mib database file exists! - starting lighttpd watchdog HTTP request sent, awaiting response... 200 OK 200 OK Lighttpd is working correctly BusyBox v1.00 (2009.12.10-06:12+0000) Built-in shell (ash) Enter 'help' for a list of built-in commands. DMP 172.24.68.28 # pwd /
Then its a matter of doing a dd.
The code automatically mounts USB drive – if there is one plugged in to the USB port. I did “dd” and got the root fs out.
Here is the mount detailed from a booted DMP
/dev/mtdblock4 on / type cramfs (rw) ramfs on /tmp type ramfs (rw) /proc on /proc type proc (rw) devpts on /dev/pts type devpts (rw) none on /proc/bus/usb type usbdevfs (rw) /dev/mtdblock5 on /persistent type jffs2 (rw) /dev/sdc1 on /tmp/ftproot/usb_1 type vfat (ro,noatime)
okay, lets move the rootfs file to a Unix box for further autopsy.
[I am sorry, I started with unix back in 1995, so I dont call them Linux yet 😉 for me its still SVR3. I am *.nix -;) ]
basic check on the file
root@raj-ux2:/home/rajesh# file rootfs.bin rootfs.bin: Linux Compressed ROM File System data, big endian size 24879104 version #2 sorted_dirs CRC 0x9554aac6, edition 0, 12672 blocks, 1840 files
okay, lets use binwalk to get some more details
binwalk rootfs.bin DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 0 0x0 CramFS filesystem, big endian size 24879104 version 2 sorted_dirs CRC 0x9554AAC6, edition 0, 12672 blocks, 1840 files 24880374 0x17BA4F6 Zlib compressed data, best compression 24881472 0x17BA940 Zlib compressed data, best compression 24881542 0x17BA986 Zlib compressed data, b
Now, its clear, its cramfs, Big Endian (coz of the Motorola origin of the processor)
lets install the cramfs programs so that we can poke around with the cramfs file.
sudo apt-get install cramfsprogs
after that we can mount this image to a directory and access it 😉
First, change the endian as we are working on a Linux box with x86 which is little endian.
cramfsswap rootfs1.bin rootfs-le.bin Filesystem is big endian, will be converted to little endian. Filesystem contains 1839 files. CRC: 0xe415b3d2
now. lets mount this
root@raj-ux3:/home/rajesh/Work1# mkdir mount; mount -o loop -t cramfs rootfs-le.bin ./mount root@raj-ux3:/home/rajesh/Work1/mount# mount | grep cramfs /home/rajesh/Work1/rootfs-le.bin on /home/rajesh/Work1/mount type cramfs (ro,relatime) root@raj-ux3:/home/rajesh/Work1# cd mount root@raj-ux3:/home/rajesh/Work1/mount# ls bin HW_PLATFORM linuxrc preburn.sh sbin tivella2 var BINFILES include LOGO proc SYSTEM_FS tivella_extra X11 dev JFFS_FS mnt PRODUCT TIMESTAMP TIVELLATAG etc KERNEL_FS persistent ROOT_FS tivella tmp home lib ppctools ROOTFS_IMAGE tivella1 usr
so there you go. You can see the file system. Now its just basic skills to decode the boot sequence, the scripts they run to get the DMP started, etc etc.
remember, its still readonly.
root@raj-ux3:/home/rajesh/Work1/mount/#cd etc; tail rc.sh
cp /etc/passwd-ORIG /persistent/passwd
### If hook does not exist or if it exists and succeed - continue normally
### If hook exists and fails (exit 1) - do nothing
if [ ! -x /persistent/rc.sh_hook ] || /persistent/rc.sh_hook
### Tivella start
This is a great starting point to plan what you want to do.
I am not publishing exact changes I made, as it may attractant copyright/legal issues if any, but basically its simple, you know what to do 😉
disable their services, enable lighthttpd, vsftpd. and telnetd on startup. May be assign any IP you may want to do the initial interface etc.
Now, in order to make change, you need to extract the cramfs image.
cramfsck -x ./Extract rootfs1.1-le.cramfs rajesh@raj-ux3:~/Work1$ ls Extract/ bin HW_PLATFORM LOGO PRODUCT TIMESTAMP tmp BINFILES include mnt Rajesh tivella usr dev JFFS_FS persistent ROOT_FS tivella1 var etc KERNEL_FS ppctools ROOTFS_IMAGE tivella2 X11 Hacked-FS lib preburn.sh sbin tivella_extra home linuxrc proc SYSTEM_FS TIVELLATAG rajesh@raj-ux3:~/Work1$
So you have the files the way you want 🙂 . You can edit the root FS here now, ie, changing the startup scripts. Its straightforward, if you are familiar with unix.
Once you done making changes to all the startup scripts the way you want, you can repack it to root file system in CramFS.
root@raj-ux3:/home/rajesh/Work1# mkcramfs usage: mkcramfs [-h] [-b blksize] [-e edition] [-i file] [-n name] dirname outfile -h print this help -E make all warnings errors (non-zero exit status) -b blksize blocksize to use -e edition set edition number (part of fsid) -i file insert a file image into the filesystem (requires >= 2.4.0) -n name set name of cramfs filesystem -p pad by 512 bytes for boot code -s sort directory entries (old option, ignored) -v be more verbose -z make explicit holes (requires >= 2.3.39) dirname root of the directory tree to be compressed outfile output file root@raj-ux3:/home/rajesh/Work1# mkcramfs ./Extract/ hackedfs.cramfs Directory data: 43024 bytes Everything: 27976 kilobytes Super block: 76 bytes CRC: c1c77f81
Remember to change the Endian 😉
rajesh@raj-ux3:~/Work1$ file hackedfs.cramfs hackedfs.cramfs: Linux Compressed ROM File System data, little endian size 28647424 version #2 sorted_dirs CRC 0xc1c77f81, edition 0, 14684 blocks, 1873 files rajesh@raj-ux3:~/Work1$ cramfsswap hackedfs.cramfs Usage: cramfsswap rajesh@raj-ux3:~/Work1$ cramfsswap hackedfs.cramfs hackedfs.cramfs-BE Filesystem is little endian, will be converted to big endian. Filesystem contains 1872 files. CRC: 0x6a34c95c
Now all you need to do is, upload this back to the DMP.
Now, its very simple here as we have access to uBOOT via Serial console
IPSTB=> update_kernel=erase fe060000 fe1bffff;tftp 00c00000 vmlinux.siis_20060602;cp.b 00c00000 fe060000 $(filesize) update_fs=erase fe1c0000 fe9fffff;erase fea00000 ff1fffff;erase ff200000 ff9fffff;erase ffa00000 ffffffff;tftp 00c00000 rootfs.siis_20060602;cp.b 00c00000 fe1c0000 $(filesize);reset bootargs=root=/dev/mtdblock4 rw rootfstype=cramfs console=ttyS0,115200 bootcmd=bootm fe060000 bootdelay=2 baudrate=115200 ethaddr=02:D1:af:82:47:01 ipaddr=192.168.58.222 serverip=192.168.58.85 gatewayip=192.168.58.1 netmask=255.255.255.0 hostname=HMC8247_EM8620 stdin=serial stdout=serial stderr=serial
So what you need is a TFTP server running on your PC/VM. Connect the ethernet port of the DMP to the PC/VM where the TFTP Server is running. assign it the ip address of 192.168.58.85. I used a linux VM on my Mac to run the tftp server.
Try a ping from uBoot. confirm connectivity is good.
then the command is already present on the uboot default macro.
update_fs=erase fe1c0000 fe9fffff;erase fea00000 ff1fffff;erase ff200000 ff9fffff;erase ffa00000 ffffffff;tftp 00c00000 rootfs.siis_20060602;cp.b 00c00000 fe1c0000 $(filesize);reset
So all you need to do is, rename your hacked root-fs to rootfs.siis and run the command update_fs from uboot prompt.
you can use whatever filename you like and run the commands one by one. like htis
erase fe1c0000 fe9fffff;erase fea00000 ff1fffff;erase ff200000 ff9fffff;erase ffa00000 ffffffff tftp 00c00000 hacked_rootfs-BE.bin cp.b 00c00000 fe1c0000 $(filesize);reset
On reboot you will have the new root FS.
In case the system is failing to boot, just fix the error, repeat the step and reload the roof FS back on to the board/Flash.
JTAG: The connector next to the Console header is the JTAG. I did get in to it using JTAG (used raspberry Pi for JTAG Hardware, with urJag)
Apologies for the bad drawing, but this is the JTAG Pinout and corresponding wiring to rPI.
Remember TRST needs to be in the correct state for the whole thing to work. If I remember correctly the URTAG dont assert this pin. You may have to manually pull it up to Logic 1.
Here is the JAG out..
—— THE END —-