예제 #1
0
파일: firm.c 프로젝트: Taktloss/rxTools
int rxMode(int emu)
{
	wchar_t path[64];
	const char *shstrtab;
	const wchar_t *msg;
	uint8_t keyx[16];
	uint32_t tid;
	int r, sector;
	Elf32_Ehdr *ehdr;
	Elf32_Shdr *shdr, *btm;
	void *keyxArg;
	FIL fd;
	UINT br, fsz;

	if (emu) {
		sector = checkEmuNAND();
		if (sector == 0) {
			ConsoleInit();
			ConsoleSetTitle(L"EMUNAND NOT FOUND!");
			print(L"The emunand was not found on\n");
			print(L"your SDCard. \n");
			print(L"\n");
			print(L"Press A to boot SYSNAND\n");
			ConsoleShow();

			WaitForButton(BUTTON_A);

			swprintf(path, _MAX_LFN, L"/rxTools/Theme/%u/boot.bin",
				cfgs[CFG_THEME].val.i);
			DrawBottomSplash(path);
		}
	} else
		sector = 0;

	r = getMpInfo();
	switch (r) {
		case MPINFO_KTR:
			tid = TID_KTR_NATIVE_FIRM;
			break;

		case MPINFO_CTR:
			tid = TID_CTR_NATIVE_FIRM;
			break;

		default:
			msg = L"Unknown Platform: %d";
			goto fail;
	}

	setAgbBios();

	if (sysver < 7 && f_open(&fd, _T("slot0x25KeyX.bin"), FA_READ) == FR_OK) {
		f_read(&fd, keyx, sizeof(keyx), &br);
		f_close(&fd);
		keyxArg = keyx;
	} else
		keyxArg = NULL;

	getFirmPath(path, tid);
	r = loadFirm(path, &fsz);
	if (r) {
		msg = L"Failed to load NATIVE_FIRM: %d\n"
			L"Reboot rxTools and try again.\n";
		goto fail;
	}

	((FirmHdr *)FIRM_ADDR)->arm9Entry = 0x0801B01C;

	getFirmPatchPath(path, tid);
	r = f_open(&fd, path, FA_READ);
	if (r != FR_OK)
		goto patchFail;

	r = f_read(&fd, (void *)PATCH_ADDR, PATCH_SIZE, &br);
	if (r != FR_OK)
		goto patchFail;

	f_close(&fd);

	ehdr = (void *)PATCH_ADDR;
	shdr = (void *)(PATCH_ADDR + ehdr->e_shoff);
	shstrtab = (char *)PATCH_ADDR + shdr[ehdr->e_shstrndx].sh_offset;
	for (btm = shdr + ehdr->e_shnum; shdr != btm; shdr++) {
		if (!strcmp(shstrtab + shdr->sh_name, ".patch.p9.reboot.body")) {
			execReboot(sector, keyxArg, ehdr->e_entry, shdr);
			__builtin_unreachable();
		}
	}

	msg = L".patch.p9.reboot.body not found\n"
		L"Please check your installation.\n";
fail:
	ConsoleInit();
	ConsoleSetTitle(L"rxMode");
	print(msg, r);
	print(L"\n");
	print(strings[STR_PRESS_BUTTON_ACTION],
		strings[STR_BUTTON_A], strings[STR_CONTINUE]);
	ConsoleShow();
	WaitForButton(BUTTON_A);

	return r;

patchFail:
	msg = L"Failed to load the patch: %d\n"
		L"Check your installation.\n";
	goto fail;
}
예제 #2
0
파일: firm.c 프로젝트: 173210/rxTools
int rxMode(int emu)
{
    const Elf32_Addr line = 32;
    wchar_t path[64];
    const char *shstrtab;
    const wchar_t *msg;
    uint8_t keyx[16];
    uint32_t tid;
    int r, sector;
    Elf32_Ehdr *ehdr;
    Elf32_Shdr *shdr, *btmShdr;
    Elf32_Addr cur, btm;
    void *keyxArg;
    FIL fd;
    UINT br, fsz;

    if (emu) {
        sector = checkEmuNAND();
        if (sector == 0) {
            ConsoleInit();
            ConsoleSetTitle(L"EMUNAND NOT FOUND!");
            print(L"The emunand was not found on\n");
            print(L"your SDCard. \n");
            print(L"\n");
            print(L"Press A to boot SYSNAND\n");
            ConsoleShow();

            WaitForButton(BUTTON_A);

            swprintf(path, _MAX_LFN, L"/rxTools/Theme/%u/boot.bin",
                     cfgs[CFG_THEME].val.i);
            DrawBottomSplash(path);
        }
    } else
        sector = 0;

    r = getMpInfo();
    switch (r) {
    case MPINFO_KTR:
        tid = TID_KTR_NATIVE_FIRM;
        break;

    case MPINFO_CTR:
        tid = TID_CTR_NATIVE_FIRM;
        break;

    default:
        msg = L"Unknown Platform: %d";
        goto fail;
    }

    setAgbBios();

    if (sysver < 7 && f_open(&fd, _T("slot0x25KeyX.bin"), FA_READ) == FR_OK) {
        f_read(&fd, keyx, sizeof(keyx), &br);
        f_close(&fd);
        keyxArg = keyx;
    } else
        keyxArg = NULL;

    getFirmPath(path, tid);
    r = loadFirm(path, &fsz);
    if (r) {
        msg = L"Failed to load NATIVE_FIRM: %d\n"
              L"Reboot rxTools and try again.\n";
        goto fail;
    }

    ((FirmHdr *)FIRM_ADDR)->arm9Entry = 0x0801B01C;

    getFirmPatchPath(path, tid);
    r = f_open(&fd, path, FA_READ);
    if (r != FR_OK)
        goto patchFail;

    r = f_read(&fd, (void *)PATCH_ADDR, PATCH_SIZE, &br);
    if (r != FR_OK)
        goto patchFail;

    f_close(&fd);

    ehdr = (void *)PATCH_ADDR;
    shdr = (void *)(PATCH_ADDR + ehdr->e_shoff);
    shstrtab = (char *)PATCH_ADDR + shdr[ehdr->e_shstrndx].sh_offset;
    for (btmShdr = shdr + ehdr->e_shnum; shdr != btmShdr; shdr++) {
        if (!strcmp(shstrtab + shdr->sh_name, ".patch.p9.reboot.body")) {
            memcpy((void *)ehdr->e_entry,
                   (void *)(PATCH_ADDR + shdr->sh_offset),
                   shdr->sh_size);

            // Drain write buffer
            __asm__ volatile ("mcr p15, 0, %0, c7, c10, 4" :: "r"(0));

            cur = ehdr->e_entry & ~(line - 1);
            btm = ehdr->e_entry + shdr->sh_size;
            while (cur < btm) {
                __asm__ volatile (
                    // Clean Dcache
                    "mcr p15, 0, %0, c7, c10, 1\n\t"

                    // Flush Icache
                    "mcr p15, 0, %0, c7, c5, 1"
                    :: "r"(cur));

                cur += line;
            }

            ((void (*)(uint32_t, void *, uintptr_t))ehdr->e_entry)(
                sector, keyxArg, 0x1FFFFFF8);

            __builtin_unreachable();
        }
    }