Magic Lantern Firmware Wiki
Advertisement

an analysis of generated "autoexec", here with

ROMBASEADDR             = 0xFF010000
RESTARTSTART            = 0x0008B000

compared to reboot.c and 5d-hack.c

800000               EXPORT _start
800000 _start
800000               B       loc_80000C
800000 ; ----------------------------------
800004 aGaonisoy     DCB "gaonisoy"
80000C ; ----------------------------------
0000C
80000C loc_80000C                  
80000C               MRS     R0, CPSR
800010               BIC     R0, R0, #0x3F
800014               ORR     R0, R0, #0xD3
800018               MSR     CPSR_cf, R0
80001C               MOV     SP, #0x1900
800020               MOV     R11, #0
800024               B       cstart
800024 ; End of function _start
Makefile
autoexec: reboot.o
-e _start
-Ttext=0x800000
asm(
".text\n"
".globl _start\n"
"_start:\n"
" b 1f\n"
".ascii \"gaonisoy\"\n" // 0x124, 128
"1:\n"
"MRS R0, CPSR\n"
"BIC R0, R0, #0x3F\n" // Clear I,F,T
"ORR R0, R0, #0xD3\n" // Set I,T, M=10011 == supervisor
"MSR CPSR, R0\n"
" ldr sp, =0x1900\n" // 0x130
" mov fp, #0\n"
" b cstart\n"
);
00800028                 ALIGN 0x1000
00801000

reboot.c

/** Include the relocatable shim code */
extern uint8_t blob_start;
extern uint8_t blob_end;

asm(
 ".text\n"
 ".align 12\n" // 2^12 == 4096 bytes
 ".incbin \"magiclantern.bin\"\n" //
801000 blob_start    DATA XREF: _start+2E018
801000              
801000                 B       loc_801004
801004
801004 loc_801004
801004                 LDR     R2, =0xB7F00
801008                 LDR     R3, =0xD0680
80100C                 CMP     R2, R3
801010                 BCS     loc_801024
801014                 MOV     R1, #0
801018
801018 loc_801018              
801018                 STR     R1, [R2],#4
80101C                 CMP     R2, R3
801020                 BCC     loc_801018
801024
801024 loc_801024              blob_start+10

5d-hack.c

extern uint32_t _bss_start[], _bss_end[];

static inline void
zero_bss( void )
{
        uint32_t *bss = _bss_start;
        while( bss < _bss_end )
                *(bss++) = 0;
}


void
__attribute__((noreturn,noinline,naked))
copy_and_restart( int offset )
{
        zero_bss();
801024 loc_801024 
801024                 LDR     R2, =0xC85F4
801028         RSBS    R1, R0, #1
80102C                 MOVCC   R1, #0
801030                 STR     R1, [R2]
// Set the flag if this was an autoboot load
autoboot_loaded = (offset == 0);
801034                 LDR     R12, =0xB7F00
801038                 MOV     R2, 0xFF010000
801040
801040 loc_801040                  
801040                 ADD     R1, R12, R2
801044                 LDR     R0, [R2],#4
801048                 ADD     R1, R1, #0xFF0000
80104C                 CMN     R2, #0xFE0000
801050                 STR     R0, [R1]
801054                 LDR     R1, =0xB7F00
801058                 BNE     loc_801040

arm-mcr.h

static inline void
blob_memcpy(
        void *          dest_v,
        const void *    src_v,
        const void *    end
)

5d-hack.c

// Copy the firmware to somewhere safe in memory
const uint8_t * const firmware_start = (void*) ROMBASEADDR;
const uint32_t firmware_len = RELOCSIZE;
uint32_t * const new_image = (void*) RELOCADDR;

blob_memcpy( new_image, firmware_start, firmware_start + firmware_len );
INSTR( HIJACK_INSTR_BL_CSTART ) = RET_INSTR;

/*
 * in cstart() (0xff010ff4) make these changes:
 * calls bzero(), then loads bs_end and calls
 * create_init_task
 */
// Reserve memory after the BSS for our application
INSTR( HIJACK_INSTR_BSS_END ) = (uintptr_t) _bss_end;

// Fix the calls to bzero32() and create_init_task()
FIXUP_BRANCH( HIJACK_FIXBR_BZERO32, bzero32 );
FIXUP_BRANCH( HIJACK_FIXBR_CREATE_ITASK, create_init_task );

// Set our init task to run instead of the firmware one
INSTR( HIJACK_INSTR_MY_ITASK ) = (uint32_t) my_init_task;
8010C4                 MOV     R0, #0
8010C8
8010C8 loc_8010C8                    
8010C8                 MOV     R1, R0,LSL#30
8010CC                 MOV     R3, #0
8010D0
8010D0 loc_8010D0                    
8010D0                 ORR     R2, R1, R3
8010D4                 MCR     p15, 0, R2,c7,c14, 2
8010D8                 ADD     R3, R3, #0x20
8010DC                 CMP     R3, #0x400
8010E0                 BNE     loc_8010D0
8010E4                 ADD     R0, R0, #1
8010E8                 CMP     R0, #4
8010EC                 BNE     loc_8010C8
8010F0                 SUB     R3, R3, #0x400
static inline void
clean_d_cache( void )
{
        uint32_t segment = 0;
        do {
                uint32_t line = 0;
                for( ; line != 0x400 ; line += 0x20 )
                {
                        asm(
                                "mcr p15, 0, %0, c7, c14, 2"
                                : : "r"( line | segment )
                        );
                }
        } while( segment += 0x40000000 );
}
8010F4                 MOV     R3, #0
8010F8                 MCR     p15, 0, R3,c7,c5
8010FC                 MOV     R3, #0
801100                 MCR     p15, 0, R3,c7,c6
801104                 MCR     p15, 0, R3,c7,c10, 4
static inline void
flush_caches( void )
{
        uint32_t reg = 0;
        asm(
                "mov %0, #0\n"
                "mcr p15, 0, %0, c7, c5, 0\n" // entire I cache
                "mov %0, #0\n"
                "mcr p15, 0, %0, c7, c6, 0\n" // entire D cache
                "mcr p15, 0, %0, c7, c10, 4\n" // drain write buffer
                : : "r"(reg)
        );
}
00801108                 LDR     R3, =0xB7F0C
0080110C                 MOV     LR, PC
00801110                 BX      R3
// We enter after the signature, avoiding the
// relocation jump that is at the head of the data
thunk reloc_entry = (thunk)( RELOCADDR + 0xC );
reloc_entry();
00801114                 LDR     R2, =0x8B168
00801118                 LDR     R3, =0x193C
0080111C                 STR     R2, [R3]
// Install our task creation hooks
task_dispatch_hook = my_task_dispatch_hook;
801120                 LDR     R2, =0xFF011028
801124                 LDR     R3, =0x10A7F00
801128                 ADD     R3, R2, R3
80112C                 MOV     LR, PC
801130                 BX      R3
801134
801134 loc_801134             
801134                 B       loc_801134
void (*ram_cstart)(void) = (void*) &INSTR( cstart );
ram_cstart();

// Unreachable
while(1)
82E000                 EXPORT blob_end
82E000 blob_end

reboot.c

    ".align 12\n"
        "blob_end:\n"
        ".globl blob_end\n"
);
82E000                 MOV     R0, PC        
82E000                           ; find_offset
82E004                 LDR     R3, =loc_82E008
82E008
82E008 loc_82E008                            
82E008                                       
82E008                 RSB     R0, R3, R0
82E00C                 BX      LR
static int
__attribute__((noinline))
find_offset( void )
{
        uintptr_t pc;
        asm __volatile__ (
                "mov %0, %%pc"
                : "=&r"(pc)
        );

        return pc - 8 - (uintptr_t) find_offset;
}
82E014                 EXPORT cstart
82E014 cstart                              
82E014                 BL      blob_end
82E018                 LDR     R4, =blob_start
82E01C                 LDR     LR, =blob_end
82E020                 RSB     LR, R4, LR
82E024                 MOVS    LR, LR,ASR#2
82E028                 ADD     R4, R4, R0
82E02C                 BEQ     loc_82E054
82E030                 MOV     R3, #0
82E034                 MOV     R2, R3
82E038
82E038 loc_82E038                    
82E038                 LDR     R12, [R4,R3]
82E03C                 ADD     R2, R2, #1
82E040                 ADD     R1, R3, #0x8B000
82E044                 CMP     LR, R2
82E048                 STR     R12, [R1]
82E04C                 ADD     R3, R3, #4
82E050                 BHI     loc_82E038
void
__attribute__((noreturn))
cstart( void )
{

        ssize_t offset = find_offset();

        blob_memcpy(
                (void*) RESTARTSTART,
                &blob_start + offset,
                &blob_end + offset
        );
82E054 loc_82E054
82E054                 MOV     R12, #0
82E058
82E058 loc_82E058           
82E058                 MOV     R1, R12,LSL#30
82E05C                 MOV     R3, #0
82E060
82E060 loc_82E060                    
82E060                 ORR     R2, R3, R1
82E064                 MCR     p15, 0, R2,c7,c14, 2
82E068                 ADD     R3, R3, #0x20
82E06C                 CMP     R3, #0x400
82E070                 BNE     loc_82E060
82E074                 ADD     R12, R12, #1
82E078                 CMP     R12, #4
82E07C                 BNE     loc_82E058
82E080                 MOV     R3, #0

82E084                 MOV     R3, #0
82E088                 MCR     p15, 0, R3,c7,c5
82E08C                 MOV     R3, #0
82E090                 MCR     p15, 0, R3,c7,c6
82E094                 MCR     p15, 0, R3,c7,c10, 4
        clean_d_cache();
        flush_caches();
82E098                 MOV     R3, #0x8B000
82E09C                 MOV     LR, PC
82E0A0                 BX      R3
// Jump into the newly relocated code
        void __attribute__((noreturn))(*copy_and_restart)(int)
                = (void*) RESTARTSTART;

        void __attribute__((noreturn))(*firmware_start)(void)
                = (void*) ROMBASEADDR;

        if( 1 )
                copy_and_restart(offset);
        else
                firmware_start();

        // Unreachable
        while(1)
Advertisement