Skip to content

Commit

Permalink
Fix more shit
Browse files Browse the repository at this point in the history
  • Loading branch information
Siguza committed Feb 18, 2022
1 parent 96becaa commit 3b29026
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 7 deletions.
34 changes: 33 additions & 1 deletion src/boot/clearhook.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,39 @@
.globl _clear_hook_end
.globl _clear_hook_orig_backing


.align 4
// This must not exceed 0x60 bytes (24 instructions), otherwise we start overwriting iBoot data.
_clear_hook:
// counterpart to the bl we emitted
mov x16, x30
// counterpart to the "mov x5, x30" we emitted
mov x30, x5

add x2, x1, x0
mov x3, 0x800000000
movk x3, 0x1800, lsl 16
add x4, x3, 0xfff, lsl 12
cmp x2, x3
b.ls _clear_hook_orig_backing
cmp x0, x4
b.hs _clear_hook_orig_backing
// Let bzero handle the chunk before our region
subs x1, x3, x0
csel x1, xzr, x1, lt
L_clear_hook_zeroloop:
// Zero the part after it ourselves
cmp x4, x2
b.hs _clear_hook_orig_backing
strb wzr, [x4], 1
b L_clear_hook_zeroloop

_clear_hook_orig_backing:
nop
nop
br x16
_clear_hook_end:

#if 0
_clear_hook:
mov x16, x30
mov x30, x5
Expand All @@ -53,3 +84,4 @@ nop
nop
br x16
_clear_hook_end:
#endif
19 changes: 13 additions & 6 deletions src/boot/stage3.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,28 @@ uint32_t* find_prev_insn(uint32_t* from, uint32_t size, uint32_t insn, uint32_t
}

extern uint32_t clear_hook_orig_backing[2];
extern uint8_t clear_hook, clear_hook_end;
extern uint32_t clear_hook[], clear_hook_end[];

void patch_bootloader(void* boot_image)
{
// 1. disable DRAM clear

uint32_t* sys_3_c7_c4_1 = find_next_insn(boot_image, 0x80000, 0xd50b7423, 0xFFFFFFFF);
if (sys_3_c7_c4_1) {
uint32_t* func_prolog = find_prev_insn(sys_3_c7_c4_1, 0x100, 0xaa0103e2, 0xffffffff);
uint32_t* dc_zva = find_next_insn(boot_image, 0x80000, 0xd50b7423, 0xFFFFFFFF);
if (dc_zva) {
uint32_t* func_prolog = find_prev_insn(dc_zva, 0x100, 0xaa0103e2, 0xffffffff);
if (func_prolog) {
for (int i = 0; i < 2; i++) {
clear_hook_orig_backing[i] = func_prolog[i];
}
memcpy(((void*)0x180 + (uint64_t)boot_image), &clear_hook, &clear_hook_end - &clear_hook);
int64_t offset = (0x180 + (int64_t)boot_image) - (4 + (int64_t)func_prolog);
size_t hooksz = (clear_hook_end - clear_hook) * sizeof(uint32_t);
// TODO: _Static_assert(hooksz <= 0x60, "Clearhook exceeds max size");
// NOTE: memcpy breaks here because we run with MMU off
volatile uint32_t *from = clear_hook, *to = (uint32_t*)((uintptr_t)boot_image + 0x300 - hooksz);
for(size_t i = 0; i < hooksz / sizeof(uint32_t); ++i)
{
to[i] = from[i];
}
int64_t offset = (int64_t)((uintptr_t)boot_image + 0x300 - hooksz) - (int64_t)((uintptr_t)func_prolog + 4);
func_prolog[0] = 0xaa1e03e5;
func_prolog[1] = 0x94000000 | ((((uint64_t)offset) >> 2) & 0x3FFFFFF);
}
Expand Down

0 comments on commit 3b29026

Please sign in to comment.