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