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() |