char code_file[] = PATH_BITS "/chain.bin";
uint8_t* bootstrap = (uint8_t*)0x24F00000;
- uint32_t size = 0;
+ uint32_t size = 0, b_size = 0;
uint8_t* chain_data;
FILE* f = fopen(code_file, "r");
abort("Missing chainloader.\n");
}
- size = fsize(f);
- fread(bootstrap, 1, size, f);
+ b_size = fsize(f);
+ fread(bootstrap, 1, b_size, f);
fclose(f);
- chain_data = bootstrap + size;
+ chain_data = bootstrap + b_size;
f = fopen(chain_file, "r");
if (!f) {
fread(chain_data, 1, size, f);
fclose(f);
+ fprintf(stderr, "Setting argc, argv...\n");
+
+ size = size - (size % 4) + 4;
+
+ uint32_t* off = (uint32_t*) &chain_data[size];
+
+ off[0] = (uint32_t)off + 4; // char**
+ off[1] = (uint32_t)off + 8; // char*
+
+ char* arg0 = (char*)&off[1];
+ memcpy(arg0, chain_file, strlen(chain_file) + 1);
+
+ uint32_t* argc_off = (uint32_t*)memfind(bootstrap, b_size, "ARGC", 4);
+ uint32_t* argv_off = (uint32_t*)memfind(bootstrap, b_size, "ARGV", 4);
+
+ argc_off[0] = 1;
+ argv_off[0] = (uint32_t)off;
+
fprintf(stderr, "Chaining to copy payload...\n");
- ((void(*)())0x24F00000)(chain_data, size);
+ ((void(*)(void*, uint32_t))0x24F00000)(chain_data, size + 256 + 8); // Size of payload + argv.
}
// This function is based on PathDeleteWorker from GodMode9.
.align 4
.global _start
_start:
+ ldr r2, =argc
+ str r0, [r2]
+
+ ldr r2, =argv
+ str r1, [r2]
+
b mpu
- nop
+argc: .int 0x00000000
+argv: .int 0x00000000
+
mpu:
- @ Change the stack pointer
+ // Change the stack pointer
mov sp, #0x27000000
- @ Disable caches / mpu
- mrc p15, 0, r4, c1, c0, 0 @ read control register
- bic r4, #(1<<12) @ - instruction cache disable
- bic r4, #(1<<2) @ - data cache disable
- bic r4, #(1<<0) @ - mpu disable
- mcr p15, 0, r4, c1, c0, 0 @ write control register
+ // Disable caches / mpu
+ mrc p15, 0, r4, c1, c0, 0 // read control register
+ bic r4, #(1<<12) // - instruction cache disable
+ bic r4, #(1<<2) // - data cache disable
+ bic r4, #(1<<0) // - mpu disable
+ mcr p15, 0, r4, c1, c0, 0 // write control register
- @ Give read/write access to all the memory regions
+ // Give read/write access to all the memory regions
ldr r5, =0x33333333
- mcr p15, 0, r5, c5, c0, 2 @ write data access
- mcr p15, 0, r5, c5, c0, 3 @ write instruction access
+ mcr p15, 0, r5, c5, c0, 2 // write data access
+ mcr p15, 0, r5, c5, c0, 3 // write instruction access
- @ Sets MPU permissions and cache settings
- ldr r0, =0xFFFF001D @ ffff0000 32k
- ldr r1, =0x01FF801D @ 01ff8000 32k
- ldr r2, =0x08000027 @ 08000000 1M
- ldr r3, =0x10000021 @ 10000000 128k
- ldr r4, =0x10100025 @ 10100000 512k
- ldr r5, =0x20000035 @ 20000000 128M
- ldr r6, =0x1FF00027 @ 1FF00000 1M
- ldr r7, =0x1800002D @ 18000000 8M
+ // Sets MPU permissions and cache settings
+ ldr r0, =0xFFFF001D // ffff0000 32k
+ ldr r1, =0x01FF801D // 01ff8000 32k
+ ldr r2, =0x08000027 // 08000000 1M
+ ldr r3, =0x10000021 // 10000000 128k
+ ldr r4, =0x10100025 // 10100000 512k
+ ldr r5, =0x20000035 // 20000000 128M
+ ldr r6, =0x1FF00027 // 1FF00000 1M
+ ldr r7, =0x1800002D // 18000000 8M
mov r10, #0x25
mov r11, #0x25
mov r12, #0x25
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
- mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5
- mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5
- mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5
+ mcr p15, 0, r10, c3, c0, 0 // Write bufferable 0, 2, 5
+ mcr p15, 0, r11, c2, c0, 0 // Data cacheable 0, 2, 5
+ mcr p15, 0, r12, c2, c0, 1 // Inst cacheable 0, 2, 5
- @ Enable caches
- mrc p15, 0, r4, c1, c0, 0 @ read control register
- orr r4, r4, #(1<<18) @ - itcm enable
- orr r4, r4, #(1<<12) @ - instruction cache enable
- orr r4, r4, #(1<<2) @ - data cache enable
- orr r4, r4, #(1<<0) @ - mpu enable
- mcr p15, 0, r4, c1, c0, 0 @ write control register
+ // Enable caches
+ mrc p15, 0, r4, c1, c0, 0 // read control register
+ orr r4, r4, #(1<<18) // - itcm enable
+ orr r4, r4, #(1<<12) // - instruction cache enable
+ orr r4, r4, #(1<<2) // - data cache enable
+ orr r4, r4, #(1<<0) // - mpu enable
+ mcr p15, 0, r4, c1, c0, 0 // write control register
- @ Flush caches
+ // Flush caches
mov r5, #0
- mcr p15, 0, r5, c7, c5, 0 @ flush I-cache
- mcr p15, 0, r5, c7, c6, 0 @ flush D-cache
- mcr p15, 0, r5, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r5, c7, c5, 0 // flush I-cache
+ mcr p15, 0, r5, c7, c6, 0 // flush D-cache
+ mcr p15, 0, r5, c7, c10, 4 // drain write buffer
- @ Fixes mounting of SDMC
+ // Fixes mounting of SDMC
ldr r0, =0x10000020
mov r1, #0x340
str r1, [r0]
+ ldr r0, argc
+ ldr r1, argv
+
bl main
.die: