Gemei A330
(MyBootloader) UART
目前國外已經有高手釋出GA330掌機的燒錄程式(rom.bin),但是受限於原廠的限制,這位高手並沒有釋出相關資料手冊,司徒也只能先將此燒錄程式進行逆向工程,看看是否有機會將Linux系統移植到GA330掌機身上,當然,要把所有GA330掌機的CPU暫存器全部逆向出來也是不太可能的,但是,至少這是唯一有機會將Linux移植到GA330掌機。
首先開啟Command Line並輸入如下指令進行反組譯
c:\> PATH c:/ga330/cygwin/arm-linux/bin;c:/ga330/CYGWIN/BIN;C:\windows\ c:\> arm-linux-objcopy --change-addresses=0x00000000 -I binary -O elf32-littlearm -B arm rom.bin rom-elf c:\> arm-linux-objcopy --set-section-flags .data=code rom-elf c:\> arm-linux-objdump -d rom-elf > rom.dis
司徒花了一些時間,從反組譯後的程式改寫一個簡單的Helo, world!程式,並將此訊息從UART輸出,希望從簡單的Hello, world!程式,開始進行GA330掌機的逆向破解之路
.equ UART_BASE, 0x04000000
.equ UART_FLAG, 0x04000018
.equ UART_TX, 0x04000020
.global _start
_start: b begin
undefined: b undefined
software: b software
preabort: b preabort
dataabort: b dataabort
irq: b irq_process
fiq: b fiq
.align
welcome_msg:
.ascii "\r\n"
.ascii "+---------------------------------------------------+\r\n"
.ascii "| (MyBootloader) UART for Gemei A330 by Steward_Fu |\r\n"
.ascii "| 2013.3.10 |\r\n"
.ascii "+---------------------------------------------------+\r\n"
.asciz "#> "
.align
irq_process:
sub sp, sp, #4
stmdb sp!, {r8}
ldr r8, =0x00103ff0
ldr r8, [r8]
str r8, [sp, #4]
ldmia sp!, {r8, pc}
begin:
ldr r0, =0x0408800c
ldr r1, =0x00ffeaaa
str r1, [r0] /* [0x0408800c] <= 0x00ffeaaa */
mov r0, #1048576 /* r0 = 0x100000 */
add r1, r0, #8192 /* r1 = 0x102000 */
add r3, r1, #8192 /* r3 = 0x104000 */
relocate_code:
/* copy code from 0x1000000 to 0x102000 with 0x2000 bytes */
cmp r1, r3
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc relocate_code
add r0, pc, #4 /* r0 = pc + 4 */
add r0, r0, #8192 /* r0+= 0x2000 */
mov pc, r0 /* jump to ram address */
bl init_irq
ldr r0, =0x00102b7c
ldr r1, =0x00102b7c
ldr r3, =0x00102b80
cmp r0, r1
beq init_boot
relocate_ram:
cmp r1, r3 /* copy data from 0x00102b7c to 0x00102b80 with 4 bytes */
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc relocate_ram
init_boot:
ldr r1, =0x00102b94
mov r2, #0
init_ram:
cmp r3, r1
strcc r2, [r3], #4 /* zero ram from 0x00102b80 to 0x00102b94 */
bcc init_ram
b init_uart_reg
init_irq:
mrs r0, CPSR
bic r0, r0, #31 /* 0x1f */
orr r1, r0, #219 /* 0xdb */
msr CPSR_fsxc, r1 /* disable irq and fiq, enter udefined mode*/
ldr sp, =0x00103cf0
orr r1, r0, #215 /* 0xd7 */
msr CPSR_fsxc, r1 /* disable irq and fiq, enter abort mode*/
ldr sp, =0x00103d70
orr r1, r0, #210 /* 0xd2 */
msr CPSR_fsxc, r1 /* disable irq and fiq, enter irq mode*/
ldr sp, =0x00103f70
orr r1, r0, #209 /* 0xd1 */
msr CPSR_fsxc, r1 /* disable irq and fiq, enter fiq mode*/
ldr sp, =0x00103ff0
bic r0, r0, #223 /* 0xdf */
orr r1, r0, #19 /* 0x13 */
msr CPSR_fsxc, r1 /* enable irq and fiq, enter supervisor mode*/
ldr sp, =0x00103bf0
mov pc, lr
send_char:
mov r2, #0x04000000 /* uart base address */
wait_tx_flag:
ldr r1, [r2, #0x18] /* r1 = [0x4000018] */
tst r1, #0x200 /* tx flag */
bne wait_tx_flag
strb r0, [r2, #0x20] /* [0x4000020] = char */
bx lr
show_message:
str lr, [sp, #-4]!
mov r3, r0
b check_char
next_char:
add r3, r3, #1
bl send_char
check_char:
ldrb r0, [r3] /* if not ending char, send this char via uart */
cmp r0, #0
bne next_char
ldr pc, [sp], #4
init_uart_reg:
mov r0, #19
mov r1, #67108864
str r0, [r1, #40] /* [0x4000040] = 0x13 */
mov r0, #7
mov r1, #67108864
str r0, [r1] /* [0x4000000] = 0x07 */
mov r0, #133
mov r1, #67108864
str r0, [r1, #4] /* [0x4000004] = 0x85 */
mov r0, #150
mov r1, #67108864
str r0, [r1, #8] /* [0x4000008] = 0x96 */
add r0, r1, #565248
ldr r1, [r0, #16]
orr r1, r1, #2
str r1, [r0, #16] /* [0x408a010]|= 2 */
adr r0, welcome_msg /* pointer to uart initial message */
bl show_message
while:
b while
經由上面的程式註解可以知道RAM的起始執行位置是位於0x1002000,因此我們需要一個LD Script檔案進行定位,該檔案內容如下
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x102000;
. = ALIGN(4);
.text : {
*(.text)
}
}
接著使用如下指令進行編譯即可產生boot.bin燒錄檔案
c:\> PATH c:/ga330/cygwin/arm-linux/bin;c:/ga330/CYGWIN/BIN;C:\windows\ c:\> arm-linux-gcc -fno-pic -pipe -O2 -Wall -finline-functions -fomit-frame-pointer -msoft-float -fno-builtin -mcpu=arm926ej-s -c ga330_boot.s c:\> arm-linux-gcc -nostdlib -o boot-elf32 ga330_boot.o -T ga330_link c:\> arm-linux-objcopy -O binary boot-elf32 boot.bin
接著使用司徒之前介紹的燒錄步驟,將boot.bin燒錄到MiniSD並插上UART線,接著按下DPad的下按鈕開機,即可看到如下的開機訊息(Baudrate: 115200bps)
+---------------------------------------------------+ | (MyBootloader) UART for Gemei A330 by Steward_Fu | | 2013.3.10 | +---------------------------------------------------+ #>