-
Notifications
You must be signed in to change notification settings - Fork 52
/
usb-loader.S
85 lines (72 loc) · 1.86 KB
/
usb-loader.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.text
.global _start
_start:
disable_interrupts:
mrs r0, cpsr
mov r1, #0xc0
orr r0, r0, r1
msr cpsr_cxsf, r0
relocate_stack:
ldr r0, =0x7000bffc // stack_start
mov sp, r0
print_welcome_banner:
adr r0, welcome_banner
bl uart_puts
load_program:
adr r0, size_buffer
mov r1, #4
mvn r2, #0
# This function address was discovered by disassembling the ROM, which
# begins around offset 0xfff00000. When the MTK Flash Tool loads code into
# an unflashed MTK chip, it makes calls to a few well-defined positions that
# contain pointers to read a buffer, write a buffer, and flush the current
# write buffer. The programming interface is the same for both USB and
# serial. However, since the MT6260 series of parts primarily boots
# off of USB, we are only interested in the USB thunks.
# The prototype for this function is:
# void usb_uart_read(void *buffer, int bytes, int timeout)
ldr r3, =0xfff03639
blx r3
ldr r1, size_buffer
# r1 now contains the number of bytes to load.
# r0 contains the current offset to write to.
# Load bytes from the serial port into RAM.
mov r0, #0x70000000
orr r0, r0, #0x6000
mvn r2, #0
ldr r3, =0xfff03639
blx r3
jump_to_new_program:
adr r0, launch_message
bl uart_puts
mov r0, #0x70000000
orr r0, r0, #0x6000
mov pc, r0
.align 4
welcome_banner: .ascii "Fernvale bootloader\r\nWrite four bytes of program "
.asciz "size, then write program data...\r\n>"
launch_message: .asciz "Launching program...\r\n"
size_buffer: .long 0
.align 4
uart_puts:
push {lr}
mov r3, r0
mov r1, #0
uart_puts_count_chars_loop:
ldrb r2, [r3], #1
cmp r2, #0
beq uart_puts_print
add r1, r1, #1
b uart_puts_count_chars_loop
uart_puts_print:
mvn r2, #0
# Call:
# void usb_uart_write(char *data, int bytes, int timeout)
ldr r3, =0xfff03653
blx r3
# Call:
# void usb_uart_flush(void)
ldr r3, =0xfff04845
blx r3
uart_puts_exit:
pop {pc}