Fandom

Magic Lantern Firmware Wiki

Autoexec

328pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

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)

Also on Fandom

Random Wiki