singrdk/base/boot/SingLdrPc/bllrbload.c

485 lines
12 KiB
C

//
//
//
#define NULL 0
typedef unsigned char byte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned __int64 ulong;
#pragma pack(1)
typedef struct _GDTR {
ushort Limit;
ulong Base;
} GDTR, *PGDTR;
#pragma pack()
static ushort * pVideoBeg = (ushort *)0xb8000;
static ushort * pVideoEnd = (ushort *)0xb8fa0;
static ushort * pCursor;
static ushort wColor;
static byte * pTarget = (byte *) 0x7c00;
static char szHexDigits[] = "0123456789abcdef";
extern ulong BlMmGetCr3(void);
extern void BlMmSetCr3(ulong Value);
extern void BlMmGetGdtr(PGDTR Gdtr);
extern void BlMmSetGdtr(PGDTR Gdtr);
extern ulong BlMmGetRsp(void);
//
// Include: byte lomem_data[];
//
#include <singlrb.cpp>
void PrintChar(char c)
{
if (c == '\n') {
while (((pCursor - pVideoBeg) % 80) != 0) {
*pCursor++ = wColor + ' ';
}
}
else if (c == '\f') {
while (pCursor > pVideoBeg) {
*--pCursor = wColor + ' ';
}
}
else {
*pCursor++ = wColor + c;
}
}
void PrintString(const char * psz)
{
for (; *psz; psz++) {
PrintChar(*psz);
}
}
void PrintHexValueSub(ulong v, int digits)
{
int i;
for (i = 4 * (digits - 1); i >= 0; i -= 4) {
*pCursor++ = wColor + szHexDigits[(v >> i) & 0xf];
}
}
void PrintHex32(uint v)
{
PrintHexValueSub((ulong)v, 8);
}
void PrintHexValue(ulong v)
{
PrintHexValueSub(v, 16);
}
void PrintHexDigit(byte v)
{
*pCursor++ = wColor + szHexDigits[(v >> 4) & 0xf];
*pCursor++ = wColor + szHexDigits[v & 0xf];
}
void PrintDump(byte * data, int size, int pad)
{
for (; size > 0; size--, pad--) {
PrintHexDigit(*data++);
}
for (; pad > 0; pad--) {
PrintString(" ");
}
}
void PrintChars(byte * data, int size, int pad)
{
for (; size > 0; size--, pad--) {
byte b = *data++;
if (b < ' ' || b > 127) {
PrintChar('.');
}
else {
PrintChar((char)b);
}
}
for (; pad > 0; pad--) {
PrintString(" ");
}
}
int FindEntry(const byte *data, int size)
{
const byte * walk = data;
for (; size > 0; size--, walk++) {
if (walk[0] == 'S' && walk[1] == 'I' && walk[2] == 'N' && walk[3] == 'G' &&
walk[4] == 'L' && walk[5] == 'R' && walk[6] == 'B' && walk[7] == 0x00 &&
walk[8] == 0xf8 && walk[9] == 0xf9 && walk[10] == 0xfa && walk[11] == 0xfb &&
walk[12] == 0xfc && walk[13] == 0xfd && walk[14] == 0xfe && walk[15] == 0xff) {
return ((walk + 32) - data);
}
}
return -1;
}
void CopyMemory(byte * target, const byte * data, int size)
{
PrintString("CopyMemory(");
PrintHexValue((ulong)target);
PrintString(",");
PrintHexValue((ulong)data);
PrintString(",");
PrintHexValue((ulong)size);
PrintString(")\n");
for (; size > 0; size--) {
*target++ = *data++;
}
}
void PrintSegment32(ulong seg)
{
PrintString(" ");
PrintHexValueSub(seg >> 56, 2);
PrintHexValueSub(seg >> 16, 6);
PrintString(" ");
PrintHexValueSub(seg >> 48, 1);
PrintHexValueSub(seg >> 0, 4);
PrintString(" ");
PrintHexValueSub(seg >> 52, 1);
PrintString(" ");
PrintHexValueSub(seg >> 40, 2);
}
void PrintSegment64(ulong seg0, ulong seg1)
{
PrintHexValueSub(seg1 >> 0, 8);
PrintHexValueSub(seg0 >> 56, 2);
PrintHexValueSub(seg0 >> 16, 6);
PrintString(" ");
PrintHexValueSub(seg0 >> 48, 1);
PrintHexValueSub(seg0 >> 0, 4);
PrintString(" ");
PrintHexValueSub(seg0 >> 52, 1);
PrintString(" ");
PrintHexValueSub(seg0 >> 40, 2);
}
void * FindModuleInfo(uint *pConfig, uint find, uint * pSize)
{
for (;;) {
uint type = pConfig[0];
uint size = pConfig[1];
void *data = &pConfig[2];
if (type == 0) {
*pSize = 0;
return NULL;
}
if (type == find) {
*pSize = size;
return data;
}
size = (size + 8 + 7) & ~7u;
pConfig = (uint *)(((byte *)pConfig) + size);
}
}
void PrintModuleInfo(uint *pConfig)
{
PrintString("Module Info:\n");
for (;;) {
uint type = pConfig[0];
uint size = pConfig[1];
void *data = &pConfig[2];
if (type == 0) {
break;
}
PrintString(" ");
PrintHex32((uint)pConfig);
PrintString(":");
PrintHex32(type);
PrintString("[");
PrintHex32(size);
PrintString("]:");
PrintDump((byte*)data, size < 16 ? size : 16, 16);
PrintString(" ");
PrintChars((byte*)data, size < 16 ? size : 16, 16);
PrintString("\n");
size = (size + 8 + 7) & ~7u;
pConfig = (uint *)(((byte *)pConfig) + size);
}
}
void __fastcall main(uint *pConfig, uint * pUnknown)
{
int offset;
void (*pStart)(void);
byte * pbSmap;
uint cbSmap;
wColor = 0x4f00;
pCursor = pVideoBeg;
PrintString("Singularity Reloader " __DATE__ " " __TIME__ "\n");
offset = FindEntry(lomem_data, sizeof(lomem_data));
pStart = (void (*)(void))(pTarget + offset);
PrintString("pConfig = ");
PrintHexValue((ulong)pConfig);
PrintString("\n");
PrintString("pUnknown = ");
PrintHexValue((ulong)pUnknown);
PrintString("\n");
PrintString(" ");
PrintDump((byte*)pUnknown, 16, 16);
PrintString(" ");
PrintChars((byte*)pUnknown, 16, 16);
PrintString("\n");
PrintString("pTarget = ");
PrintHexValue((ulong)pTarget);
PrintString("..");
PrintHexValue((ulong)(pTarget + sizeof(lomem_data)));
PrintString("\n");
// PrintModuleInfo(pConfig);
#if 0
PrintString("lomem = ");
PrintHexValue((ulong)lomem_data);
PrintString("..");
PrintHexValue((ulong)(lomem_data + sizeof(lomem_data)));
PrintString("\n");
#endif
#if 0
{
ulong cr3;
ulong *p;
GDTR gdt;
cr3 = BlMmGetCr3();
PrintString("cr3 = ");
PrintHexValue((ulong)cr3);
PrintString("\n");
p = (ulong *)cr3;
PrintString("cr3.0 = ");
PrintHexValue((ulong)p[0]);
PrintString(" ");
PrintHexValue((ulong)p[1]);
PrintString(" ");
PrintHexValue((ulong)p[2]);
PrintString(" ");
PrintHexValue((ulong)p[3]);
PrintString("\n");
p = (ulong *)(p[0] & 0xfffffffffffff000);
PrintString("cr3.0.0 = ");
PrintHexValue((ulong)p[0]);
PrintString(" ");
PrintHexValue((ulong)p[1]);
PrintString(" ");
PrintHexValue((ulong)p[2]);
PrintString(" ");
PrintHexValue((ulong)p[3]);
PrintString("\n");
p = (ulong *)(p[0] & 0xfffffffffffff000);
PrintString("cr3.0.0.0 = ");
PrintHexValue((ulong)p[0]);
PrintString(" ");
PrintHexValue((ulong)p[1]);
PrintString(" ");
PrintHexValue((ulong)p[2]);
PrintString(" ");
PrintHexValue((ulong)p[3]);
PrintString("\n");
p = (ulong *)cr3;
p = (ulong *)(p[0] & 0xfffffffffffff000);
p = (ulong *)(p[3] & 0xfffffffffffff000);
PrintString("cr3.0.3.0 = ");
PrintHexValue((ulong)p[0]);
PrintString(" ");
PrintHexValue((ulong)p[1]);
PrintString(" ");
PrintHexValue((ulong)p[2]);
PrintString(" ");
PrintHexValue((ulong)p[3]);
PrintString("\n");
BlMmGetGdtr(&gdt);
#if 0
PrintString("gdt = ");
PrintHexValue((ulong)gdt.Base);
PrintString("..");
PrintHexValue((ulong)gdt.Limit);
PrintString("\n");
#endif
p = (ulong *)gdt.Base;
PrintString("gdt.1 = ");
PrintSegment32(p[1]);
PrintString(" : ");
PrintSegment64(p[1],p[2]);
PrintString("\n");
PrintString("gdt.2 = ");
PrintSegment32(p[2]);
PrintString(" : ");
PrintSegment64(p[2],p[3]);
PrintString("\n");
PrintString("gdt.3 = ");
PrintSegment32(p[3]);
PrintString(" : ");
PrintSegment64(p[3],p[4]);
PrintString("\n");
PrintString("gdt.4 = ");
PrintSegment32(p[4]);
PrintString(" : ");
PrintSegment64(p[4],p[5]);
PrintString("\n");
PrintString("gdt.5 = ");
PrintSegment32(p[5]);
PrintString(" : ");
PrintSegment64(p[5],p[6]);
PrintString("\n");
PrintString("gdt.6 = ");
PrintSegment32(p[6]);
PrintString(" : ");
PrintSegment64(p[6],p[7]);
PrintString("\n");
PrintString("gdt.7 = ");
PrintSegment32(p[7]);
PrintString(" : ");
PrintSegment64(p[7],p[8]);
PrintString("\n");
PrintString("gdt.8 = ");
PrintSegment32(p[8]);
PrintString(" : ");
PrintSegment64(p[8],p[9]);
PrintString("\n");
PrintString("gdt.9 = ");
PrintSegment32(p[9]);
PrintString(" : ");
PrintSegment64(p[9],p[10]);
PrintString("\n");
PrintString("gdt.a = ");
PrintSegment32(p[10]);
PrintString(" : ");
PrintSegment64(p[10],p[11]);
PrintString("\n");
}
#endif
CopyMemory(pTarget, lomem_data, sizeof(lomem_data));
pbSmap = (byte *)FindModuleInfo(pConfig, 0x9001, &cbSmap);
if (pbSmap != NULL) {
byte * pnew = (byte *)0x1000;
CopyMemory(pnew, pbSmap, cbSmap);
pbSmap = pnew;
}
for (offset = 0; offset < cbSmap; offset += 20) {
PrintString(" SMAP[");
PrintHexDigit((byte)(offset / 20));
PrintString("] ");
PrintHexValue(((ulong *)(pbSmap + offset + 0))[0]);
PrintString(" x ");
PrintHexValue(((ulong *)(pbSmap + offset + 8))[0]);
PrintString(" ");
PrintHex32(((uint *)(pbSmap + offset + 16))[0]);
PrintString("\n");
}
((uint *)pStart)[-4] = 0x600000;
((uint *)pStart)[-3] = (uint)pbSmap;
((uint *)pStart)[-2] = cbSmap;
PrintString("pbSmap = ");
PrintHexValue((ulong)pbSmap);
PrintString("\n");
PrintString("pTarget = ");
PrintHexValue((ulong)pTarget);
PrintString(" [");
PrintDump((byte *)pTarget, 16, 16);
PrintString("]\n");
PrintString("pStart = ");
PrintHexValue((ulong)(pStart));
PrintString(" [");
PrintDump((byte *)pStart, 16, 16);
PrintString("]\n");
#if 0
{
byte * pb = (byte *)0x600000;
int bad = 0;
int i;
PrintString("Scanning:\n");
for (i = 0; i < 0x800000; i++) {
if (pb[i] != 0xee) {
PrintString(" ");
PrintHexValue((ulong)i);
PrintString(": ");
PrintDump(pb, i, 16);
PrintString("\n");
i += 16;
bad++;
if (bad > 20) {
for (;;);
}
}
}
}
#endif
#if 0
PrintString("Test1\n");
{
uint target = 0x500000;
uint offset;
for (offset = 1; offset < 0x10000000; offset <<= 1) {
PrintString(" ");
PrintHex32(target + offset);
PrintString(" : ");
*((uint *)(target + offset)) = (0xff000000 | offset);
PrintHex32(*((uint *)(target + offset)));
PrintString("\n");
}
}
PrintString("Test2\n");
for(;;);
#endif
pStart();
PrintString("Halt.\n");
for (;;);
// pStart();
}