FreeCalypso > hg > freecalypso-reveng
comparison leo-obj/bootloader/Notes @ 276:85c65bc1d033
leo-obj/bootloader/Notes: bootloader blob reverse-engineered
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 21 Sep 2018 23:08:32 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 275:cbd944ebeff0 | 276:85c65bc1d033 |
|---|---|
| 1 The present bootloader.lib blob contains not one but two bootloaders inside, | |
| 2 speaking different protocols. There is the original TI GSM bootloader, and | |
| 3 then there is the so-called FLUID bootloader. The original TI GSM bootloader | |
| 4 initializes both UARTs at what was intended to be 115200 baud, but will actually | |
| 5 result in 230400 baud on 26 MHz hardware, as there is no VCLKOUT_DIV2 or | |
| 6 VTCXO_DIV2 setting done anywhere. Then it provides a certain time window | |
| 7 during which it listens on both UARTs for a bootloader command packet, and if | |
| 8 it gets a COM_GET_MONITOR_ID command, it will respond to it and stop the normal | |
| 9 flash boot process. It will then listen for further command packets without a | |
| 10 timeout. It appears that this bootloader was originally designed with commands | |
| 11 that write directly to flash, but the present version no longer has any of those | |
| 12 commands, and instead it has commands to load a code image into RAM and to jump | |
| 13 to it. | |
| 14 | |
| 15 The so-called FLUID bootloader is a separate beast with its own self-contained | |
| 16 code and its own serial protocol. There is one special command packet that can | |
| 17 be sent to the first bootloader that will cause it to call fluid_bootloader(), | |
| 18 and the latter function never returns. The FLUID bootloader reinitializes both | |
| 19 UARTs again (same baud rate, and same bogosity on 26 MHz platforms), and then | |
| 20 it sends out a continuous stream of 'H' (hello) characters on both UARTs until | |
| 21 it hears a response, telling it which UART it should use for further | |
| 22 communication. | |
| 23 | |
| 24 Commands for the original (pre-FLUID) bootloader are binary strings or packets | |
| 25 of the following format: | |
| 26 | |
| 27 * begin with 0xAA byte | |
| 28 * the byte after the initial 0xAA is the number of bytes to follow, | |
| 29 including stuffing bytes | |
| 30 * the payload bytes follow, if there is 0xAA in the payload, it is duplicated | |
| 31 | |
| 32 The command to enter the FLUID bootloader is just 0xDD (one byte) before | |
| 33 string encoding, or 0xAA 0x01 0xDD in the full packet form which the host | |
| 34 needs to send. The native commands for the first bootloader are: | |
| 35 | |
| 36 0x00 = COM_GET_MONITOR_ID | |
| 37 0x09 = COM_LOAD_APPLICATION | |
| 38 0x0A = COM_SEND_RUN_ADDRESS | |
| 39 | |
| 40 COM_GET_MONITOR_ID and COM_LOAD_APPLICATION take no arguments, i.e., just | |
| 41 0xAA 0x01 and the opcode. After receiving COM_LOAD_APPLICATION, the bootloader | |
| 42 will switch to expecting S-records: you need to send it a complete S-record | |
| 43 image consisting of an S0 header record, one or more S3 payload records and a | |
| 44 terminating S7 record. Each S-record is sent as follows: the 'S' character and | |
| 45 the record type digit are sent literally in ASCII, then the rest of the record | |
| 46 (starting with the length byte and ending with the checksum) is sent as binary | |
| 47 bytes. No CR or LF characters are sent over the wire. The code is designed to | |
| 48 take *.m0 S-record images produced by TI's hex470: the S0 and S7 records must | |
| 49 be exactly as produced by that tool, no variations allowed, and the data format | |
| 50 is 16-bit word-oriented with the upper byte first, i.e., byte-reversed relative | |
| 51 to the natural ARM little-endian byte order. | |
| 52 | |
| 53 COM_SEND_RUN_ADDRESS opcode is followed by 4 bytes of address in MSB-first byte | |
| 54 order, for a total pre-stuffing command packet length of 5 bytes. This command | |
| 55 packet is the only one in the present version for which 0xAA escaping may be | |
| 56 needed. The transfer of control is done with BX. | |
| 57 | |
| 58 cmdboot.obj: | |
| 59 | |
| 60 cmd_check_application_in_flash(): checks the 32-bit word in flash where the | |
| 61 IRQ vector branch points, returns 1 if the word is not all-1s (good image) | |
| 62 or 0 otherwise (bad image). | |
| 63 | |
| 64 convert.obj: | |
| 65 | |
| 66 This module has 0x10 bytes of purely local (static) bss. | |
| 67 | |
| 68 con_initialize_conversion(): sets 32-bit words at .bss+4 and .bss+0xC to 0. | |
| 69 | |
| 70 serial.obj: | |
| 71 | |
| 72 .bss+4: byte var initialized to 0 in ser_initialize_flash_data_detection() | |
| 73 appears to be a boolean flag indicating if the S0 header record | |
| 74 has already been received or not | |
| 75 | |
| 76 .bss+5: S-record checksum accumulator | |
| 77 | |
| 78 .bss+7: byte var initialized to 0 in ser_initialize_flash_data_detection() | |
| 79 used to decide if we are looking for the 'S' character or for the digit | |
| 80 immediately after the 'S' | |
| 81 | |
| 82 .bss+0xC: 32-bit var initialized to 1 in ser_initialize_flash_data_detection() | |
| 83 0 = receiving payload data bytes | |
| 84 1 = expect beginning of S-record | |
| 85 2 = expect the bytes after S0 | |
| 86 3 = expect the bytes after S7 | |
| 87 4 = expect the bytes after S3 | |
| 88 5 = state after the S3 record length byte (receiving address bytes) | |
| 89 6 = expect S3 record checksum byte | |
| 90 | |
| 91 ser_initialize_serial_link(): both UARTs are initialized sensibly, the baud | |
| 92 rate divisor is set to 7. | |
| 93 | |
| 94 start.obj: | |
| 95 | |
| 96 static function at 0x0: an init function called immediately at the beginning | |
| 97 by sta_select_application(). This function disables all interrupts, stops the | |
| 98 watchdog timer, and puts the DPLL into bypass mode with the external clock | |
| 99 pass-thru, removing the division by 2 set by the bogus code in bootloader.s. | |
| 100 | |
| 101 sta_select_application(): | |
| 102 calls the static function at 0x0 | |
| 103 calls ser_initialize_serial_link() | |
| 104 calls con_initialize_conversion() | |
| 105 calls cmd_check_application_in_flash() |
