・無線ファームファイルの新フォーマットに対応。

・NVRAMからの読み込みをARM9で行うようにする。
# TwlSDKのrevision 6168 以降を使用してください。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1470 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
sato_masaki 2008-05-22 09:24:40 +00:00
parent 61dc95a88a
commit a386e82697
3 changed files with 121 additions and 55 deletions

View File

@ -19,6 +19,7 @@
#include <twl/os/common/format_rom.h> #include <twl/os/common/format_rom.h>
#include <twl/lcfg.h> #include <twl/lcfg.h>
#include <twl/nwm/ARM9/ForLauncher/nwm_init_for_launcher.h> #include <twl/nwm/ARM9/ForLauncher/nwm_init_for_launcher.h>
#include <nitro/nvram/nvram.h>
#include <firm.h> #include <firm.h>
#include <sysmenu.h> #include <sysmenu.h>
@ -51,8 +52,6 @@
#define SIGNHEAP_SIZE 0x01000 #define SIGNHEAP_SIZE 0x01000
#define FWHEADER_SIZE 0x100
/* /*
internal variables internal variables
@ -67,11 +66,14 @@ static OSTick startTick = 0;
static OSMessageQueue mesq; static OSMessageQueue mesq;
static OSMessage mesAry[1]; static OSMessage mesAry[1];
static u8 fwType; // must be in main memory
/* /*
internal functions internal functions
*/ */
static void InstallFirmCallback(void* arg); static void InstallFirmCallback(void* arg);
static BOOL GetFirmwareFilepath(char *path); static BOOL GetFirmwareFilepath(char *path);
static s32 ReadFirmwareSecurityArea(char *path, u8 *buffer, s32 bufSize);
static s32 ReadFirmwareHeader(char *path, u8 *buffer, s32 bufSize); static s32 ReadFirmwareHeader(char *path, u8 *buffer, s32 bufSize);
static s32 ReadFirmwareBinary(char *path, u32 offset, u8 *buffer, s32 bufSize); static s32 ReadFirmwareBinary(char *path, u32 offset, u8 *buffer, s32 bufSize);
static BOOL VerifyWlanfirmSignature(u8* buffer, u32 length); static BOOL VerifyWlanfirmSignature(u8* buffer, u32 length);
@ -160,27 +162,14 @@ BOOL GetFirmwareFilepath(char *path)
} }
s32 ReadFirmwareSecurityArea(char *path, u8 *buffer, s32 bufSize)
{
return ReadFirmwareBinary(path, 0, buffer, bufSize);
}
s32 ReadFirmwareHeader(char *path, u8 *buffer, s32 bufSize) s32 ReadFirmwareHeader(char *path, u8 *buffer, s32 bufSize)
{ {
FSFile file[1]; return ReadFirmwareBinary(path, NWM_FW_SECURITY_AREA_SIZE, buffer, bufSize);
s32 flen;
FS_InitFile( file );
if (!FS_OpenFileEx(file, path, FS_FILEMODE_R)) {
OS_TWarning("FS_OpenFileEx(%s) failed.\n", path);
return -1;
}
flen = FS_ReadFile(file, buffer, bufSize);
if( flen == -1 ) {
OS_TWarning("FS_ReadFile failed.\n");
return -1;
}
(void)FS_CloseFile(file);
return flen;
} }
s32 ReadFirmwareBinary(char *path, u32 offset, u8 *buffer, s32 bufSize) s32 ReadFirmwareBinary(char *path, u32 offset, u8 *buffer, s32 bufSize)
@ -228,7 +217,7 @@ static const u8 s_pubkey9_1[ 0x80 ] = {
BOOL VerifyWlanfirmSignature(u8* buffer, u32 length) BOOL VerifyWlanfirmSignature(u8* buffer, u32 length)
{ {
#pragma unused(length) #pragma unused(length)
NWMFirmFileHeader *hdr = (NWMFirmFileHeader*)buffer; NWMFirmSecurityArea *hdr = (NWMFirmSecurityArea*)buffer;
u8 *pPubkey; u8 *pPubkey;
u8 *pSign; u8 *pSign;
u8 *txt; u8 *txt;
@ -249,14 +238,14 @@ BOOL VerifyWlanfirmSignature(u8* buffer, u32 length)
#else #else
pPubkey = OSi_GetFromFirmAddr()->rsa_pubkey[WLANFIRM_PUBKEY_INDEX]; pPubkey = OSi_GetFromFirmAddr()->rsa_pubkey[WLANFIRM_PUBKEY_INDEX];
#endif #endif
pSign = (u8*)((u32)buffer + (u32)hdr->soffset); pSign = (u8*)hdr->sign;
txt = buffer; txt = (u8*)hdr->hash;
txtlen = (u32)hdr->soffset; /* <20><>¼Ì¼OÜÅÌLength */ txtlen = (u32)NWM_FW_SECURITY_AREA_SIZE - SIGN_LENGTH; /* 署名の直前までのLength */
/* calculate SHA-1 digest */ /* calculate SHA-1 digest */
SVC_SHA1Init( &sctx ); SVC_SHA1Init( &sctx );
SVC_SHA1Update( &sctx, (const void*)txt,txtlen); SVC_SHA1Update( &sctx, (const void*)txt, txtlen);
SVC_SHA1GetHash( &sctx, txtDigest ); SVC_SHA1GetHash( &sctx, txtDigest );
#if (REPORT_HASH_COMPARISON == 1) #if (REPORT_HASH_COMPARISON == 1)
@ -366,13 +355,35 @@ void PrintDigest(u8 *digest)
BOOL InstallWlanFirmware( BOOL isHotStartWLFirm ) BOOL InstallWlanFirmware( BOOL isHotStartWLFirm )
{ {
NWMRetCode err; NWMRetCode err;
NWMFirmDataParam *pFdParam = (NWMFirmDataParam *)NWM_PARAM_FWDATA_ADDRESS;
NVRAMResult nvRes;
s_isFinished = FALSE; s_isFinished = FALSE;
pNwmBuf = 0; pNwmBuf = NULL;
pFwBuffer = 0; pFwBuffer = NULL;
OS_InitMessageQueue(&mesq, mesAry, sizeof(mesAry)/sizeof(mesAry[0])); OS_InitMessageQueue(&mesq, mesAry, sizeof(mesAry)/sizeof(mesAry[0]));
/* Read FW type from NVRAM */
nvRes = NVRAMi_Read(NWM_NVR_FWTYPE_OFFSET_ADDRESS, 1, &fwType );
if (nvRes != NVRAM_RESULT_SUCCESS)
{
OS_TWarning("Error: Couldn't access NVRAM.\n");
goto instfirm_error;
}
if (fwType == 0xFF)
{
// NVRAMの該当領域が0xFF(何も書かれていない)の場合は、fwType=0として扱う。
OS_TWarning("Firmware Type has not been found in NVRAM.\n");
fwType = 0;
}
pFdParam->fwType = fwType;
OS_TPrintf("[Wlan Firm] FWtype is %d\n", fwType);
/* HotStart/ColdStart̃`ƒFƒbƒN */ /* HotStart/ColdStart̃`ƒFƒbƒN */
s_isHotStartWLFirm = isHotStartWLFirm; s_isHotStartWLFirm = isHotStartWLFirm;
@ -396,42 +407,80 @@ BOOL InstallWlanFirmware( BOOL isHotStartWLFirm )
} else { // COLD START } else { // COLD START
s32 flen = 0; s32 flen = 0;
char path[256]; char path[256];
u32 offset, length, fwType; u32 offset, length, hdrLen;
u8 hdrBuffer[FWHEADER_SIZE];
u8 *pHash = NULL; u8 *pHash = NULL;
u8 *pSecBuf = NULL;
u8 *pHdrBuf = NULL;
// Get Filepath // Get Filepath
if (FALSE == GetFirmwareFilepath(path)) { if (FALSE == GetFirmwareFilepath(path)) {
goto instfirm_error; goto instfirm_error;
} }
// Get WLAN Firmware type // Read Security area of WLAN firm
fwType = ((NWMFirmDataParam *)NWM_PARAM_FWDATA_ADDRESS)->fwType; /* Allocate security area buffer from heap. */
OS_TPrintf("[Wlan Firm] FWtype is %d\n", fwType); pSecBuf = SYSM_Alloc( NWM_FW_SECURITY_AREA_SIZE );
// Read header of WLAN firm if (!pSecBuf) {
flen = ReadFirmwareHeader(path, hdrBuffer, FWHEADER_SIZE); OS_TWarning("[Wlan Firm] Error: Couldn't allocate memory for Security Area.\n");
goto instfirm_error;
}
flen = ReadFirmwareSecurityArea(path, pSecBuf, NWM_FW_SECURITY_AREA_SIZE);
if ( 0 >= flen ) if ( 0 >= flen )
{ {
OS_TPrintf("[Wlan Firm] Error: Couldn't read wlan firmware header.\n"); OS_TPrintf("[Wlan Firm] Error: Couldn't read wlan firmware security area.\n");
SYSM_Free( pSecBuf );
pSecBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
// Check signature data // Check signature data
if (FALSE == VerifyWlanfirmSignature(hdrBuffer, (u32)flen)) if (FALSE == VerifyWlanfirmSignature(pSecBuf, (u32)flen))
{ {
OS_TPrintf("[Wlan Firm] Error: This Wlan Firmware is quite illegal!\n"); OS_TPrintf("[Wlan Firm] Error: This Wlan Firmware is quite illegal!\n");
OS_TPrintf("[Wlan Firm] It has never been installed.\n"); OS_TPrintf("[Wlan Firm] It has never been installed.\n");
SYSM_Free( pSecBuf );
pSecBuf = NULL;
goto instfirm_error;
}
hdrLen = ((NWMFirmSecurityArea*)pSecBuf)->hdrLen;
// Free Security area buffer
SYSM_Free( pSecBuf );
pSecBuf = NULL;
/* Allocate header area buffer from heap. */
pHdrBuf = SYSM_Alloc( hdrLen );
if (!pHdrBuf) {
OS_TWarning("[Wlan Firm] Error: Couldn't allocate memory for Header area.\n");
goto instfirm_error;
}
// Read header of WLAN firm
flen = ReadFirmwareHeader(path, pHdrBuf, (s32)hdrLen);
if ( 0 >= flen )
{
OS_TPrintf("[Wlan Firm] Error: Couldn't read wlan firmware header.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
// Find corresponding FW image // Find corresponding FW image
offset = NWMi_GetFirmImageOffset(hdrBuffer, fwType); offset = NWMi_GetFirmImageOffset(pHdrBuf, (u32)fwType);
length = NWMi_GetFirmImageLength(hdrBuffer, fwType); length = NWMi_GetFirmImageLength(pHdrBuf, (u32)fwType);
if (offset == 0 || length == 0) { if (offset == 0 || length == 0) {
OS_TPrintf("[Wlan Firm] Error: Couldn't get Firmware image.\n"); OS_TPrintf("[Wlan Firm] Error: Couldn't get Firmware image.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
@ -439,6 +488,9 @@ BOOL InstallWlanFirmware( BOOL isHotStartWLFirm )
pFwBuffer = SYSM_Alloc( length ); pFwBuffer = SYSM_Alloc( length );
if (!pFwBuffer) { if (!pFwBuffer) {
OS_TWarning("[Wlan Firm] Error: Couldn't allocate memory for WlanFirmware.\n"); OS_TWarning("[Wlan Firm] Error: Couldn't allocate memory for WlanFirmware.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
@ -448,14 +500,20 @@ BOOL InstallWlanFirmware( BOOL isHotStartWLFirm )
if ( 0 >= flen ) if ( 0 >= flen )
{ {
OS_TPrintf("[Wlan Firm] Error: Couldn't read wlan firmware.\n"); OS_TPrintf("[Wlan Firm] Error: Couldn't read wlan firmware.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
// Compare hashes // Compare hashes
pHash = NWMi_GetFirmImageHashAddress(hdrBuffer, fwType); pHash = NWMi_GetFirmImageHashAddress(pHdrBuf, (u32)fwType);
if (pHash == NULL) if (pHash == NULL)
{ {
OS_TPrintf("[Wlan Firm] Error: Couldn't get hash of wlan firmware image.\n"); OS_TPrintf("[Wlan Firm] Error: Couldn't get hash of wlan firmware image.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
@ -463,10 +521,17 @@ BOOL InstallWlanFirmware( BOOL isHotStartWLFirm )
if (FALSE == CheckHash((const u8*)pHash, (const u8*)pFwBuffer, length)) if (FALSE == CheckHash((const u8*)pHash, (const u8*)pFwBuffer, length))
{ {
OS_TPrintf("[Wlan Firm] Error: Hash data is illegal.\n"); OS_TPrintf("[Wlan Firm] Error: Hash data is illegal.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
goto instfirm_error; goto instfirm_error;
} }
OS_TPrintf("[Wlan Firm] CheckHash ok.\n"); OS_TPrintf("[Wlan Firm] CheckHash ok.\n");
// Free Header area buffer
SYSM_Free( pHdrBuf );
pHdrBuf = NULL;
pNwmBuf = SYSM_Alloc( NWM_SYSTEM_BUF_SIZE ); pNwmBuf = SYSM_Alloc( NWM_SYSTEM_BUF_SIZE );
if (!pNwmBuf) { if (!pNwmBuf) {
OS_TWarning("Error: Couldn't allocate memory for NWM.\n"); OS_TWarning("Error: Couldn't allocate memory for NWM.\n");

View File

@ -26,7 +26,7 @@
// extern data----------------------------------------------------------------- // extern data-----------------------------------------------------------------
// define data----------------------------------------------------------------- // define data-----------------------------------------------------------------
#define DISABLE_WLFIRM_LOAD
// function's prototype------------------------------------------------------- // function's prototype-------------------------------------------------------
static void INTR_VBlank( void ); static void INTR_VBlank( void );
static void deleteTmp(); static void deleteTmp();

View File

@ -32,9 +32,10 @@ MY_TITLE = HNCA
MY_FIRM = $(MY_FIRM_ROOT_CYG)/nwm_firm.bin MY_FIRM = $(MY_FIRM_ROOT_CYG)/nwm_firm.bin
# FWファイルの先頭1バイトに入っているバージョン情報を取得 # FWファイルの先頭1バイトに入っているバージョン情報を取得
MY_VERSION = $(shell perl -e "open(IN,'$(MY_FIRM)');binmode(IN);read(IN, \$$buf, 1);print unpack("C", \$$buf);close(IN);") MY_VERSION_MAJOR = $(shell perl -e "open(IN,'$(MY_FIRM)');binmode(IN);seek(IN, 160 + 0, 0);read(IN, \$$buf, 1);print unpack("C", \$$buf);close(IN);")
MY_VERSION_MINOR = $(shell perl -e "open(IN,'$(MY_FIRM)');binmode(IN);seek(IN, 160 + 1, 0);read(IN, \$$buf, 1);print unpack("C", \$$buf);close(IN);")
MAKETAD_FLAGS += 0003000F484E4341 3031 $(MY_VERSION) WIRELESS_FW -p MAKETAD_FLAGS += 0003000F484E4341 3031 $(MY_VERSION_MAJOR) WIRELESS_FW -v $(MY_VERSION_MINOR) -p
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
MY_TAD = $(MY_TITLE).tad MY_TAD = $(MY_TITLE).tad