I've dabbled in music production on and off for 15 years, so I've always tried to keep decent audio interfaces for all my workstations. Last year I moved from Focusrite and picked up a Motu UltraLite AVB, mostly for the networking features. The entire control panel and config system is a web page that can be accessed anywhere over the network, and using this it can function as a standalone mixer and DSP box in live situations. The DAC & ADC performance is also exceptional on MOTU's Sabre ESS equipped models, with this one in particular measuring an output noise floor a tiny bit below -140db
Anyway, I figured with an LCD, an ethernet port, DSP and a webserver onboard, it has to be running some type of embedded OS. So, I tracked down their "offline" firmware update files (they prefer you to do updates online through the web panel). Grepping through it with binwalk reveals something not very surprising for the veterans here:
There's our linux kernel. Digging further, there's a tmpfs archive, making up the temp filesystem that gets embiggened on boot. I began digging through that out of curiosity - remember, the main UI of this thing is a web page, so I figured there's html content somewhere:
Note the last file - to quote the great danny elfman, what's this? start_telnet.html certainly isn't linked anywhere in the UI, and googling around, has never been mentioned anywhere. Its contents are pretty simple:
There's my favorite four words, For Internal Use Only. I'm sure you can take a guess what this button does - at least, what I hoped it did - starts a telnet daemon granting shell access to the embedded linux install. So, browsing to the IP of the device and appending /start_telnet.html, do we get a working webpage? Indeed:
Clicking the "start" button doesn't change anything on the page, or provide any kind of feedback that something has happened. But, if you then telnet to the IP of the MOTU device (port 23), you'll be granted a login prompt where you can log in as root and an empty password. Note you must have the ethernet port of the device connected to your network, you can't access the debug telnet server over the localhost port you use to manage the device over USB. Anyway:
We can see it's running an Arago-derived embedded linux build, on top of an ARM926EJ-S CPU. Poking around a bit at the storage and filesystem layout:
The interesting (MOTU specific) stuff is under /opt:
Under that /opt/motu folder is all the web content, the DSP binary, and all the other MOTU-specific stuff that makes the box work. But what are these scmd and ssutil binaries? Loading scmd into Ghidra to search for strings, we find:
So it's a nice little utility to interface with the fpga onboard, as well as i2c r/w debug etc. What about ssutil?
Well those sound fun. I wonder if I could.....
Yep, ssutil definitely works as expected. That's all for now, I'll put info on the debug UART in a thread reply under this main post. Here is a ZIP of interesting output (dmesg, u-boot, etc) for anyone who wants to poke through: https://fohdeesha.com/data/other/motu-avb-re.zip
Anyway, I figured with an LCD, an ethernet port, DSP and a webserver onboard, it has to be running some type of embedded OS. So, I tracked down their "offline" firmware update files (they prefer you to do updates online through the web panel). Grepping through it with binwalk reveals something not very surprising for the veterans here:
Code:
Scan Time: 2021-01-15 07:07:44
Target File: /root/re/MOTU AVB 1.3.5+626 for UltraLite AVB and Stage-B16.update
MD5 Checksum: c6e4ecd77376704ad985dbdc17ffcba0
Signatures: 386
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
131468 0x2018C Xilinx Virtex/Spartan FPGA bitstream dummy + sync word
--------trimmed for brevity---------------
4260224 0x410180 uImage header, OS: Linux, CPU: ARM, image type: OS Kernel Image, image name: "Linux-2.6.32-rc8"
4260288 0x4101C0 Linux kernel ARM boot executable zImage (little-endian)
Code:
root@testing:~/re/motu-fw/_rootfs.extracted# ls -lha |grep -i html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux1.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux2.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux3.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux4.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux5.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux6.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux7.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 aux9.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 group1.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 group3.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 group5.html
-rw-r--r-- 1 root root 5.6K Jan 15 07:08 motu_avb.html
-rw-r--r-- 1 root root 5.3K Jan 15 07:08 reverb1.html
-rw-r--r-- 1 root root 1.1K Jan 15 07:08 set_update_channel.html
-rw-r--r-- 1 root root 770 Jan 15 07:08 start_telnet.html
Code:
root@testing:~/re/motu-fw/_rootfs.extracted# cat start_telnet.html
---trimmed for brevity----
<h1>Telnet Starter - For Internal Use Only</h1>
<label for="channel">Click Here to start telnet:</label>
<button id="button">Start</button>
<script type="application/javascript">
document.getElementById('button').addEventListener('click', function(){
var req = new XMLHttpRequest();
req.open('POST', "/start_telnet");
req.send();
Clicking the "start" button doesn't change anything on the page, or provide any kind of feedback that something has happened. But, if you then telnet to the IP of the MOTU device (port 23), you'll be granted a login prompt where you can log in as root and an empty password. Note you must have the ethernet port of the device connected to your network, you can't access the debug telnet server over the localhost port you use to manage the device over USB. Anyway:
We can see it's running an Arago-derived embedded linux build, on top of an ARM926EJ-S CPU. Poking around a bit at the storage and filesystem layout:
Code:
[ 1.035116] m25p80 spi1.0: found mx25l25645g, expected s25fl256s
[ 1.041632] 4 cmdlinepart partitions found on MTD device s25fl256s
[ 1.048046] Creating 4 MTD partitions on "s25fl256s":
[ 1.053268] 0x000000000000-0x000000590000 : "Boot"
[ 1.063130] 0x000000590000-0x000000b80000 : "Linux"
[ 1.072011] 0x000000b80000-0x000001380000 : "RootFs"
[ 1.080736] 0x000001380000-0x000002000000 : "User_Data"
[ 1.090130] spi_davinci spi_davinci.1: Controller at 0xfef0e000
[ 1.099096] spi_davinci spi_davinci.0: Controller at 0xfec41000
root@UltraLite-AVB:/dev# ls -1 /dev/spidev0.*
/dev/spidev0.0
/dev/spidev0.1
root@UltraLite-AVB:/dev# cat /proc/mtd
dev: size erasesize name
mtd0: 00590000 00010000 "Boot"
mtd1: 005f0000 00010000 "Linux"
mtd2: 00800000 00010000 "RootFs"
mtd3: 00c80000 00010000 "User_Data"
root@UltraLite-AVB:/dev# df -h
Filesystem Size Used Available Use% Mounted on
rootfs 15.5M 14.3M 1.2M 92% /
/dev/root 15.5M 14.3M 1.2M 92% /
tmpfs 25.3M 132.0K 25.1M 1% /var/volatile
tmpfs 25.3M 0 25.3M 0% /tmp
/dev/mtdblock3 12.5M 688.0K 11.8M 5% /mnt/user
root@UltraLite-AVB:/dev# mount
rootfs on / type rootfs (rw)
/dev/root on / type ext2 (rw,relatime,errors=continue)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620)
tmpfs on /var/volatile type tmpfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
/dev/mtdblock3 on /mnt/user type jffs2 (rw,sync,relatime)
Code:
root@testing:~/re/motu-fw/_rootfs.extracted/ext-root/opt# ls -lh
total 1000K
-rw-r--r-- 1 root root 22 Jan 15 07:07 DeviceDescription
drwxr-xr-x 2 root root 4.0K Jan 15 07:07 img
drwxr-xr-x 5 root root 4.0K Jan 15 07:07 motu
-rw-r--r-- 1 root root 25K Jan 15 07:07 scmd
-rw-r--r-- 1 root root 44K Jan 15 07:07 ssutil
-rw-r--r-- 1 root root 916K Jan 15 07:07 tamio
Code:
fpga read/write options:
-f, --fpga Read or write fpga
-e, --emif Emif (CS 2,5)
-s, --spi Use SPI mem map
-r, --read ADR (i.e. 0x3200)
-w, --write ADR (i.e. 0x3200)
-v, --val VAL For writing (i.e. 0x1234)
Read fpga SPI Example: scmd -f -s -r 0x05
Write fpga SPI Example: scmd -f -s -w 0x05 -v 0x34
Read fpga EMIF Example: scmd -f -e 2 -r 0x8030
Write fpga EMIF Example: scmd -f -e 2 -w 0x8030 -v 0x1234
I2C read/write options:
-i, --i2c DEV read or write i2c
-r, --read ADR (i.e. 0x03)
-w, --write ADR (i.e. 0x03)
-v, --val VAL For writing (i.e. 0x12)
Read i2c Example: scmd -i -r 0x05
Write i2c Example: scmd -i -w 0x05 -v 0x34
CSR read/write options:
-q, --quad read or write csr
-r, --read ADR (i.e. 0x10000004)
-w, --write ADR (i.e. 0x10000004)
-v, --val VAL For writing (i.e. 0x12345678)
Read quad Example: scmd -q -r 0x10000004
Write quad Example: scmd -q -w 0x10000004 -v 0x12345678
Error Log Debug Level:
-d | --debug Set syslog level mask [0xFF]
Example: scmd -d 0xff
Code:
Options:
-f bitmap Set firmware update bitmap b0 = firmware update, b1 = firmware corrupt
-fr Get firmware update bitmap
-p Get satellite personality string
-d Get satellite LCD display type string
-hr Get hostname string
-hw string Set hostname string
-lt string Draw text on the LCD
-lt X string Draw text on LCD[X]
-lp string percent Draw text with progress bar on the LCD
-lp X string percent Draw text with progress bar on LCD[X]
-lg filename Draw GIF on the LCD
-lg X filename Draw GIF on LCD[X]
-b Read button state
-r Ultralite power down
-ap Read Auto Power Mode flag
-mr Read Device UID
-ms Set Max 10 dirty flag (0 or 1)
-mg Get Max 10 dirty flag
-ir chipAdr reg i2c read byte (Use hex)
-iw chipAdr reg val i2c write byte (Use hex)
Yep, ssutil definitely works as expected. That's all for now, I'll put info on the debug UART in a thread reply under this main post. Here is a ZIP of interesting output (dmesg, u-boot, etc) for anyone who wants to poke through: https://fohdeesha.com/data/other/motu-avb-re.zip
Last edited: