mirror of
				https://github.com/brain-hackers/brainlilo
				synced 2025-11-04 14:38:35 +09:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										220
									
								
								BrainLILO.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								BrainLILO.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
/*
 | 
			
		||||
 * BrainLILO
 | 
			
		||||
 * U-Boot loader for electric dictionary.
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2019 C. Shirasaka <holly_programmer@outlook.com>
 | 
			
		||||
 * based on
 | 
			
		||||
 ** ResetKitHelper
 | 
			
		||||
 ** Soft/hard reset the electronic dictionary.
 | 
			
		||||
 ** 
 | 
			
		||||
 ** Copyright (C) 2012 T. Kawada <tcppjp [ at ] gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This file is licensed in MIT license.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining 
 | 
			
		||||
 * a copy of this software and associated documentation files (the "Software"), 
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation the
 | 
			
		||||
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 | 
			
		||||
 * sell copies of the Software, and to permit persons to whom the Software is 
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in 
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define BRAINLILO_API extern "C" __declspec(dllexport)
 | 
			
		||||
#include "BrainLILO.h"
 | 
			
		||||
#include "BrainLILODrv.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static bool g_initialized=false;
 | 
			
		||||
static HANDLE g_helperHandle=NULL;
 | 
			
		||||
static HINSTANCE g_hInstance;
 | 
			
		||||
 | 
			
		||||
static void initialize(){
 | 
			
		||||
    if(g_initialized)
 | 
			
		||||
        return;
 | 
			
		||||
    
 | 
			
		||||
    g_initialized=true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void getThisDllDirectoryPath(LPWSTR buffer){
 | 
			
		||||
	// retrive the path of the application.
 | 
			
		||||
	GetModuleFileName(g_hInstance, buffer, 512);
 | 
			
		||||
	
 | 
			
		||||
    const size_t notFound=(size_t)-1;
 | 
			
		||||
    size_t i=0;
 | 
			
		||||
    size_t j=notFound;
 | 
			
		||||
    
 | 
			
		||||
    while(buffer[i]){
 | 
			
		||||
        if(buffer[i]==L'/' || buffer[i]==L'\\'){
 | 
			
		||||
            j=i;
 | 
			
		||||
        }
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(j==notFound)
 | 
			
		||||
        return;
 | 
			
		||||
    
 | 
			
		||||
    buffer[j]=0;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool isDriverLoaded(){
 | 
			
		||||
    HANDLE handle;
 | 
			
		||||
    handle=CreateFile(L"LIN0:", GENERIC_READ|GENERIC_WRITE|FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);
 | 
			
		||||
    if(handle==INVALID_HANDLE_VALUE)
 | 
			
		||||
		handle=NULL;
 | 
			
		||||
    if(handle){
 | 
			
		||||
        CloseHandle(handle);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool addDriverToRegistry(){
 | 
			
		||||
	HKEY hKey;
 | 
			
		||||
	DWORD dw;
 | 
			
		||||
	RegCreateKeyEx(HKEY_LOCAL_MACHINE, (L"Drivers\\BuiltIn\\LILODrv"), 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, &dw);
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	dw = 0x0000;
 | 
			
		||||
	if(RegSetValueEx(hKey, (L"Index"), 0, REG_DWORD, (BYTE*)&dw, sizeof(DWORD)) != ERROR_SUCCESS)
 | 
			
		||||
	{
 | 
			
		||||
		RegCloseKey(hKey);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	dw = 0x0100;
 | 
			
		||||
	if(RegSetValueEx(hKey, (L"Order"), 0, REG_DWORD, (BYTE*)&dw, sizeof(DWORD)) != ERROR_SUCCESS)
 | 
			
		||||
	{
 | 
			
		||||
		RegCloseKey(hKey);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if(RegSetValueEx(hKey, (L"Dll"), 0, REG_SZ, (BYTE*)(L"\\Windows\\BrainLILODrv.dll"), sizeof(TCHAR) * ((DWORD)wcslen((L"\\Windows\\BrainLILODrv.dll")) + 1)) != ERROR_SUCCESS)
 | 
			
		||||
	{
 | 
			
		||||
		RegCloseKey(hKey);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if(RegSetValueEx(hKey, (L"Prefix"), 0, REG_SZ, (BYTE*)(L"LIN"), sizeof(TCHAR) * ((DWORD)wcslen((L"LIN")) + 1)) != ERROR_SUCCESS)
 | 
			
		||||
	{
 | 
			
		||||
		RegCloseKey(hKey);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void loadDriverIfNeeded(){
 | 
			
		||||
    if(isDriverLoaded())
 | 
			
		||||
        return;
 | 
			
		||||
	
 | 
			
		||||
	OutputDebugString(L"BrainLILO: installing LILODriver...");
 | 
			
		||||
	
 | 
			
		||||
	DWORD err;
 | 
			
		||||
    HANDLE driver=NULL;
 | 
			
		||||
	
 | 
			
		||||
    wchar_t driverPath[1024];
 | 
			
		||||
    getThisDllDirectoryPath(driverPath);
 | 
			
		||||
    wcscat(driverPath, L"\\BrainLILODrv.dll");
 | 
			
		||||
	
 | 
			
		||||
	TCHAR newDriverPath[128];
 | 
			
		||||
	wcscpy(newDriverPath,L"\\Windows\\BrainLILODrv.dll");
 | 
			
		||||
	
 | 
			
		||||
    {
 | 
			
		||||
        wchar_t buf[1024];
 | 
			
		||||
        swprintf(buf, L"BrainLILO: copying \"%ls\" to \"%ls\"",
 | 
			
		||||
                 driverPath, newDriverPath);
 | 
			
		||||
        OutputDebugString(buf);
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
	if(!CopyFile(driverPath,newDriverPath, FALSE)){
 | 
			
		||||
	
 | 
			
		||||
		
 | 
			
		||||
		if(GetFileAttributes(newDriverPath)==(DWORD)-1){
 | 
			
		||||
			OutputDebugString(L"BrainLILO: failed to copy");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
        
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	OutputDebugString(L"BrainLILO: registering BrainLILODriver...");
 | 
			
		||||
	
 | 
			
		||||
	try{
 | 
			
		||||
		driver=RegisterDevice(L"LIN", 0, L"\\Windows\\BrainLILODrv.dll", 0);
 | 
			
		||||
		
 | 
			
		||||
		if(driver==INVALID_HANDLE_VALUE)
 | 
			
		||||
			driver=NULL;
 | 
			
		||||
		
 | 
			
		||||
		if(!driver){
 | 
			
		||||
			
 | 
			
		||||
			driver=RegisterDevice(L"LIN", 0, L"BrainLILODrv.dll", 0);
 | 
			
		||||
			
 | 
			
		||||
			if(driver==INVALID_HANDLE_VALUE)
 | 
			
		||||
				driver=NULL;
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		err=GetLastError();
 | 
			
		||||
	}catch(DWORD e){
 | 
			
		||||
		err=e;
 | 
			
		||||
	}
 | 
			
		||||
	if(!driver && (err!=0x964)){
 | 
			
		||||
		OutputDebugString(L"BrainLILO: failed to install...");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void openDriver(){
 | 
			
		||||
    if(g_helperHandle)
 | 
			
		||||
        return;
 | 
			
		||||
    g_helperHandle=CreateFile(L"LIN0:", GENERIC_READ|GENERIC_WRITE|FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);
 | 
			
		||||
	if(g_helperHandle==INVALID_HANDLE_VALUE)
 | 
			
		||||
		g_helperHandle=NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BOOL APIENTRY DllMain(HINSTANCE hInstance, 
 | 
			
		||||
                                           DWORD  ul_reason_for_call, 
 | 
			
		||||
                                           LPVOID lpReserved
 | 
			
		||||
                                           )
 | 
			
		||||
{
 | 
			
		||||
    switch (ul_reason_for_call)
 | 
			
		||||
	{
 | 
			
		||||
		case DLL_PROCESS_ATTACH:
 | 
			
		||||
		case DLL_THREAD_ATTACH:
 | 
			
		||||
            
 | 
			
		||||
            g_hInstance=hInstance;
 | 
			
		||||
            
 | 
			
		||||
            initialize();
 | 
			
		||||
            loadDriverIfNeeded();
 | 
			
		||||
            openDriver();
 | 
			
		||||
			
 | 
			
		||||
		case DLL_THREAD_DETACH:
 | 
			
		||||
		case DLL_PROCESS_DETACH:
 | 
			
		||||
			break;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BRAINLILO_API BOOL RKDoSoftReset(){
 | 
			
		||||
	
 | 
			
		||||
	initialize();
 | 
			
		||||
    loadDriverIfNeeded();
 | 
			
		||||
    openDriver();
 | 
			
		||||
	
 | 
			
		||||
    return DeviceIoControl(g_helperHandle, IOCTL_LIN_DO_LINUX,
 | 
			
		||||
                           NULL, 0, NULL, 0,
 | 
			
		||||
                           NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								BrainLILO.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								BrainLILO.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// This file is in public domain.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#ifndef BRAINLILO_API
 | 
			
		||||
#define BRAINLILO_API __declspec(dllimport)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"{
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
    BRAINLILO_API BOOL RKDoSoftReset();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										9
									
								
								BrainLILODrv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								BrainLILODrv.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// This file is in public domain.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <winioctl.h>
 | 
			
		||||
 | 
			
		||||
#define _LIN_ACCESS_CTL_CODE(_Function) \
 | 
			
		||||
CTL_CODE(FILE_DEVICE_UNKNOWN, _Function, METHOD_BUFFERED, FILE_ANY_ACCESS)
 | 
			
		||||
 | 
			
		||||
#define IOCTL_LIN_DO_LINUX _LIN_ACCESS_CTL_CODE(0x804)
 | 
			
		||||
							
								
								
									
										298
									
								
								BrainLILOdrv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								BrainLILOdrv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,298 @@
 | 
			
		||||
/*
 | 
			
		||||
 * BrainLILODrv
 | 
			
		||||
 * U-Boot loader for electric dictionary.
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2019 C. Shirasaka <holly_programmer@outlook.com>
 | 
			
		||||
 * based on
 | 
			
		||||
 ** ResetKitHelper
 | 
			
		||||
 ** Soft/hard reset the electronic dictionary.
 | 
			
		||||
 ** 
 | 
			
		||||
 ** Copyright (C) 2012 T. Kawada <tcppjp [ at ] gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This file is licensed in MIT license.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining 
 | 
			
		||||
 * a copy of this software and associated documentation files (the "Software"), 
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation the
 | 
			
		||||
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 | 
			
		||||
 * sell copies of the Software, and to permit persons to whom the Software is 
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in 
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#define FSNOTIFY_POWER_OFF      1
 | 
			
		||||
#define FSNOTIFY_POWER_ON       0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BRAINLILODRV_API __declspec(dllexport)
 | 
			
		||||
 | 
			
		||||
#include "BrainLILODrv.h"
 | 
			
		||||
 | 
			
		||||
#define FILE_DEVICE_POWER   FILE_DEVICE_ACPI    
 | 
			
		||||
 | 
			
		||||
#define IOCTL_POWER_CAPABILITIES    \
 | 
			
		||||
CTL_CODE(FILE_DEVICE_POWER, 0x400, METHOD_BUFFERED, FILE_ANY_ACCESS)
 | 
			
		||||
#define IOCTL_POWER_GET             \
 | 
			
		||||
CTL_CODE(FILE_DEVICE_POWER, 0x401, METHOD_BUFFERED, FILE_ANY_ACCESS)
 | 
			
		||||
#define IOCTL_POWER_SET             \
 | 
			
		||||
CTL_CODE(FILE_DEVICE_POWER, 0x402, METHOD_BUFFERED, FILE_ANY_ACCESS)
 | 
			
		||||
#define IOCTL_POWER_QUERY           \
 | 
			
		||||
CTL_CODE(FILE_DEVICE_POWER, 0x403, METHOD_BUFFERED, FILE_ANY_ACCESS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef BOOL (*KernelIoControlProc)(DWORD dwIoControlCode, LPVOID lpInBuf,
 | 
			
		||||
						DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize,LPDWORD lpBytesReturned);
 | 
			
		||||
static KernelIoControlProc KernelIoControl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
 | 
			
		||||
 | 
			
		||||
typedef PVOID (*MmMapIoSpaceProc)(PHYSICAL_ADDRESS, ULONG, BOOL);
 | 
			
		||||
static MmMapIoSpaceProc MmMapIoSpace;
 | 
			
		||||
 | 
			
		||||
typedef void (*FileSystemPowerFunctionProc)(DWORD);
 | 
			
		||||
static FileSystemPowerFunctionProc FileSystemPowerFunction;
 | 
			
		||||
 | 
			
		||||
typedef LPVOID (*AllocPhysMemProc)(DWORD,DWORD,DWORD,DWORD,PULONG);
 | 
			
		||||
 | 
			
		||||
typedef void (*NKForceCleanBootProc)(BOOL);
 | 
			
		||||
 | 
			
		||||
static void disableInterrupts(){
 | 
			
		||||
    asm volatile("mrs	r0, cpsr\n"
 | 
			
		||||
        "orr	r0,r0,#0x80\n"
 | 
			
		||||
        "msr	cpsr_c,r0\n"
 | 
			
		||||
        "mov	r0,#1":::"r0");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void EDNA2_physicalInvoker(){
 | 
			
		||||
	// r0-r7=params
 | 
			
		||||
	// r8=proc address
 | 
			
		||||
	asm volatile("nop\n" // who cares interrupt vectors?
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "msr	cpsr_c, #211\n"	// to supervisor mode
 | 
			
		||||
				 "mov	r9, #0\n"
 | 
			
		||||
				 "mcr	p15,0,r9,c13,c0,0\n" // clear fcse PID
 | 
			
		||||
				 "mrc	p15,0,r9,c1,c0,0\n" // read ctrl regs
 | 
			
		||||
				 "bic	r9, r9, #5\n" // disable MMU/DCache
 | 
			
		||||
				 "bic	r9, r9, #4096\n" // disable ICache
 | 
			
		||||
				 "orr	r9, r9, #8192\n" // and reset vectors to upper
 | 
			
		||||
				 "mcr	p15,0,r9,c1,c0,0\n" // write ctrl regs
 | 
			
		||||
				 "mov	r9, #0\n"
 | 
			
		||||
				 "mcr	p15,0,r9,c7,c7,0\n" // invalidate cache
 | 
			
		||||
				 "mcr	p15,0,r9,c8,c7,0\n" // invalidate tlb
 | 
			
		||||
				 "mov	pc, r8\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 "nop\n"
 | 
			
		||||
				 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void EDNA2_installPhysicalInvoker(){
 | 
			
		||||
	void *ptr=(void *)0xa8000000;
 | 
			
		||||
	wchar_t buf[256];
 | 
			
		||||
	swprintf(buf, L"ResetKit: copying to 0x%08x from 0x%08x\n",
 | 
			
		||||
			 (int)(ptr), (int)(&EDNA2_physicalInvoker));
 | 
			
		||||
	OutputDebugString(buf);
 | 
			
		||||
	memcpy(ptr, (const void *)&EDNA2_physicalInvoker, 64*4);
 | 
			
		||||
	//clearCache();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__attribute__((noreturn))
 | 
			
		||||
static void EDNA2_runPhysicalInvoker(){
 | 
			
		||||
	// r0=info
 | 
			
		||||
	asm volatile("msr	cpsr_c, #211\n" // to supervisor mode
 | 
			
		||||
				 "mrc	p15,0,r0,c1,c0,0\n" // read ctrl regs
 | 
			
		||||
				 "bic	r0, r0, #8192\n" // reset vector to lower
 | 
			
		||||
				 "mcr	p15,0,r0,c1,c0,0\n" // write ctrl regs
 | 
			
		||||
				 
 | 
			
		||||
				 "ldr	r0, =0x0000\n"
 | 
			
		||||
				 "ldr	r1, =0x0000\n"
 | 
			
		||||
				 "ldr	r2, =0x0000\n"
 | 
			
		||||
				 "ldr	r3, =0x0000\n"
 | 
			
		||||
				 "ldr	r4, =0x0000\n"
 | 
			
		||||
				 "ldr	r5, =0x0000\n"
 | 
			
		||||
				 "ldr	r6, =0x0000\n"
 | 
			
		||||
				 "ldr	r7, =0x0000\n"
 | 
			
		||||
				 "ldr	r8, =0x40002000\n"
 | 
			
		||||
				 "ldr	r9, =0x0000\n"
 | 
			
		||||
				 
 | 
			
		||||
				 "mrc	p15,0,r10,c1,c0,0\n" // read ctrl regs
 | 
			
		||||
				 "bic	r10, r10, #5\n" // disable MMU/DCache
 | 
			
		||||
				 "mcr	p15,0,r10,c1,c0,0\n" // write ctrl regs
 | 
			
		||||
		
 | 
			
		||||
				 "mov	pc, r8\n"
 | 
			
		||||
		
 | 
			
		||||
				 "swi	#0\n" // jump!
 | 
			
		||||
                 );
 | 
			
		||||
	
 | 
			
		||||
	// never reach here
 | 
			
		||||
	while(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((noreturn))
 | 
			
		||||
static DWORD EDNA2_callKernelEntryPoint(){
 | 
			
		||||
	OutputDebugString(L"BrainLILO: disabling interrupts");
 | 
			
		||||
    disableInterrupts();
 | 
			
		||||
	OutputDebugString(L"BrainLILO: injecting code to internal ram");
 | 
			
		||||
	EDNA2_installPhysicalInvoker();
 | 
			
		||||
	OutputDebugString(L"BrainLILO: invoking");
 | 
			
		||||
	EDNA2_runPhysicalInvoker();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool doLinux(){
 | 
			
		||||
	char *bootloaderdata;
 | 
			
		||||
	TCHAR bootloaderFileName[128]=TEXT("\\Storage Card\\loader\\u-boot.bin");
 | 
			
		||||
	HANDLE hFile;
 | 
			
		||||
	DWORD wReadSize;
 | 
			
		||||
	PULONG bootloaderptr;
 | 
			
		||||
 | 
			
		||||
	OutputDebugString(L"BrainLILO: loading bootloader.");
 | 
			
		||||
	hFile = CreateFile(bootloaderFileName , GENERIC_READ , 0 , NULL ,OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL);
 | 
			
		||||
	if (hFile == INVALID_HANDLE_VALUE) {
 | 
			
		||||
		OutputDebugString(L"Cant load bootloader");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	bootloaderdata  = (char *)malloc(GetFileSize(hFile , NULL));
 | 
			
		||||
	ReadFile(hFile , bootloaderdata , GetFileSize(hFile , NULL) , &wReadSize , NULL);
 | 
			
		||||
	CloseHandle(hFile);
 | 
			
		||||
 | 
			
		||||
	PHYSICAL_ADDRESS pa;
 | 
			
		||||
	pa.QuadPart=0x40002000;
 | 
			
		||||
	bootloaderptr=(PULONG)MmMapIoSpace(pa,wReadSize,FALSE);
 | 
			
		||||
	wchar_t buf[256];
 | 
			
		||||
	swprintf(buf, L"BrainLILO: copying bootloader to 0x%08x from 0x%08x\n",(int)(bootloaderptr), (int)(bootloaderdata));
 | 
			
		||||
	OutputDebugString(buf);
 | 
			
		||||
	memcpy(bootloaderptr,bootloaderdata,wReadSize);
 | 
			
		||||
	OutputDebugString(L"BrainLILO: bootloader copied");
 | 
			
		||||
	free(bootloaderdata);
 | 
			
		||||
	
 | 
			
		||||
	EDNA2_callKernelEntryPoint();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API BOOL LIN_IOControl(DWORD handle, DWORD dwIoControlCode, DWORD *pInBuf, DWORD nInBufSize, DWORD * pOutBuf, DWORD nOutBufSize, 
 | 
			
		||||
                                           PDWORD pBytesReturned){
 | 
			
		||||
    SetLastError(0);
 | 
			
		||||
    
 | 
			
		||||
    switch(dwIoControlCode){
 | 
			
		||||
        case IOCTL_LIN_DO_LINUX:
 | 
			
		||||
            if(FileSystemPowerFunction)
 | 
			
		||||
                FileSystemPowerFunction(FSNOTIFY_POWER_OFF);
 | 
			
		||||
            if(!doLinux()){
 | 
			
		||||
                if(FileSystemPowerFunction)
 | 
			
		||||
                    FileSystemPowerFunction(FSNOTIFY_POWER_ON);
 | 
			
		||||
                return FALSE;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API BOOL LIN_Read(DWORD handle, LPVOID pBuffer, DWORD dwNumBytes){
 | 
			
		||||
    SetLastError(ERROR_INVALID_FUNCTION);
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API BOOL LIN_Write(DWORD handle, LPVOID pBuffer, DWORD dwNumBytes){
 | 
			
		||||
    SetLastError(ERROR_INVALID_FUNCTION);
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API DWORD LIN_Seek(DWORD handle, long lDistance, DWORD dwMoveMethod){
 | 
			
		||||
    SetLastError(ERROR_INVALID_FUNCTION);
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API void LIN_PowerUp(void){
 | 
			
		||||
	OutputDebugString(L"BrainLILO: resuming.");
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API void LIN_PowerDown(void){
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API DWORD LIN_Init(LPCTSTR pContext,
 | 
			
		||||
									   DWORD dwBusContext){
 | 
			
		||||
    
 | 
			
		||||
	void *ctx;
 | 
			
		||||
	ctx=(void *)LocalAlloc(LPTR, sizeof(4));
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	return (DWORD)ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API DWORD LIN_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode){
 | 
			
		||||
	
 | 
			
		||||
	void *hnd=(void *)LocalAlloc(LPTR, 4);
 | 
			
		||||
	return (DWORD)hnd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API BOOL LIN_Close(DWORD handle){
 | 
			
		||||
	LocalFree((void *)handle);
 | 
			
		||||
	
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BRAINLILODRV_API BOOL LIN_Deinit(DWORD dwContext){
 | 
			
		||||
	
 | 
			
		||||
	LocalFree((void *)dwContext);
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" BOOL APIENTRY DllMainCRTStartup( HANDLE hModule, 
 | 
			
		||||
                                           DWORD  ul_reason_for_call, 
 | 
			
		||||
                                           LPVOID lpReserved
 | 
			
		||||
                                           )
 | 
			
		||||
{
 | 
			
		||||
    switch (ul_reason_for_call)
 | 
			
		||||
	{
 | 
			
		||||
		case DLL_PROCESS_ATTACH:
 | 
			
		||||
	case DLL_THREAD_ATTACH:
 | 
			
		||||
			KernelIoControl=(KernelIoControlProc)
 | 
			
		||||
			GetProcAddress(LoadLibrary(L"COREDLL"),
 | 
			
		||||
						   L"KernelIoControl");
 | 
			
		||||
			
 | 
			
		||||
			MmMapIoSpace=(MmMapIoSpaceProc)
 | 
			
		||||
			GetProcAddress(LoadLibrary(L"CEDDK"),
 | 
			
		||||
						   L"MmMapIoSpace");
 | 
			
		||||
            
 | 
			
		||||
            FileSystemPowerFunction=(FileSystemPowerFunctionProc)
 | 
			
		||||
			GetProcAddress(LoadLibrary(L"COREDLL"),
 | 
			
		||||
						   L"FileSystemPowerFunction");
 | 
			
		||||
            
 | 
			
		||||
		case DLL_THREAD_DETACH:
 | 
			
		||||
		case DLL_PROCESS_DETACH:
 | 
			
		||||
			break;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
 | 
			
		||||
CC=/opt/mingw32ce/bin/arm-mingw32ce-gcc
 | 
			
		||||
CXX=/opt/mingw32ce/bin/arm-mingw32ce-g++
 | 
			
		||||
LD=/opt/mingw32ce/bin/arm-mingw32ce-g++
 | 
			
		||||
STRIP=/opt/mingw32ce/bin/arm-mingw32ce-strip
 | 
			
		||||
DLLTOOL=/opt/mingw32ce/bin/arm-mingw32ce-dlltool
 | 
			
		||||
AS=/opt/mingw32ce/bin/arm-mingw32ce-as
 | 
			
		||||
NM=/opt/mingw32ce/bin/arm-mingw32ce-nm
 | 
			
		||||
WINDRES=/opt/mingw32ce/bin/arm-mingw32ce-windres
 | 
			
		||||
 | 
			
		||||
OUTPUT=BrainLILO.dll BrainLILODrv.dll BrainLILO.exe 
 | 
			
		||||
 | 
			
		||||
CXXFLAGS= -DEV_PLATFORM_WIN32 -DUNICODE -D_UNICODE -DEV_UNSAFE_SWPRINTF -mwin32 \
 | 
			
		||||
-O0 -mcpu=arm926ej-s -D_WIN32_WCE=0x600 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 \
 | 
			
		||||
-D_FILE_OFFSET_BITS=64 -static
 | 
			
		||||
 | 
			
		||||
DLLFLAGS=-DEV_PLATFORM_WIN32 -DUNICODE -D_UNICODE -DEV_UNSAFE_SWPRINTF -mwin32 \
 | 
			
		||||
-O0 -mcpu=arm926ej-s -D_WIN32_WCE=0x600 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 \
 | 
			
		||||
-D_FILE_OFFSET_BITS=64 -DNDEBUG -Wall -static \
 | 
			
		||||
 -Wl,--image-base,0x100000 \
 | 
			
		||||
 -shared
 | 
			
		||||
 
 | 
			
		||||
DRVFLAGS= -DEV_PLATFORM_WIN32 -DUNICODE -D_UNICODE -DEV_UNSAFE_SWPRINTF -mwin32 \
 | 
			
		||||
-O0 -mcpu=arm926ej-s -D_WIN32_WCE=0x600 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 \
 | 
			
		||||
-D_FILE_OFFSET_BITS=64 -DNDEBUG -Wall -static \
 | 
			
		||||
 -Wl,--image-base,0x100000 \
 | 
			
		||||
 -nostdlib -lcoredll -shared
 | 
			
		||||
 | 
			
		||||
.PHONY:		all clean
 | 
			
		||||
 | 
			
		||||
all:				$(OUTPUT)
 | 
			
		||||
 | 
			
		||||
clean:			
 | 
			
		||||
				rm -f $(OUTPUT)
 | 
			
		||||
 | 
			
		||||
BrainLILO.dll:	BrainLILO.cpp
 | 
			
		||||
				$(CXX) BrainLILO.cpp -o BrainLILO.dll $(DLLFLAGS)
 | 
			
		||||
				$(STRIP) BrainLILO.dll
 | 
			
		||||
				
 | 
			
		||||
BrainLILODrv.dll:	BrainLILODrv.cpp
 | 
			
		||||
				$(CXX) BrainLILODrv.cpp -o BrainLILODrv.dll $(DRVFLAGS)
 | 
			
		||||
				$(STRIP) BrainLILODrv.dll
 | 
			
		||||
 | 
			
		||||
BrainLILO.exe:	bootloader.cpp
 | 
			
		||||
				$(CXX) bootloader.cpp -o BrainLILO.exe $(CXXFLAGS)
 | 
			
		||||
				$(STRIP) BrainLILO.exe
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										86
									
								
								bootloader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								bootloader.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
// This file is in public domain.
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <tchar.h>
 | 
			
		||||
 | 
			
		||||
#define MainWindowClassName L"SelectorMainWindowClass"
 | 
			
		||||
 | 
			
		||||
#define DataTypeAlertError          0x1000
 | 
			
		||||
#define DataTypeAlertInformation    0x1001
 | 
			
		||||
#define DataTypeAlertWarning        0x1002
 | 
			
		||||
 | 
			
		||||
static void showAlertWarning(LPCWSTR message,
 | 
			
		||||
                           LPCWSTR title){
 | 
			
		||||
    
 | 
			
		||||
    HWND selectorMainWindow=FindWindow(MainWindowClassName, NULL);
 | 
			
		||||
    
 | 
			
		||||
    if(!selectorMainWindow){
 | 
			
		||||
        MessageBox(NULL, message, title, 
 | 
			
		||||
                   MB_ICONWARNING);
 | 
			
		||||
        return;
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    wchar_t data[2048];
 | 
			
		||||
    wcscpy(data, message);
 | 
			
		||||
    data[wcslen(message)]=0;
 | 
			
		||||
    wcscpy(data+wcslen(message)+1, title);
 | 
			
		||||
    
 | 
			
		||||
    size_t dataLen=wcslen(message)+wcslen(title)+1;
 | 
			
		||||
    
 | 
			
		||||
    COPYDATASTRUCT info;
 | 
			
		||||
    info.dwData=DataTypeAlertWarning;
 | 
			
		||||
    info.cbData=dataLen*sizeof(wchar_t);
 | 
			
		||||
    
 | 
			
		||||
    HGLOBAL global=GlobalAlloc(GPTR, info.cbData);
 | 
			
		||||
    memcpy((LPVOID)global, data, info.cbData);
 | 
			
		||||
    
 | 
			
		||||
    info.lpData=(LPVOID)global;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    SendMessage(selectorMainWindow, WM_COPYDATA, NULL,
 | 
			
		||||
                (LPARAM)&info);
 | 
			
		||||
    
 | 
			
		||||
    GlobalFree(global);
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR lpCmd, int nShow){
 | 
			
		||||
    HINSTANCE lib=LoadLibrary(L"BrainLILO");
 | 
			
		||||
	if(!lib){
 | 
			
		||||
		wchar_t buf[256];
 | 
			
		||||
		swprintf(buf, L"Cannot perform a soft reset.\n"
 | 
			
		||||
				L"BrainLILO was not loaded (0x%08x).",
 | 
			
		||||
				GetLastError());
 | 
			
		||||
        showAlertWarning(buf, L"Error");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    typedef BOOL (*RKDoSoftResetProc)();
 | 
			
		||||
    RKDoSoftResetProc RKDoSoftReset=
 | 
			
		||||
    (RKDoSoftResetProc)GetProcAddress(lib, L"RKDoSoftReset");
 | 
			
		||||
    if(!RKDoSoftReset){
 | 
			
		||||
        wchar_t buf[256];
 | 
			
		||||
		swprintf(buf, L"Cannot perform a soft reset.\n"
 | 
			
		||||
                 L"RKDoSoftReset not found (0x%08x).",
 | 
			
		||||
                 GetLastError());
 | 
			
		||||
        showAlertWarning(buf, L"Error");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(!RKDoSoftReset()){
 | 
			
		||||
        wchar_t buf[256];
 | 
			
		||||
		swprintf(buf, L"Cannot perform a soft reset.\n"
 | 
			
		||||
                 L"Operation failed (0x%08x).",
 | 
			
		||||
                 GetLastError());
 | 
			
		||||
        showAlertWarning(buf, L"Error");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user