mirror of
https://github.com/cjdelisle/openwrt.git
synced 2025-09-16 06:39:29 +00:00
EcoNet EN75xx is a big endian MIPS platform used in XPON (fiber), DSL, and SIM (3g/4g) applications. Complete GPL vender SDKs exist for this platform, but are based on Linux 2.6. The SmartFiber XP8421-B is a fiber modem which is available for $20 online and has 512MB of memory, 256MB of SPI NAND flash and 2 USB 2.0 ports in addition to ethernet, wifi and XPON. Many of the drivers for this SoC bear little resemblence to anything currently supported in OpenWRT or Linux upstream, so there is no realistic timeline for reaching a feature complete port. The aim of this patch is to provide the foundation (INTC, timer, SPI, NAND, image format) to be able to flash and boot to a shell. I'm not getting paid for this, I'm just a hobbyist, and this is my first contribution. So any advice and guidance to help get this landed will be most appreciated. The XP8421-B, and apparently many other devices of this platform, use a dual-image layout. I have chosen to reuse this to support dual-boot between OpenWRT and the factory firmware. Certain design decisions were made with the goal of not overwriting data that is used by the factory OS. Flashing instructions (from bootloader): 1. Build and then locate the squashfs-tclinux.trx image file 2. Get the length of that file in hex: `printf '%X\n' "$(stat -c%s the-file-squashfs-tclinux.trx)"` 3. Connect to device with xmodem capability, e.g. `picocom --send-cmd lsx -vv -b 115200 /dev/ttyUSB0` 4. Switch device on and press a key within 3 seconds 5. Enter bootloader username and password: telecomadmin nE7jA%5m 6. Type: `xmdm 80020000 <file length hex>` 7. Quickly start xmodem and send the file, in picocom that is `ctrl+a ctrl+s <paste-the-file-name> enter` If the transfer fails to start, wait 30 seconds to a minute for the bootloader prompt to return and then try the command again. 8. Once the transfer has completed successfully, type the following `flash 80000 80020000 <file length hex>` 9. Type `go` or simply restart the device to boot into OpenWRT Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
119 lines
2.6 KiB
Bash
Executable File
119 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
set -e
|
|
|
|
# This is not necessary, but it makes finding the rootfs easier.
|
|
PAD_ROOTFS_OFFSET_TO=4194304
|
|
|
|
# Constant
|
|
HDRLEN=256
|
|
|
|
die() {
|
|
echo "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
[ $# -eq 3 ] || die "SYNTAX: $0 <kernel lzma> <rootfs squashfs> <version string>"
|
|
kernel=$1
|
|
rootfs=$2
|
|
version=$3
|
|
which zytrx >/dev/null || die "zytrx not found in PATH $PATH"
|
|
[ -f "$kernel" ] || die "Kernel file not found: $kernel"
|
|
[ -f "$rootfs" ] || die "Rootfs file not found: $rootfs"
|
|
[ "$(echo "$version" | wc -c)" -lt 32 ] || die "Version string too long: $version"
|
|
|
|
kernel_len=$(stat -c '%s' "$kernel")
|
|
header_plus_kernel_len=$(($HDRLEN + $kernel_len))
|
|
rootfs_len=$(stat -c '%s' "$rootfs")
|
|
|
|
if [ "$PAD_ROOTFS_OFFSET_TO" -gt "$header_plus_kernel_len" ]; then
|
|
padding_len=$(($PAD_ROOTFS_OFFSET_TO - $header_plus_kernel_len))
|
|
else
|
|
padding_len=0
|
|
fi
|
|
|
|
echo "padding_len: $padding_len" >&2
|
|
|
|
padded_rootfs_len=$(($padding_len + $rootfs_len))
|
|
|
|
echo "padded_rootfs_len: $padded_rootfs_len" >&2
|
|
|
|
total_len=$(($header_plus_kernel_len + $padded_rootfs_len))
|
|
|
|
echo "total_len: $total_len" >&2
|
|
|
|
padding() {
|
|
head -c $padding_len /dev/zero | tr '\0' '\377'
|
|
}
|
|
|
|
to_hex() {
|
|
hexdump -v -e '1/1 "%02x"'
|
|
}
|
|
|
|
from_hex() {
|
|
perl -pe 's/\s+//g; s/(..)/chr(hex($1))/ge'
|
|
}
|
|
|
|
trx_crc32() {
|
|
tmpfile=$(mktemp)
|
|
outtmpfile=$(mktemp)
|
|
cat "$kernel" > "$tmpfile"
|
|
padding >> "$tmpfile"
|
|
cat "$rootfs" >> "$tmpfile"
|
|
# We just need a CRC-32/JAMCRC of the concatnated files
|
|
# There's no readily available tool for this, but zytrx does create one when
|
|
# creating their TRX header, so we just use that.
|
|
zytrx \
|
|
-B NR7101 \
|
|
-v x \
|
|
-i "$tmpfile" \
|
|
-o "$outtmpfile" >/dev/null
|
|
dd if="$outtmpfile" bs=4 count=1 skip=3 | to_hex
|
|
rm "$tmpfile" "$outtmpfile" >/dev/null
|
|
}
|
|
|
|
tclinux_trx_hdr() {
|
|
# TRX header magic
|
|
printf '2RDH' | to_hex
|
|
|
|
# Length of the header
|
|
printf '%08x\n' "$HDRLEN"
|
|
|
|
# Length of header + content
|
|
printf '%08x\n' "$total_len"
|
|
|
|
# crc32 of the content
|
|
trx_crc32
|
|
|
|
# version
|
|
echo "$version" | to_hex
|
|
head -c "$((32 - $(echo "$version" | wc -c)))" /dev/zero | to_hex
|
|
|
|
# customer version
|
|
head -c 32 /dev/zero | to_hex
|
|
|
|
# kernel length
|
|
printf '%08x\n' "$kernel_len"
|
|
|
|
# rootfs length
|
|
printf '%08x\n' "$padded_rootfs_len"
|
|
|
|
# romfile length (0)
|
|
printf '00000000\n'
|
|
|
|
# "model" (32 bytes of zeros)
|
|
head -c 32 /dev/zero | to_hex
|
|
|
|
# Load address (CONFIG_ZBOOT_LOAD_ADDRESS)
|
|
printf '80020000\n'
|
|
|
|
# "reserved" 128 bytes of zeros
|
|
head -c 128 /dev/zero | to_hex
|
|
}
|
|
|
|
tclinux_trx_hdr | from_hex
|
|
cat "$kernel"
|
|
padding
|
|
cat "$rootfs"
|