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