mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
・FS rom archive 利用不可 (実質メモリブートなので) ・srlファイルはwriterのMakefileで指定すること git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2665 b08762b0-b915-fc4b-9d8c-17b2551a87ff
501 lines
19 KiB
C
501 lines
19 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlFirm - nandfirm - sdmc-launcher
|
||
File: main.c
|
||
|
||
Copyright 2007 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Date:: $
|
||
$Rev$
|
||
$Author$
|
||
*---------------------------------------------------------------------------*/
|
||
#include <firm.h>
|
||
#include "font.h"
|
||
#include "screen.h"
|
||
|
||
#ifdef FIRM_USE_PRODUCT_KEYS
|
||
static const u8* const rsa_key_user = NULL; // not acceptable
|
||
static const u8* const rsa_key_sys = NULL; // not acceptable
|
||
static const u8 rsa_key_secure[128] =
|
||
{
|
||
0xC7, 0x94, 0x50, 0x00, 0x3A, 0xE1, 0x0E, 0x6C, 0xA8, 0xD1, 0xC0, 0x2D, 0x77, 0xB7, 0x6D, 0xBC,
|
||
0x31, 0xDB, 0x12, 0x08, 0x09, 0x0D, 0x2A, 0xE8, 0xC9, 0x1A, 0x2B, 0x6E, 0x6C, 0x85, 0x78, 0xD7,
|
||
0x46, 0x50, 0x05, 0xB5, 0xCC, 0x3B, 0xEC, 0xBA, 0xF4, 0xDE, 0xC2, 0x13, 0x13, 0xBE, 0x67, 0xEE,
|
||
0x85, 0x19, 0xEB, 0x62, 0xB3, 0x5C, 0x09, 0xA8, 0x54, 0x44, 0x26, 0x85, 0x25, 0xEA, 0xE5, 0x85,
|
||
0xD1, 0xB5, 0xCE, 0xA0, 0xFF, 0x6B, 0x61, 0xCA, 0x94, 0xC1, 0x67, 0xBE, 0xC0, 0x7E, 0x3B, 0xFF,
|
||
0x12, 0x9B, 0x79, 0xDB, 0xAC, 0xD3, 0x5A, 0x3F, 0x14, 0x37, 0x49, 0xA8, 0x7C, 0x2F, 0x07, 0xF4,
|
||
0x8B, 0xA9, 0x8B, 0x8D, 0xB2, 0x60, 0xA5, 0xD5, 0x64, 0xEE, 0xCF, 0x3F, 0x32, 0xEE, 0x77, 0xAC,
|
||
0x27, 0x75, 0x2B, 0x04, 0xD7, 0x26, 0xA8, 0x8A, 0x55, 0x2A, 0x76, 0xE5, 0x68, 0x80, 0x57, 0x85
|
||
};
|
||
#else
|
||
#if 0
|
||
static const u8 rsa_key_user[128] =
|
||
{
|
||
0xAC, 0x93, 0xBB,
|
||
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
|
||
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
|
||
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
|
||
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
|
||
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
|
||
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
|
||
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
|
||
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
|
||
};
|
||
#else
|
||
static const u8* const rsa_key_user = NULL; // not acceptable
|
||
#endif
|
||
static const u8 rsa_key_sys[128] =
|
||
{
|
||
0xe9, 0x9e, 0xa7, 0x9f, 0x59, 0x4d, 0xf4, 0xa7, 0x60, 0x04, 0xbd, 0x47, 0xf2, 0xb3, 0x64, 0xcd,
|
||
0x16, 0x79, 0xc1, 0x47, 0x39, 0xf6, 0xa9, 0xf8, 0xee, 0x1a, 0xd0, 0x72, 0xcf, 0x43, 0x97, 0x0c,
|
||
0x93, 0xa1, 0x38, 0x4e, 0x13, 0x40, 0x6c, 0x10, 0x59, 0x43, 0xe2, 0x71, 0x29, 0x54, 0x14, 0x2c,
|
||
0xc5, 0xda, 0x59, 0x4d, 0xb4, 0x6a, 0xef, 0x85, 0x61, 0x6f, 0x7f, 0x1c, 0x59, 0x34, 0x2c, 0xc6,
|
||
0x24, 0xf3, 0x7b, 0xc3, 0xb7, 0x40, 0xd1, 0x46, 0xf8, 0x90, 0xb7, 0xc2, 0x98, 0x50, 0xaf, 0x95,
|
||
0x52, 0x42, 0xdb, 0xac, 0xd6, 0x7e, 0xa9, 0xc3, 0x3d, 0x1b, 0x51, 0x56, 0x07, 0x06, 0xd0, 0x0b,
|
||
0x01, 0xbb, 0x58, 0x93, 0xea, 0xa0, 0x2c, 0xc7, 0x7d, 0x6a, 0x31, 0x7e, 0xc9, 0xe2, 0xda, 0xfe,
|
||
0x1f, 0x2e, 0x9d, 0xa7, 0x54, 0x84, 0xdc, 0x28, 0xb9, 0x18, 0xea, 0x16, 0xf2, 0x95, 0x55, 0x6d,
|
||
};
|
||
static const u8 rsa_key_secure[128] =
|
||
{
|
||
0xa7, 0x9f, 0x54, 0xa0, 0xc7, 0x45, 0xae, 0xf6, 0x63, 0xa7, 0x53, 0xb7, 0x0a, 0xcc, 0x0b, 0xcb,
|
||
0x65, 0xe1, 0x11, 0xc6, 0x05, 0x15, 0xb5, 0x6e, 0xbd, 0xac, 0x0c, 0xca, 0xf4, 0x7c, 0x68, 0x7a,
|
||
0xf9, 0x0e, 0x5d, 0x98, 0x5b, 0xc8, 0x4d, 0x22, 0x3b, 0xa3, 0xbe, 0x8b, 0x5b, 0x7f, 0x26, 0x44,
|
||
0x9f, 0xc4, 0x48, 0x44, 0xb1, 0x32, 0xb7, 0xbe, 0x63, 0xba, 0xd6, 0xc1, 0x10, 0xce, 0xf6, 0xed,
|
||
0x47, 0x8f, 0xe1, 0xff, 0x7f, 0x5a, 0xd5, 0x5d, 0x94, 0x38, 0x2f, 0xa1, 0xd4, 0xef, 0x82, 0xb1,
|
||
0x0d, 0xc4, 0x43, 0xec, 0xbe, 0x77, 0xb6, 0x82, 0x9c, 0xfa, 0x17, 0x87, 0x84, 0x82, 0x25, 0x46,
|
||
0xfb, 0xd6, 0x05, 0xc8, 0x9a, 0x7e, 0xad, 0x44, 0x40, 0x0d, 0x35, 0x9c, 0x45, 0x44, 0x64, 0x36,
|
||
0x61, 0x4b, 0xf7, 0xe6, 0x31, 0x5c, 0x7d, 0x96, 0x73, 0xe8, 0xac, 0xb4, 0xe3, 0x5e, 0xd1, 0x9d,
|
||
};
|
||
#endif
|
||
|
||
static SVCSignHeapContext acPool;
|
||
|
||
static const u8 defaultKey[ SVC_SHA1_BLOCK_SIZE ] =
|
||
{
|
||
0x21, 0x06, 0xc0, 0xde,
|
||
0xba, 0x98, 0xce, 0x3f,
|
||
0xa6, 0x92, 0xe3, 0x9d,
|
||
0x46, 0xf2, 0xed, 0x01,
|
||
|
||
0x76, 0xe3, 0xcc, 0x08,
|
||
0x56, 0x23, 0x63, 0xfa,
|
||
0xca, 0xd4, 0xec, 0xdf,
|
||
0x9a, 0x62, 0x78, 0x34,
|
||
|
||
0x8f, 0x6d, 0x63, 0x3c,
|
||
0xfe, 0x22, 0xca, 0x92,
|
||
0x20, 0x88, 0x97, 0x23,
|
||
0xd2, 0xcf, 0xae, 0xc2,
|
||
|
||
0x32, 0x67, 0x8d, 0xfe,
|
||
0xca, 0x83, 0x64, 0x98,
|
||
0xac, 0xfd, 0x3e, 0x37,
|
||
0x87, 0x46, 0x58, 0x24,
|
||
};
|
||
|
||
|
||
/*
|
||
PRINT_MEMORY_ADDR <20><><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>ƁA<C681><41><EFBFBD>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD>SPrintf<74><66><EFBFBD>s<EFBFBD><73><EFBFBD>܂<EFBFBD>(<28><><EFBFBD>̃t<CC83>@<40>C<EFBFBD><43><EFBFBD>̂<EFBFBD>)
|
||
FINALROM<4F>łł<C582><C582>R<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>c<EFBFBD><63><EFBFBD>̂Œ<CC82><C592>ӂ<EFBFBD><D382>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
|
||
*/
|
||
//#define PRINT_MEMORY_ADDR 0x02FFC000
|
||
|
||
#ifdef PRINT_MEMORY_ADDR
|
||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||
#undef OS_TPrintf
|
||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||
#endif
|
||
|
||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||
|
||
/***************************************************************
|
||
PreInit
|
||
|
||
FromBoot<6F>̑Ή<CC91><CE89><EFBFBD>OS_Init<69>O<EFBFBD>ɕK<C995>v<EFBFBD>ȃ<EFBFBD><C883>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
|
||
***************************************************************/
|
||
static void PreInit(void)
|
||
{
|
||
/*
|
||
<20><><EFBFBD>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֘A
|
||
*/
|
||
// SHARED<45>̈<EFBFBD><CC88>N<EFBFBD><4E><EFBFBD>A
|
||
MI_CpuClearFast((void *)HW_WRAM_EX_LOCK_BUF, (HW_WRAM_EX_LOCK_BUF_END - HW_WRAM_EX_LOCK_BUF));
|
||
MI_CpuClearFast((void *)HW_BIOS_EXCP_STACK_MAIN, (HW_REAL_TIME_CLOCK_BUF - HW_BIOS_EXCP_STACK_MAIN));
|
||
MI_CpuClearFast((void *)HW_PXI_SIGNAL_PARAM_ARM9, (HW_MMEMCHECKER_MAIN - HW_PXI_SIGNAL_PARAM_ARM9));
|
||
// MI_CpuClearFast((void*)HW_ROM_HEADER_BUF, (HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF));
|
||
|
||
/*
|
||
FromBrom<6F>֘A
|
||
*/
|
||
if ( !OSi_FromBromToMenu() )
|
||
{
|
||
OS_Terminate();
|
||
}
|
||
|
||
// <20>u<EFBFBD>[<5B>g<EFBFBD>^<5E>C<EFBFBD>v<EFBFBD>̕ύX
|
||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||
}
|
||
|
||
/***************************************************************
|
||
PostInit
|
||
|
||
<20>e<EFBFBD>평<EFBFBD><ED8F89><EFBFBD><EFBFBD>
|
||
***************************************************************/
|
||
static void PostInit(void)
|
||
{
|
||
// <20>A<EFBFBD><41><EFBFBD>[<5B>i<EFBFBD>ݒ<EFBFBD>
|
||
{
|
||
static u32 arena[ 0x400 / sizeof(u32) ];
|
||
OS_SetMainArenaLo( arena );
|
||
OS_SetMainArenaHi( &arena[ 0x400 / sizeof(u32) ] );
|
||
}
|
||
// RSA<53>p<EFBFBD>q<EFBFBD>[<5B>v<EFBFBD>ݒ<EFBFBD>
|
||
SVC_InitSignHeap( &acPool, (void*)HW_FIRM_RSA_BUF, HW_FIRM_RSA_BUF_SIZE );
|
||
}
|
||
|
||
/***************************************************************
|
||
CheckHeader
|
||
|
||
<20>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD>V<EFBFBD>X<EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD>j<EFBFBD><6A><EFBFBD>[<5B>Ƃ<EFBFBD><C682>Ė<EFBFBD><C496><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
|
||
***************************************************************/
|
||
static BOOL CheckHeader(void)
|
||
{
|
||
ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
|
||
// <20>C<EFBFBD>j<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>[<5B>h<EFBFBD>Ȃ<EFBFBD>
|
||
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
|
||
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
|
||
OS_TPrintf("Codec Mode : %s\n", rhs->exFlags.codec_mode ? "TWL" : "NITRO");
|
||
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
|
||
OS_TPrintf("AES Encryption : %s\n", rhs->enable_aes ? "AVAILABLE" : "NOT AVAILABLE");
|
||
if ( rhs->enable_aes )
|
||
{
|
||
OS_TPrintf("AES Key Type : %s\n", ( rhs->developer_encrypt_old || rhs->exFlags.developer_encrypt ) ? "FOR DEVELOPMENT" : "FOR PRODUCT");
|
||
}
|
||
// <20>G<EFBFBD><47><EFBFBD>g<EFBFBD><67><EFBFBD>|<7C>C<EFBFBD><43><EFBFBD>g
|
||
OS_TPrintf("ARM9 Entry point : %08X\n", rhs->main_entry_address);
|
||
OS_TPrintf("ARM7 Entry point : %08X\n", rhs->sub_entry_address);
|
||
// <20><><EFBFBD>[<5B>h<EFBFBD>͈<EFBFBD>
|
||
OS_TPrintf("ARM9 ROM address : %08X\n", rhs->main_rom_offset);
|
||
OS_TPrintf("ARM9 RAM address : %08X\n", rhs->main_ram_address);
|
||
OS_TPrintf("ARM9 size : %08X\n", rhs->main_size);
|
||
OS_TPrintf("ARM7 ROM address : %08X\n", rhs->sub_rom_offset);
|
||
OS_TPrintf("ARM7 RAM address : %08X\n", rhs->sub_ram_address);
|
||
OS_TPrintf("ARM7 size : %08X\n", rhs->sub_size);
|
||
OS_TPrintf("ARM9 LTD ROM address: %08X\n", rhs->main_ltd_rom_offset);
|
||
OS_TPrintf("ARM9 LTD RAM address: %08X\n", rhs->main_ltd_ram_address);
|
||
OS_TPrintf("ARM9 LTD size : %08X\n", rhs->main_ltd_size);
|
||
OS_TPrintf("ARM7 LTD ROM address: %08X\n", rhs->sub_ltd_rom_offset);
|
||
OS_TPrintf("ARM7 LTD RAM address: %08X\n", rhs->sub_ltd_ram_address);
|
||
OS_TPrintf("ARM7 LTD size : %08X\n", rhs->sub_ltd_size);
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>قڍœK<C593><4B><EFBFBD>ς<EFBFBD>
|
||
#ifdef FIRM_USE_PRODUCT_KEYS
|
||
if ( rhs->platform_code != PLATFORM_CODE_TWL_LIMITED || // TWL Limited only
|
||
!rhs->enable_signature || // Should be use ROM header signature
|
||
#else
|
||
if ( // no check
|
||
#endif
|
||
!rhs->exFlags.codec_mode || // TWL mode only
|
||
// should be in main memory
|
||
HW_TWL_MAIN_MEM > (u32)rhs->main_ram_address ||
|
||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ram_address ||
|
||
HW_TWL_MAIN_MEM > (u32)rhs->main_ltd_ram_address ||
|
||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ltd_ram_address ||
|
||
// should be in static area without Limited region
|
||
(u32)rhs->main_ram_address > (u32)rhs->main_entry_address ||
|
||
(u32)rhs->sub_ram_address > (u32)rhs->sub_entry_address ||
|
||
// should be in main memory (end address)
|
||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->main_ram_address + rhs->main_size ||
|
||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->sub_ram_address + rhs->sub_size ||
|
||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->main_ltd_ram_address + rhs->main_ltd_size ||
|
||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->sub_ltd_ram_address + rhs->sub_ltd_size ||
|
||
// should be in static area without Limited region (end address)
|
||
(u32)rhs->main_ram_address + rhs->main_size <= (u32)rhs->main_entry_address ||
|
||
(u32)rhs->sub_ram_address + rhs->sub_size <= (u32)rhs->sub_entry_address ||
|
||
0 )
|
||
{
|
||
OS_TPrintf("Invalid ROM header for SDMC Launcher!\n");
|
||
return FALSE;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
/***************************************************************
|
||
EraseAll
|
||
|
||
<20>s<EFBFBD><73><EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
|
||
<20><><EFBFBD>낢<EFBFBD><EB82A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
DS<44><53><EFBFBD>[<5B>h<EFBFBD>ɂ<EFBFBD><C982>ďI<C48F><49><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD><CC82>悢<EFBFBD><E682A2><EFBFBD>H
|
||
***************************************************************/
|
||
static void EraseAll(void)
|
||
{
|
||
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
|
||
#ifdef SDK_FINALROM
|
||
MI_CpuClearFast( (void*)HW_TWL_ROM_HEADER_BUF, HW_TWL_ROM_HEADER_BUF_SIZE );
|
||
MI_CpuClearFast( (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||
OS_BootFromFIRM();
|
||
#endif
|
||
}
|
||
|
||
static inline BOOL CheckDigest( u8* a, u8* b, BOOL aClr, BOOL bClr )
|
||
{
|
||
BOOL result = TRUE;
|
||
int i;
|
||
for ( i = 0; i < SVC_SHA1_DIGEST_SIZE; i++ )
|
||
{
|
||
if ( a[i] != b[i] )
|
||
{
|
||
result = FALSE;
|
||
}
|
||
}
|
||
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_DIGEST_SIZE);
|
||
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_DIGEST_SIZE);
|
||
return result;
|
||
}
|
||
|
||
static void myInit(void);
|
||
static void myVBlankIntr(void);
|
||
|
||
void TwlMain( void )
|
||
{
|
||
#define X_OFF 2
|
||
s16 y = 2;
|
||
|
||
PreInit();
|
||
myInit();
|
||
PostInit();
|
||
|
||
//---- clear screen buffer
|
||
ClearScreen();
|
||
PrintString( X_OFF, y, FONT_CYAAN, "Mem Launcher (N)" );
|
||
PrintString( X_OFF+18, y++, FONT_YELLOW, "%s", __DATE__ );
|
||
PrintString( X_OFF+21, y++, FONT_YELLOW, "%s", __TIME__ );
|
||
OS_WaitVBlankIntr();
|
||
y++;
|
||
|
||
PrintString( X_OFF, y++, FONT_WHITE, "Initialized." );
|
||
y++;
|
||
|
||
PrintString( X_OFF, y++, FONT_WHITE, "Checking header..." );
|
||
OS_WaitVBlankIntr();
|
||
|
||
/*
|
||
<20>w<EFBFBD>b<EFBFBD>_<EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N (<28>Ĕz<C494>u<EFBFBD>t<EFBFBD><74>)
|
||
*/
|
||
MI_CpuCopyFast( (void*)HW_TWL_MAIN_MEM, rh, HW_TWL_ROM_HEADER_BUF_SIZE );
|
||
DC_StoreRange( rh, HW_TWL_ROM_HEADER_BUF_SIZE );
|
||
|
||
#define HEADER_AUTH_SIZE 0xe00
|
||
{
|
||
const void* rsa_key;
|
||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||
SignatureData sd;
|
||
|
||
// <20>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>v<EFBFBD>Z
|
||
SVC_CalcSHA1( md, rh, HEADER_AUTH_SIZE );
|
||
// <20><><EFBFBD>̊m<CC8A><6D>
|
||
rsa_key = (rh->s.titleID_Hi & TITLE_ID_HI_SECURE_FLAG_MASK)
|
||
? rsa_key_secure
|
||
: ( (rh->s.titleID_Hi & TITLE_ID_HI_APP_TYPE_MASK) ? rsa_key_sys : rsa_key_user );
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̕<EFBFBD><CC95><EFBFBD><EFBFBD><EFBFBD>
|
||
SVC_DecryptSign( &acPool, &sd, rh->signature, rsa_key );
|
||
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
|
||
{
|
||
MI_CpuClear8( &sd, sizeof(sd) ); // <20>c<EFBFBD><63><EFBFBD>폜 (<28><><EFBFBD>ɕK<C995>v<EFBFBD>Ȃ<EFBFBD><C882>̂͂Ȃ<CD82><C882>H)
|
||
OS_TPrintf("Failed to call FS_LoadHeader().\n");
|
||
goto end;
|
||
}
|
||
MI_CpuClear8( &sd, sizeof(sd) ); // <20>c<EFBFBD><63><EFBFBD>폜 (<28><><EFBFBD>ɕK<C995>v<EFBFBD>Ȃ<EFBFBD><C882>̂͂Ȃ<CD82><C882>H)
|
||
// ROM<4F>w<EFBFBD>b<EFBFBD>_<EFBFBD>̃R<CC83>s<EFBFBD>[
|
||
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||
}
|
||
if ( !CheckHeader() )
|
||
{
|
||
OS_TPrintf("Failed to call CheckHeader().\n");
|
||
goto end;
|
||
}
|
||
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
|
||
DC_FlushAll();
|
||
// 8: after to load header
|
||
PXI_NotifyID( FIRM_PXI_ID_DONE_HEADER );
|
||
|
||
/*
|
||
Static<69>Ĕz<C494>u<EFBFBD>҂<EFBFBD>
|
||
*/
|
||
PrintString( X_OFF, y++, FONT_WHITE, "Replacing static data..." );
|
||
OS_WaitVBlankIntr();
|
||
|
||
if ( PXI_RecvID() != FIRM_PXI_ID_NULL )
|
||
{
|
||
OS_TPrintf("Failed to decrypt static data.\n");
|
||
goto end;
|
||
}
|
||
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
|
||
|
||
// 7: after PXI
|
||
PrintString( X_OFF, y++, FONT_WHITE, "Checking static data..." );
|
||
OS_WaitVBlankIntr();
|
||
/*
|
||
Static<69>`<60>F<EFBFBD>b<EFBFBD>N
|
||
*/
|
||
{
|
||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||
if ( rh->s.main_size > 0 )
|
||
{
|
||
SVC_CalcHMACSHA1( md, rh->s.main_ram_address, rh->s.main_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
|
||
if ( !CheckDigest( md, rh->s.main_static_digest, TRUE, FALSE ) )
|
||
{
|
||
OS_TPrintf("Failed to check main_static_digest.\n");
|
||
goto end;
|
||
}
|
||
}
|
||
if ( rh->s.sub_size > 0 )
|
||
{
|
||
SVC_CalcHMACSHA1( md, rh->s.sub_ram_address, rh->s.sub_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
|
||
if ( !CheckDigest( md, rh->s.sub_static_digest, TRUE, FALSE ) )
|
||
{
|
||
OS_TPrintf("Failed to check sub_static_digest.\n");
|
||
goto end;
|
||
}
|
||
}
|
||
if ( rh->s.main_ltd_size > 0 )
|
||
{
|
||
SVC_CalcHMACSHA1( md, rh->s.main_ltd_ram_address, rh->s.main_ltd_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
|
||
if ( !CheckDigest( md, rh->s.main_ltd_static_digest, TRUE, FALSE ) )
|
||
{
|
||
OS_TPrintf("Failed to check main_ltd_static_digest.\n");
|
||
goto end;
|
||
}
|
||
}
|
||
if ( rh->s.sub_ltd_size > 0 )
|
||
{
|
||
SVC_CalcHMACSHA1( md, rh->s.sub_ltd_ram_address, rh->s.sub_ltd_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
|
||
if ( !CheckDigest( md, rh->s.sub_ltd_static_digest, TRUE, FALSE ) )
|
||
{
|
||
OS_TPrintf("Failed to check sub_ltd_static_digest.\n");
|
||
goto end;
|
||
}
|
||
}
|
||
}
|
||
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
|
||
// 8: after FS_LoadStatic
|
||
PXI_NotifyID( FIRM_PXI_ID_DONE_STATIC );
|
||
// 9: after PXI
|
||
OS_WaitVBlankIntr();
|
||
|
||
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
|
||
PrintString( X_OFF, y++, FONT_WHITE, "Booting..." );
|
||
OS_WaitVBlankIntr();
|
||
OS_BootFromFIRM();
|
||
|
||
end:
|
||
PrintString( X_OFF+20, y, FONT_RED, "Failed." );
|
||
OS_WaitVBlankIntr();
|
||
EraseAll();
|
||
|
||
// failed
|
||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||
OS_Terminate();
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------
|
||
// myInit
|
||
//
|
||
void myInit(void)
|
||
{
|
||
//---- init
|
||
OS_InitFIRM();
|
||
OS_InitTick();
|
||
OS_InitAlarm();
|
||
FX_Init();
|
||
GX_Init();
|
||
GX_DispOff();
|
||
GXS_DispOff();
|
||
|
||
//---- init displaying
|
||
GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
|
||
MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
|
||
(void)GX_DisableBankForLCDC();
|
||
|
||
MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
|
||
MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
|
||
MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
|
||
MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
|
||
|
||
//---- setting 2D for top screen
|
||
GX_SetBankForBG(GX_VRAM_BG_128_A);
|
||
|
||
G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
|
||
GX_BG_COLORMODE_16,
|
||
GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
|
||
G2_SetBG0Priority(0);
|
||
G2_BG0Mosaic(FALSE);
|
||
GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
|
||
GX_SetVisiblePlane(GX_PLANEMASK_BG0);
|
||
|
||
GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
|
||
GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
|
||
|
||
//---- setting 2D for bottom screen
|
||
GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
|
||
|
||
G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
|
||
GX_BG_COLORMODE_16,
|
||
GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
|
||
G2S_SetBG0Priority(0);
|
||
G2S_BG0Mosaic(FALSE);
|
||
GXS_SetGraphicsMode(GX_BGMODE_0);
|
||
GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
|
||
|
||
GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
|
||
GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
|
||
|
||
//---- screen
|
||
MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
|
||
DC_FlushRange(gScreen, sizeof(gScreen));
|
||
/* DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F><EFBFBD>W<EFBFBD>X<EFBFBD>^<5E>փA<D683>N<EFBFBD>Z<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>̂ŃL<C583><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD> Wait <20>͕s<CD95>v */
|
||
// DC_WaitWriteBufferEmpty();
|
||
GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
|
||
GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
|
||
|
||
//---- backdrop
|
||
*(u16*)HW_PLTT = GX_RGB(8,0,0);
|
||
*(u16*)HW_DB_PLTT = GX_RGB(8,0,0);
|
||
|
||
//---- init interrupt
|
||
OS_SetIrqFunction(OS_IE_V_BLANK, myVBlankIntr);
|
||
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
|
||
(void)GX_VBlankIntr(TRUE);
|
||
(void)OS_EnableIrq();
|
||
(void)OS_EnableInterrupts();
|
||
|
||
//---- start displaying
|
||
GX_DispOn();
|
||
GXS_DispOn();
|
||
}
|
||
|
||
//----------------------------------------------------------------
|
||
// myVBlankIntr
|
||
// vblank interrupt handler
|
||
//
|
||
static void myVBlankIntr(void)
|
||
{
|
||
//---- upload pseudo screen to VRAM
|
||
DC_FlushRange(gScreen, sizeof(gScreen));
|
||
/* DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F><EFBFBD>W<EFBFBD>X<EFBFBD>^<5E>փA<D683>N<EFBFBD>Z<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>̂ŃL<C583><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD> Wait <20>͕s<CD95>v */
|
||
// DC_WaitWriteBufferEmpty();
|
||
GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
|
||
GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
|
||
|
||
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
|
||
}
|