Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

The TL866 II PLUS has a bootloader installed at the start of the internal flash

which is used to update the firmware. The hardware reset vector (the instruction at
0000h) points to the bootloader. On each boot the bootloader inspects various state
(TBD) and determines whether it should execute itself to allow firmware updates or
jump into the main firmware.

The process of reverse engineering the bootloader is still ongoing.

- 1 USB Protocol
- 1.1 Reset
- 1.2 Report
- 1.3 Erase
- 1.4 Write Block

## USB Protocol

The bootloader and the stock firmware communicate with the host via a simple custom
USB protocol. It uses three bidirectional bulk endpoints on Interface 0. Endpoint 1
Out is used to send commands and Endpoint 1 In is used to read status responses.
For commands that transfer large amounts of data the payload is split evenly
between Endpoint 2 and Endpoint 3, presumably to increase transfer speed.

When sending a command, the first 8 bytes are always the command header and are
written to Endpoint 1. The behavior for the payload — the data, if any, to be sent
after the command header — depends on its size. If the payload plus the 8-byte
header fit in a single 64-byte packet, the payload is sent in the same packet as
the header on Endpoint 1. If the payload is exactly 64 bytes, it's sent in a single
packet on Endpoint 2. Otherwise, the payload is split between Endpoint 2 and
Endpoint 3. If the total size of the payload is less than 128 bytes, each endpoint
gets exactly half, with Endpoint 2 first. Otherwise, the data is split into 64-byte
blocks. The first half of the blocks are sent to Endpoint 2 and the other half to
Endpoint 3. If there are an odd number of whole blocks Endpoint 3 gets the extra
one. If the final block is partial, it is always sent to Endpoint 3.

### Reset

The reset command asks the device to reboot. When used from the stock firmware the
device resets into the bootloader, and when used from the bootloader the device
resets to the stock firmware.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | command | 1 | 3F | the command identifier |
| 1 | _reserved_ | 7 | 0 | reserved, set to zero |

When resetting from the stock firmware, another command is transmitted first. This
may be some kind of key required to permit reset. If this command isn't sent first,
the reset command appears to succeed but the device reboots to the stock firmware,
not the bootloader.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | command | 1 | 3D | the command identifier |
| 1 | _reserved_ | 3 | 0 | reserved, set to zero |
| 4 | key? | 4 | 86 B9 78 A5 | unknown, maybe just a fixed key? Set statically in
the official client. |

### Report
The report command requests that the firmware identify itself.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 00 | the command identifier |
| 1 | _reserved_ | 7 | 0 | reserved, set to zero |

The device will respond with a 41-byte structure:

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 00 | the command, echoed |
| 1 | bStatus | 1 | 01 | no longer used? |
| 2 | _unknown_ | 2 | | |
| 4 | bFwVersionMinor | 1 | | firmware version minor part: 00.0.xx |
| 5 | bFwVersionMajor | 1 | | firmware version major part: 00.x.00 |
| 6 | bModel | 1 | 05 | device model: 05 is the TL866II-Plus, 06 is the XGecu T500
|
| 7 | _unknown_ | 1 | | |
| 8 | sDeviceCode | 8 | | ISO 8859-1 string (no zero terminator) |
| 16 | sSerialNumber | 20 | | ISO 8859-1 string (no zero terminator) |
| 36 | _unknown_ | 4 | | |
| 40 | bDeviceVersion | 1 | | firmware version device part: xx.0.00 |

In versions of the TL866 A/CS firmware 03.2.82 and earlier, the bStatus field was
used to indicate whether the device was currently running the stock firmware (value
01) or the bootloader (value 02). A/CS firmware 03.2.85 and the TL866II-Plus appear
to always return 01. The only difference in the report output between the stock
firmware and the bootloader on the TL866II-Plus is the version number, for which
the bootloader always returns 1.0.

### Erase

The erase command erases the firmware area of the internal flash (i.e. everything
but the bootloader).

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 3C | the command identifier |
| 1 | _reserved_ | 7 | 0 | reserved, set to zero |

The device responds with an 8-byte acknowledgement.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 3C | the command, echoed |
| 1 | _unknown_ | 7 | | |

### Write Block

The write block command receives an encrypted data block, decrypts it, and writes
the cleartext to the flash. As with all commands, it has an 8-byte header. The
encrypted data is sent after the command header.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 3B | the command identifier |
| 1 | bKeyOffset | 1 | | An offset into the XOR table used for decryption by the
bootloader. |
| 2 | wBlockSize | 2 | | The size in bytes of the encrypted data to be sent. |
| 4 | dAddress | 4 | | The program memory address of the start of the block. |

The device does not send a response to the write block command. Instead, another
command is sent to retrieve the status.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | bCommand | 1 | 39 | the command identifier |
| 1 | _reserved_ | 7 | 0 | reserved, set to zero |

The device responds with a 32-byte packet. The unknown parts of the structure have
only ever been observed to be all zeroes.

| Offset | Field | Size | Value | Description |


| --- | --- | --- | --- | --- |
| 0 | _unknown_ | 1 | | |
| 1 | bStatus | 1 | | 00 on success; any other value indicates error |
| 2 | _unknown_ | 30 | | |

You might also like