mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
162 lines
7.0 KiB
Markdown
162 lines
7.0 KiB
Markdown
# RTLPlayground
|
|
A Playground for Firmware development for RTL8372/RTL8373 based 2.5GBit Switches
|
|
|
|
## Compiling
|
|
Install the following particular build requisites (Debian 12, should work on Ubuntu)
|
|
```
|
|
sudo apt install sdcc xxd
|
|
```
|
|
|
|
Now, building the firmware image should work:
|
|
```
|
|
$ make
|
|
sdas8051 -plosgff crtstart.asm
|
|
sdcc -mmcs51 -c rtlplayground.c
|
|
sdcc -mmcs51 -c rtl837x_flash.c
|
|
sdcc -mmcs51 -Wl-bHOME=0x100 -o rtlplayground.ihx crtstart.rel rtlplayground.rel rtl837x_flash.rel
|
|
objcopy --input-target=ihex -O binary rtlplayground.ihx rtlplayground.img
|
|
if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi
|
|
echo "0000000: 00 40" | xxd -r - rtlplayground.bin
|
|
cat rtlplayground.img >> rtlplayground.bin
|
|
```
|
|
Note, that the image generated ends in .bin, not .img, in order to make
|
|
IMSProg happy.
|
|
|
|
## Installation
|
|
You can play with the image using ghidra or flash real Switch Hardware
|
|
|
|
### Supported Hardware
|
|
If you do not have an RTL837x-based switch device such as the ones
|
|
mentionned here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
|
(https://github.com/up-n-atom/SWTG118AS) or one of the other that
|
|
deployment was tested on, including:
|
|
- keepLINK kp-9000-6hx-x2 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
|
- keepLINK KP-9000-6XHML-X2, same as above, but Managed
|
|
- keepLINK kp-9000-6hx-x (RTL8372 + RTL8221B 2.5GBit PHY: 5 x 2.5GBit + 1x 10GBit SFP+)
|
|
- keepLINK kp-9000-9xh-x-eu (2 x RTL8373, one slaved to the other via MDIO: 8x 2.5GBit + 1x 10GBit SFP+)
|
|
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
|
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
|
AliExpress as keepLINK 5+1 port managed
|
|
|
|
you can use ghidra to look at the image layout to understand how the image
|
|
is organized.
|
|
|
|
### Understanding the image using ghidra
|
|
Start ghidra, load file starting from offset 0x0002 into
|
|
memory starting at 0x0000. The lengthe is 0x10000. Select generic 8051, big
|
|
endian.
|
|
|
|
After loading, the boot vector is at 0x0000, which will jump to 0x0100 for
|
|
the boot routine.
|
|
|
|
The firmware uses only bank 1 of the RTL837x since it is quite short.
|
|
Otherwise the firmware would be organized as follows
|
|
```
|
|
--------------------------- 0x0000 ---------------------------------
|
|
Boot-Vector
|
|
ISRs
|
|
Common Code
|
|
Trampoline for inter-bank calls
|
|
Inter-bank calls, calling trampoline, one for each callable function
|
|
|
|
----- Bank 1 0x4000 ------ ---- Bank 2 0x4000 ----- -------- .....
|
|
Overlay 1 Overlay 2 Overlay n
|
|
|
|
--------- 0xffff --------- -------- 0xffff -------- -------- 0xffff
|
|
```
|
|
The RTL837x firmware images are organized as follows:
|
|
The first 2 bytes of the image give the size of the prefetched data at the
|
|
start of the CPU power up. The default is 0x4000 (bytes: 0x00 0x40), which
|
|
means that the entire shared area of the code memory in all banks,
|
|
0x4000 bytes is read immediately into the code RAM.
|
|
|
|
Common code starts at
|
|
0x0002 in the image and has length 0x3ffd, the first bank starts at 0x4000
|
|
in the image, is mapped to 0x4000 and has length 0xc000. The second bank
|
|
starts at 0x10000, is mapped to 0x4000 and has length 0xc000. The third
|
|
bank would start at 0x1c000 and would again be mapped to 0x4000.
|
|
There are about 30 banks in use for managed switches, unmanaged ones use
|
|
2-3, while the hardware would allow to use 0x3f banks, i.e. up to 4 MB of
|
|
flash.
|
|
|
|
|
|
### Hardware supported by the code so far
|
|
|
|
- The following hardware is supported:
|
|
- Clock generation, including different divider settings
|
|
- Interrupt control for timer, serial, external irqs 0, 1
|
|
- Serial console via SFRs
|
|
- Flash operations via SFRs
|
|
- Access to Switch registers via SFRs
|
|
- LED setup
|
|
- Reset
|
|
- Some switch settings
|
|
- Access to PHYs via MDIO (only conceptually, not tested):
|
|
- Clause 22? via SFR
|
|
- Clause 45 via SFR
|
|
|
|
Access to CPU-Port NIC via a different set of SFRs and external IRQ1 is conceptually understood, but not
|
|
included because without proper switch register configuration it cannot be
|
|
tested.
|
|
|
|
The RTL8372/3 have 256 bytes of internal RAM (INTMEM) accessible through MOV
|
|
instructions, which are used for the stack and important globals. Some of
|
|
these are bit-adressable, e.g. for storing global flags.
|
|
|
|
Additionally, 64kB of extended RAM (XMEM) is built in, which is accessed
|
|
through the MOVX instruction. It is used for global variables, for most
|
|
of the function argument passing that is not done using the 8 registers
|
|
R0-R7 or registers A/B, and for local variables (which requires extremely
|
|
careful planning). The flash memory is transparently accessible for code
|
|
being executed and can be used to store configuration. Access is done through
|
|
the MOVC instruction, possibly setting the bank register before and
|
|
resetting it to access the entire 4MB space. Code is prefetched from flash
|
|
and cached in a small RAM automatically by the HW.
|
|
|
|
The peripherial functions are accessed through 2 different mechanisms:
|
|
- Special Function Registers (SFRs, 0x80-0xff) for banking, timers, UART, access to
|
|
switch registers, MDIO, SPI (flash) and NIC transfers. Some SFRs are not
|
|
used for HW purposes and can be used as RAM. Some SFRs are bit-adressable,
|
|
allowing for very tight event wait loops (a single 2-byte instruction).
|
|
- 0x10000 switch registers, which appear to be very similar to the registers
|
|
of the RTL838x, for which source code and datasheets are available. This
|
|
controls clock dividers, GPIO/LEDs and general switch functionality.
|
|
There should be an I2C controller that reads the SFP EEPROMs, but it is not
|
|
clear whether this is bit-banged GPIO like for the RTL83xx or dedicated HW
|
|
as for the RTL93xx.
|
|
|
|
The playground image shows access to the different types of memory using the
|
|
SDCC compiler. Any support of Linux or e.g. Zephyr would require porting gcc.
|
|
There are FreeRTOS ports to 8051 processors using sdcc, however.
|
|
|
|
|
|
### Installation on an actual switch
|
|
|
|
> [!CAUTION]
|
|
> NOTE THAT WHILE THIS PROCEDURE HAS BEEN SUCCESSFULLY TESTED ON ALL DEVICES ABOVE,
|
|
> ABSOLUTELY NO GUARANTY CAN BE GIVEN THAT YOU WILL NOT DESTROY YOUR SWITCH,
|
|
> ANY OTHER EQUIPMENT INVOLVED OR HARM YOURSELF BY OPENING THE ELECTRONIC
|
|
> DEVICE. OPENING THE SWITCH WILL VOID ITS WARRANTY.
|
|
|
|
There is no support for uploading the firmware via ethernet. Instead you
|
|
need to open the switch and flash the image directly onto the flash chip,
|
|
which is done easiest using a SOIC-8 clip (alternatively you de-solder the
|
|
flash chip and install a SOIC adapter):
|
|
- Disconnect power from switch
|
|
- Attach the clip onto the flash chip
|
|
- Connect USB of flash programmer, the power LED on the switch will light
|
|
up, check cabling if not. Don't panic, mixing up GND and 3.3V does not
|
|
seem to destroy the switch (at leasts the on I did this to).
|
|
- Use IMSProg (flashrom should work, too) to detect the clip
|
|
- MAKE A BACKUP OF THE EXISTING FIRMWARE!
|
|
- then load the firmware into IMSProg
|
|
- and program flash
|
|
|
|
Now you can connect a serial cable to the UART port found on all the
|
|
devices, set 8N1 @ 57600 baud and power up the switch.
|
|
|
|
The device will perform some examples and provide a minimal console, which
|
|
currently only allows to do a reset.
|
|
|
|
Enjoy playing!
|