-
Reverse engineering the U-boot binary
11/24/2023 at 10:09 • 0 commentsSince the application boot sequence is hardcoded (not defined using bootcmd) we need to dive deeper into how this works.
Using Ghidra I have decompiled the U-boot MIPS assembly code to understand more. I simply loaded the DRAM dump performed earlier into Ghidra and disassembled for MIPS32 architecture. The initial output from Ghidra is difficult to interpret, but slowly as you start to give functions and variables more intuitive names the process begins to speed up.
It turns out that the application boot sequence is very complicated with CRC checks and multiple flows for various software upgrades via ethernet and USB. There is also some redundant code that seems to perform no function whatsoever, almost as if this version of M-boot has been further hacked and modified by the author of the final application software. I will provide more detail on this later in the form of a flow chart after I've fully reverse engineered it.
What I have managed to determine is the main application boot sequence. In order to replicate it via the U-boot command line type the following sequence:
spi_rdc 0x81100000 0x300000 0x700000 mscompress7 d 0 0x81100000 0x700000 0x80000180 go 0x80000224
This sequence: 1.) copies the compressed application image from flash to DRAM starting at starting 0x81100000, 2.) decompresses the image to DRAM starting at address 0x80000180, 3.) begin code execution from DRAM address 0x80000224. The main application now boots with display out via HDMI. Note, this sequence bypasses all of the CRC checks in the standard hardcoded sequence.
Interestingly, we can also use the same process to boot the secret software upgrader application:
spi_rdc 0x81100000 0x90000 0x250000 mscompress7 d 0 0x81100000 0x250000 0x80000180 go 0x80000224
Again, this provides a display output via HDMI and goes through a sequence of trying to update software via ethernet, USB and OTA.
-
Examination of the firmware dump and initial boot sequence
10/23/2023 at 20:01 • 0 commentsIn a previous log we saw how the contents of the SPI flash chip can be dumped to a binary file over USB, the .bin file of this dump is attached in the Files area. We will now examine that file using a variety of linux-based tools (hex dump, binwalk, strings).
Here is my best guess of the map of the 16MiB flash chip, the table will be updated as we learn more:
Flash start address Flash end address Description 0x000000 0x00316F BootROM (mapped to base address 0xBFC00000) 0x003170 0x00FFFF BootRAM (last 32 bytes are the S-Boot version string) 0x010000 0x0103FF Unknown header 0x010400 0x06FFFF U-boot image (LZMA compressed) 0x070000 0x08FFFF JPEG image (displayed during application boot) 0x090000 0x2E7FFF Upgrader application image (LZMA compressed) 0x2E8000 0x2EFFFF Application CRC 0x2F0000 0x2F7FFF Application CRC (backup copy) 0x2F8000 0x2FFFFF ? 0x300000 0x9FFFFF Main application image (LZMA compressed) 0xA00000 0xCFFFFF Application image (ZLIB compressed) 0xD00000 0xFDFFFF Application data? 0xFE0000 0xFEFFFF U-boot environment variables 0xFF0000 0xFFFFFF U-boot environment variables (redundancy) The U-boot image starting at 0x010400 is LZMA compressed with a unique string of bytes as a footer. Removing this footer and uncompressing with unlzma reveals a binary containing MIPS instructions.
A JPEG image is held at address 0x070000 and is displayed during boot via HDMI. The image is the Manhattan branding for this unit and has a resolution of 720 x 576 pixels, it is displayed during the boot of the main application. A cool little hack might be to replace this image with something of your own :-) Image shown below.
The two blocks starting at 0x2E8000 and 0x2F0000 are identical redundant copies, clearly containing some important data that must be conserved should a write action to this area fail and brick the unit. Reverse engineering of the U-boot binary reveals them to be CRC checksums related to the main application image, the format of these will be explored later. The third block starting at 0x2F8000 is of unknown format at present.
The application images are compressed with a mixture of LMZA compression and ZLIB compression. They are uncompressed and executed by the U-boot boot sequence. Uncompressing these reveals an eCOS real-time operating system. This is the operating system for the satellite receiver application. One is a separate 'upgrader' application for software updates (more on this later). Disappointingly, it's not Linux, so we won't be able to hack our way to a root shell :-(
Finally we have application data and the 2x identical copies of the U-boot environment variables, again for important redundancy protection.
The initial boot sequence (up to U-boot) has been examined by studying the firmware dump and the M-boot manual (attached in the files area):
1.) Reset vector 0xBFC00000, BootROM code execution direct from flash
2.) DRAM, UART and other initializations
3.) BootRAM code copied to DRAM, at address 0x81000000 and executed
4.) U-boot LMZA image copied to DRAM at address 0x81100000
5.) U-boot image uncompressed to DRAM at address 0x871F0180
6.) Execution of U-boot MIPS code from same address.From this point, the U-boot boot sequence takes over. In standard U-boot, the boot sequence should be specified in the environment variables (bootcmd). However, we know in this version of U-boot the sequence is instead hardcoded and the bootcmd is a inoperable. In fact, if we modify the bootcmd to include an echo statement + saveenv we do not get any feedback in the console during the full boot flow. It is highly likely the bootcmd is ignored in this version of U-boot and a hardcoded sequence is instead executed. How we therefore modify this sequence to autoboot a future custom OS is unclear, the only viable option at present to boot something custom using the U-boot command prompt.
So what and where is the hardcoded boot sequence in the U-boot binary? The DEBUG level commands in the console can provide some insight. However, to dive deeper we need to dissemble the U-boot code. I will aim to look at this in a future update.
Updated 24th November 2023
-
Enabling debug messaging
10/12/2023 at 12:57 • 0 commentsOn examination of the help output there is a command dbg that can be used to set the debug message level:
kiwi# help .... dbg - set debug message level. Default level is INFO
The default level is INFO. We can use this command to change the level of feedback in the terminal when any commands are executing. Let's set to level DEBUG, this is the highest level of detail.
kiwi# dbg DEBUG Saving Environment to SPI Flash... Write addr=0x00FE0000, size=0x00010000 block erase Write addr=0x00FF0000, size=0x00010000 block erase
This change is made to the environment variables which are stored on the SPI flash. The good news is these changes therefore persist after a reboot. The address locations in flash where the environment variables are stored will be helpful when we later analyze our firmware flash dump. We can check the changes to the environment variables by running the printenv command:
UARTOnOff=on baudrate=115200 bootcmd=if mmc rescan ${mmcdev}; then if run loadbootscript; then run bootscript; else if run loaduimage; then run mmcboot; fi; fi; fi bootdelay=0 bootscript=echo Running bootscript from mmc${mmcdev} ...; source ${loadaddr} console=ttyS2,115200n8 dbgLevel=DEBUG loadaddr=0x82000000 loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage mmcargs=setenv bootargs console=${console} vram=${vram} root=${mmcroot} rootfstype=${mmcrootfstype} mmcboot=echo Booting from mmc${mmcdev} ...; run mmcargs; bootm ${loadaddr} mmcdev=0 mmcroot=/dev/mmcblk0p2 rw mmcrootfstype=ext3 rootwait osd_language=English stderr=serial stdin=serial stdout=serial ubispeedup=UBI usbtty=cdc_acm vram=16M Environment size: 805/65532 bytes
A new line dbgLevel=DEBUG has been appended.
Let's reset the unit and allow the normal boot process to proceed so we can review the debug level output:
UART_115200 AC_FLOW [23456789A][23456789A][3456789AB][3456789AB]-6677 BST-OK_RAM[AT][MB][start ub][677] U-Boot 2011.06-svn565 (Mar 01 2018 - 21:27:50) MBOT-1106-0.8.KANO_TEE_NAND.a1 DRAM: 256 MiB Hello U-Boot Stack Pointer at: 87E52E00 mem initial, start 0x86DD0180, len 0x420000 msIR_Initialize [MIU INFO] miu opencreate instance at 86FE7288 with private size 80 bytes at 86FE72D0 SPI: Flash is detected (0x0C05, 0xC8, 0x40, 0x18) MDrv_SERFLASH_GetInfo() u32AccessWidth = 1 u32TotalSize = 16777216 u32SecNum = 256 u32SecSize = 65536 create instance at 86FE7328 with private size 48 bytes at 86FE7370 uboot held at [8F000000~90000000] Now running in RAM - U-Boot at: 871F0180 In: serial Out: serial Err: serial Net: No ethernet found. Set MAC default MAC: 0x0: 0x30: 0x1B: 0xBA:0x2: 0xDB [AT][MB][initDbgLevel][779]_end [TRACE] getNextCmd IN [DEBUG] getNextCmd:159: This is the last cmd [TRACE] MsDrv_GetMIUSize IN [TRACE] MsDrv_GetMIUSize OK [TRACE] MsDrv_GetMIUSize IN [TRACE] MsDrv_GetMIUSize OK [TRACE] MsDrv_GetMIUSize IN [TRACE] MsDrv_GetMIUSize OK Hit any key to stop autoboot: 0 [TRACE] do_spi_rdc IN offset 0x2E0000, size 0x10000 [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x80700000 [DEBUG] _spi_rdc:769: flash_addr=0x2E0000 [DEBUG] _spi_rdc:770: len=0x10000 Flash is detected (0x0C05, 0xC8, 0x40, 0x18) initialization done! [DEBUG] _spi_rdc:799: Start read 10000 data from serial device... [TRACE] do_spi_rdc OK ERR>Invalid Ldr Sign ERR>Reading LDR sign from backup [TRACE] do_spi_rdc IN offset 0x80000, size 0x10000 [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x80700000 [DEBUG] _spi_rdc:769: flash_addr=0x80000 [DEBUG] _spi_rdc:770: len=0x10000 [DEBUG] _spi_rdc:799: Start read 10000 data from serial device... [TRACE] do_spi_rdc OK **********************LOADER_INFO********************* @DF.0 #1.0 $1.0 ^1.5 *17 ************************************************************ SSS eLOADER 21:28:06 Mar 1 2018 ************************************************************ CPS SZE[1740] MAIN.C 2484> Checking for key sequence... enInvokemode:0 M.c 712> USB_(0) Check USB port[0]: [USB] usb_lowlevel_init++ [USB] USB EHCI LIB VER: 2014.10.02 [USB] Port 0 is Enabled [USB] TV_usb_init (UTMI Init) ++ [USB] UTMI Base BF207500 [USB] UHC Base BF204800 [USB] USBC Base BF200E00 [USB] BC Base BF240A00 [USB] TV_usb_init-- [USB] Usb_host_Init++ [USB] Async base addr: 0xA7E1A100 [USB] Reg 0x28: 0xA100 0xA7E1 [USB] disable run [USB] Host Speed:2 [USB] enable aynch [USB] Usb_host_Init-- [USB] FAILED [USB] usb_lowlevel_init--[0] scanning bus for devices... [USB] control1 max:40 [USB] interface[0] conf:1 value FF: 1 USB Device(s) found M.c 716>USB_0_Init_Success [TRACE] do_spi_rdc IN offset 0xDC0000, size 0x10000 [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x80600000 [DEBUG] _spi_rdc:769: flash_addr=0xDC0000 [DEBUG] _spi_rdc:770: len=0x10000 [DEBUG] _spi_rdc:799: Start read 10000 data from serial device... [TRACE] do_spi_rdc OK Marker read success Marker [0xFFFFFFFF] mode[0] Jumping to Application... MsBoot.c E-1174>APP CRC Check..!! [TRACE] do_spi_rdc IN offset 0x2E8000, size 0x8000 [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x80900000 [DEBUG] _spi_rdc:769: flash_addr=0x2E8000 [DEBUG] _spi_rdc:770: len=0x8000 [DEBUG] _spi_rdc:799: Start read 8000 data from serial device... [TRACE] do_spi_rdc OK [TRACE] do_spi_rdc IN offset 0x300000, size 0x4B29FC [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x81100000 [DEBUG] _spi_rdc:769: flash_addr=0x300000 [DEBUG] _spi_rdc:770: len=0x4B29FC [DEBUG] _spi_rdc:799: Start read 4B29FC data from serial device... [TRACE] do_spi_rdc OK APP CRC Success... [TRACE] _spi_rdc IN [DEBUG] _spi_rdc:768: dram_addr=0x81100000 [DEBUG] _spi_rdc:769: flash_addr=0x300000 [DEBUG] _spi_rdc:770: len=0x700000 [DEBUG] _spi_rdc:799: Start read 700000 data from serial device... Decompression OK! MSBOOT.C 1196-E> Decompression OK[Go] disable interrupts ## Starting application at 0x80000224 ...
We can now see much more detail regarding how data is moved from flash to RAM using the spi_rdc command, the address locations and size in flash, and the destination address is RAM. This will be helpful in the later firmware analysis and how we may intercept this process to boot a custom OS.
Updated 13th October 2023
-
Extracting the firmware
09/28/2023 at 20:15 • 0 commentsThe conventional way of doing this is to use the command md to dump the firmware bytes as text characters to the terminal, pipe to a text file, and run a script to convert from ASCII to binary. Unfortunately, this process is very slow, I calculated that to dump the entire 256MiB of RAM would take 36 hours with a resulting text file larger than 1GB!
Thankfully, there is a quicker and easier way, thanks to some nifty USB tools bundled in with M-boot :-)
kiwi# usb usb - USB sub-system Usage: usb reset [dev] - reset (rescan) USB controller usb start [dev] - start (scan) USB controller usb stop [f] - stop USB [f]=force stop usb tree - show USB device tree usb info [dev] - show available USB devices usb storage - show details of USB storage devices usb dev [dev] - show or set current USB storage device usb part [dev] - print partition table of one or all USB storage devices usb read addr blk# cnt - read `cnt' blocks starting at block `blk#' to memory address `addr' usb write addr blk# cnt - write `cnt' blocks starting at block `blk#' from memory address `addr'
The board has 2x USB2.0 ports. The first (USB 0) is internally connected to the WiFi chip. The second (USB 1) is exposed as a USB2.0 port for us to use. Plug a freshly FAT32 formatted USB pen/thumb drive into this port. Reset the port to discover the device:
kiwi# usb reset 1 (Re)start USB 1... Check USB port[1]: [USB] usb_lowlevel_init++ [USB] USB EHCI LIB VER: 2014.10.02 [USB] Port 1 is Enabled [USB] TV_usb_init (UTMI Init) ++ [USB] UTMI Base BF207400 [USB] UHC Base BF201A00 [USB] USBC Base BF200F00 [USB] BC Base BF240A80 [USB] TV_usb_init-- [USB] Usb_host_Init++ [USB] Async base addr: 0xA7E1A100 [USB] Reg 0x28: 0xA100 0xA7E1 [USB] disable run [USB] Host Speed:2 [USB] enable aynch [USB] Usb_host_Init-- [USB] FAILED [USB] usb_lowlevel_init--[0] scanning bus for devices... [USB] control1 max:40 [USB] interface[0] conf:1 value 8: 1 USB Device(s) found scanning bus for storage devices... [USB] no_of_ep: 2 [USB] find bulk ep: 0 [USB] find bulk ep2: 1 [USB] bulk max packet size: ep(in) 0x200, ep2(out) 0x200 [USB] bulk0 is in max lun:0 1 Storage Device(s) found
Confirm that you have plugged into the port is a USB storage device. The device is registered as storage device 0, not to be confused with port 0:
kiwi# usb storage Device 0: Vendor: Kingston Rev: 1.00 Prod: DT 100 G2 Type: Removable Hard Disk Capacity: 3824.0 MB = 3.7 GB (7831552 x 512)
First task is to dump the contents of the RAM (virtual address range 0x80000000 to 0x8FFFFFFF) to a binary file on the pen drive (USB storage device 0). Remember, this is contents of the RAM with the M-boot bootloader only, we have not yet loaded any application programs to memory. We will use the fatwrite command to achieve this, where the final argument is the number of bytes to write in hex:
kiwi# fatwrite usb 0 0x80000000 RAM.bin 0x10000000 file RAM.bin not found ################################################################# ################################################################ ################################################################
Second task is to use the spi_rdc command to write the contents of the SPI flash chip to RAM, the first argument is the start address in RAM to transfer the data to, the second the start address on the SPI flash chip, the third the number of bytes to transfer, all in hex. We then use fatwrite as before to write this data to a binary file on the pen drive, where the number of bytes to write is now the 16MiB capacity of the flash chip (0x1000000)
kiwi# spi_rdc 0x80000000 0 0x1000000 offset 0x0, size 0x1000000 Flash is detected (0x0C05, 0xC8, 0x40, 0x18) initialization done! kiwi# fatwrite usb 0 0x80000000 flash.bin 0x1000000 file flash.bin not found ################################################################# ################################################################ ################################################################ ################################################################
We should now have two binary files on our USB pen drive, one a 256MiB dump of the RAM, the second a 16MiB dump of the SPI flash. Next we will analyze these files.
Updated 27th October 2023
-
Exploring the bootloader
09/28/2023 at 11:48 • 0 commentsFrom the U-boot shell prompt we can explore the command options available to us using the help command. There is a lot for us to explore:
kiwi# help ? - alias for 'help' CmdPerformanceTest- gettime - Get the system executing time ac - set a new config to the bootargs base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootargs_set- Set info exchange and set to boot args. bootcheck- bootcheck - Do boot check bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol checkfile- check file exist in u disk,and set the partition. checkstr- check_str_resume cleanallenv- cleanall environment variables to persistent storage cmp - memory compare config2env- Set config to environment. config_raw_io- Config the target device for raw I/O coninfo - print console devices and information cp - memory copy crc32 - checksum calculation custar - do usb update from the specified file that is in usb. dbg - set debug message level. Default level is INFO dc - delete the specific cofig that is in the bootargs delay - delay time, time unit is ms dhcp - boot image via network using DHCP/TFTP protocol du - du - Disable UART ebist - PHY loopback test echo - echo args to console editenv - edit environment variable edump - EMAC Register settings dump eloopback- Long loopback test env - environment handling commands epd - emac power down estart - EMAC start ewavetest- EMAC wave test exit - exit script false - do nothing, unsuccessfully fatfilesize- fatfilesize - load binary file from a dos filesystem fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatpartload- fatpartload - load binary file from a dos filesystem fatwrite- fatwrite - write binary file to a dos filesystem filelist- Dump the file list. filelisttest- This command is only for file list test filepartload- load part of a file to RAM get_mmap- get memory info from supernova's mmap gettime - gettime - Get the system executing time go - start application at address 'addr' gpio - GPIO Command: help - print command description/usage if_boot_to_pm- if boot to PM iminfo - print header information for application image imxtract- extract a part of a multi-image initDbgLevel- Initial varaible 'dbgLevel' init_raw_io- init raw_io module itest - return true/false on integer compare kernelProtect- kernelProtect - Protect kernel kernelProtectBist- kernelProtectBist - Protect kernel bist led - See led commands loadb - load binary file over serial line (kermit mode) loadenv - loadenv - load env for nand loads - load S-Record file over serial line loadspi - load data from SPI loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range m2e - Restore the address and len to env from supernova's mmap macaddr - setup EMAC MAC addr mbup - mboot upgrade md - memory display memtest - Get the performance of memory miuProtect- miuProtect - Protect miu mm - memory modify (auto-incrementing address) mscompress7- Compress or decompress lzma files msg - print string - msg [string] mstar - update kernal & root file system automatically by script file mtest - simple RAM read/write test mversion- show changelist - mversion mw - memory write (fill) nm - memory modify (constant address) nuttxProtect- nuttx Protect - Protect nuttx ota_zip_check- do OTA zip package check. ping - send ICMP ECHO_REQUEST to network host pm51 - pm51 command: pm51 [option] pmProtect- runtime pm Protect - Protect runtime PM pop_raw_io_config- pop raw_io last config printenv- print environment variables push_raw_io_config- push raw_io current config raw_io_status- get raw_io status raw_read- Read the raw datas that store in the target device Yo have to execute 'config_raw_io' before using this cmd raw_write- Write the raw datas that store in the target deviceYo have to execute 'config_raw_io' before using this cmd recovery_wipe_partition- do recovery wipe data or cache. reset - Perform RESET of the CPU riu - riu - riu command run - run commands in an environment variable sar - sar Command: saveenv - save environment variables to persistent storage setenv - set environment variables showtb - Show register command table. - showtb [stage] showvar - print local hushshell variables showversion- Show version sleep - delay execution for some time source - run script from memory spi - See SPI commands spi2usb - Read data from spi to usb spi_rdc - spi_rdc - SPI read code from SPI flash to DRAM spi_wrc - spi_wrc - SPI write code from DRAM to SPI flash test - minimal test like /bin/sh testmode- set testmode into bootargs. tftpboot- boot image via network using TFTP protocol true - do nothing, successfully udstar - Execute the script file that is stored in usb disk unlockcmi- unlock cmi transfer board - unlock update_mode- get/set update_mode updatemiureg- Call driver to update miu setting usb - USB sub-system usb2spi - write data from usb to spi usb_bin_check- do usb bin document check. usbboot - boot from USB device ustar - ustar - update kernal & root file system automatically by script file version - print monitor, compiler and linker version wdt_enable- wdt_enable n - set Watchdog timer to n secs
Looking at the version information we can confirm this is U-boot running on a MIPS platform:
kiwi# version U-Boot 2011.06-svn565 (Mar 01 2018 - 21:27:50) mips-linux-gnu-gcc (Sourcery G++ Lite 4.3-51) 4.3.2 GNU ld (Sourcery G++ Lite 4.3-51) 2.18.50.20080215
Running bdinfo we can see we have 256MiB RAM is mapped onto virtual address range 0x80000000 to 0x8FFFFFFF. We can also peek into this address space using the md command. Peeking into any address outside of this range (certainly the addresses I've tried) causes the board to crash.
kiwi# bdinfo boot_params = 0x88492E00 memstart = 0x80000000 memsize = 0x10000000 flashstart = 0x00000000 flashsize = 0xDEADBEEF flashoffset = 0x00000000 ethaddr = (not set) ip_addr = 87E52D7CI4 baudrate = 115200 bps
The flash information is clearly garbage, perhaps meant to be a decoy. Aside from the amusing hexspeak the flash is only 16MiB in size and flashsize=0xDEADBEEF is nonesense. Without a datasheet for this SoC it is difficult to understand the full memory map, there must be boot-ROM code somewhere, as well as various hardware registers. All we know so far is where the RAM resides. We don't yet know what the reset vector is.
Running printenv we can see the output of the U-boot environment variables:
kiwi# printenv UARTOnOff=on baudrate=115200 bootcmd=if mmc rescan ${mmcdev}; then if run loadbootscript; then run bootscript; else if run loaduimage; then run mmcboot; fi; fi; fi bootdelay=0 bootscript=echo Running bootscript from mmc${mmcdev} ...; source ${loadaddr} console=ttyS2,115200n8 loadaddr=0x82000000 loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage mmcargs=setenv bootargs console=${console} vram=${vram} root=${mmcroot} rootfstype=${mmcrootfstype} mmcboot=echo Booting from mmc${mmcdev} ...; run mmcargs; bootm ${loadaddr} mmcdev=0 mmcroot=/dev/mmcblk0p2 rw mmcrootfstype=ext3 rootwait osd_language=English stderr=serial stdin=serial stdout=serial ubispeedup=UBI usbtty=cdc_acm vram=16M Environment size: 788/65532 bytes
Once again we can see misleading information here.... The bootcmd is bounded by an if statement which requires the command mmc rescan 0 to return success as a condition for the execution of the boot script or kernel image. Since mmc rescan 0 is not a valid command (according to help it doesn't appear in the list) this is not possible, and there is no alternative captured in the bootcmd for if this conditional statement fails. Furthermore there is no MMC/SD hardware on this board, it isn't possible to load from an MMC/SD based file system. Clearly the U-boot is booting something, so one must presume there is a hardcoded alternative boot command somewhere in the binary and this bootcmd environment variable is either another decoy, or a remnant from a previous development version.
Last updated 27th Oct 2023
-
Establishing a UART connection and a shell
09/28/2023 at 11:43 • 0 commentsThe board has a very convenient 4-pin connector for the UART interface. With a multimeter I've managed to figure out the pinout.
4-pins: VCC(5V), TX, RX, GND
To interface with a computer I've used an FTDI FT232 based USB-UART adapter, the cheap Chinese ones on eBay are more than adequate. The cable should be arranged to connect the ground pins and cross-over TX and RX pins. Do not connect to the VCC pin. It is important to ensure your UART adapter is set to 3.3V mode (this SoC operates on 3.3V logic).
Open your favorite terminal application (I use picocom for Linux) and set the baudrate to 115200. Power on the board and you will see the following output in the terminal:
UART_115200 AC_FLOW [23456789A][23456789A][3456789AB][3456789AB]-6677 BST-OK_RAM[AT][MB][start ub][677] U-Boot 2011.06-svn565 (Mar 01 2018 - 21:27:50) MBOT-1106-0.8.KANO_TEE_NAND.a1 DRAM: 256 MiB Hello U-Boot Stack Pointer at: 87E52E00 mem initial, start 0x86DD0180, len 0x420000 msIR_Initialize [MIU INFO] miu opencreate instance at 86FE7288 with private size 80 bytes at 86FE72D0 SPI: Flash is detected (0x0C05, 0xC8, 0x40, 0x18) MDrv_SERFLASH_GetInfo() u32AccessWidth = 1 u32TotalSize = 16777216 u32SecNum = 256 u32SecSize = 65536 create instance at 86FE7328 with private size 48 bytes at 86FE7370 uboot held at [8F000000~90000000] Now running in RAM - U-Boot at: 871F0180 *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: No ethernet found. Set MAC default MAC: 0x0: 0x30: 0x1B: 0xBA:0x2: 0xDB Hit any key to stop autoboot: 0 offset 0x2E0000, size 0x10000 Flash is detected (0x0C05, 0xC8, 0x40, 0x18) initialization done! ERR>Invalid Ldr Sign ERR>Reading LDR sign from backup offset 0x80000, size 0x10000 **********************LOADER_INFO********************* @DF.0 #1.0 $1.0 ^1.5 *17 ************************************************************ SSS eLOADER 21:28:06 Mar 1 2018 ************************************************************ CPS SZE[1740] MAIN.C 2484> Checking for key sequence... enInvokemode:0 M.c 712> USB_(0) Check USB port[0]: [USB] usb_lowlevel_init++ [USB] USB EHCI LIB VER: 2014.10.02 [USB] Port 0 is Enabled [USB] TV_usb_init (UTMI Init) ++ [USB] UTMI Base BF207500 [USB] UHC Base BF204800 [USB] USBC Base BF200E00 [USB] BC Base BF240A00 [USB] TV_usb_init-- [USB] Usb_host_Init++ [USB] Async base addr: 0xA7E1A100 [USB] Reg 0x28: 0xA100 0xA7E1 [USB] disable run [USB] Host Speed:2 [USB] enable aynch [USB] Usb_host_Init-- [USB] FAILED [USB] usb_lowlevel_init--[0] scanning bus for devices... [USB] control1 max:40 [USB] interface[0] conf:1 value FF: 1 USB Device(s) found M.c 716>USB_0_Init_Success offset 0xDC0000, size 0x10000 Marker read success Marker [0xFFFFFFFF] mode[0] Jumping to Application... MsBoot.c E-1174>APP CRC Check..!! offset 0x2E8000, size 0x8000 offset 0x300000, size 0x4B29FC APP CRC Success... Decompression OK! MSBOOT.C 1196-E> Decompression OK[Go] disable interrupts ## Starting application at 0x80000224 ...
Beyond this output the interface goes silent and the unit begins the application boot process.
You will notice this unit is using the U-boot bootloader. In fact, this is M-boot, a proprietary version for MStar chipsets that combines U-boot with a first stage bootloader called S-boot (more on this later). More information on M-boot can be found a the following link (https://mstar.fandom.com/wiki/MBoot). I've also found source code and documentation for a version of M-boot at the following GitHub, (https://github.com/neuschaefer/mstar-mboot/tree/master), although unlikely this is the exact version we are using here.
You will notice the following line:
Hit any key to stop autoboot: 0
This implies we can interrupt the boot process and get a U-boot shell. The make this happen, power cycle the unit and continuously press a keyboard key, you will quickly get the bootloader finishing on a shell prompt:
UART_115200 AC_FLOW [23456789A][23456789A][3456789AB][3456789AB]-6677 BST-OK_RAM[AT][MB][start ub][677] U-Boot 2011.06-svn565 (Mar 01 2018 - 21:27:50) MBOT-1106-0.8.KANO_TEE_NAND.a1 DRAM: 256 MiB Hello U-Boot Stack Pointer at: 87E52E00 mem initial, start 0x86DD0180, len 0x420000 msIR_Initialize [MIU INFO] miu opencreate instance at 86FE7288 with private size 80 bytes at 86FE72D0 SPI: Flash is detected (0x0C05, 0xC8, 0x40, 0x18) MDrv_SERFLASH_GetInfo() u32AccessWidth = 1 u32TotalSize = 16777216 u32SecNum = 256 u32SecSize = 65536 create instance at 86FE7328 with private size 48 bytes at 86FE7370 uboot held at [8F000000~90000000] Now running in RAM - U-Boot at: 871F0180 *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: No ethernet found. Set MAC default MAC: 0x0: 0x30: 0x1B: 0xBA:0x2: 0xDB Hit any key to stop autoboot: 0 kiwi#
Updated 27th October 2023