mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 21:55:08 +00:00
Alex Ionescu <ionucu@videotron.ca>
Relocate kernel if the /3GB switch is supplied in kernel parameters. svn path=/trunk/; revision=13941
This commit is contained in:
parent
6cc6c8571b
commit
b6926c02fc
|
@ -164,9 +164,7 @@ FrLdrStartup(ULONG Magic)
|
||||||
/* Re-initalize EFLAGS */
|
/* Re-initalize EFLAGS */
|
||||||
Ke386EraseFlags();
|
Ke386EraseFlags();
|
||||||
|
|
||||||
/* Get Kernel Base and Set MmSystemRangeStart */
|
/* Get the PAE Mode */
|
||||||
FrLdrGetKernelBase();
|
|
||||||
|
|
||||||
FrLdrGetPaeMode();
|
FrLdrGetPaeMode();
|
||||||
|
|
||||||
/* Initialize the page directory */
|
/* Initialize the page directory */
|
||||||
|
@ -531,6 +529,14 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||||
ULONG_PTR TargetSection;
|
ULONG_PTR TargetSection;
|
||||||
ULONG SectionSize;
|
ULONG SectionSize;
|
||||||
LONG i;
|
LONG i;
|
||||||
|
PIMAGE_DATA_DIRECTORY RelocationDDir;
|
||||||
|
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||||
|
ULONG Count;
|
||||||
|
ULONG_PTR Address, MaxAddress;
|
||||||
|
PUSHORT TypeOffset;
|
||||||
|
ULONG_PTR Delta;
|
||||||
|
PUSHORT ShortPtr;
|
||||||
|
PULONG LongPtr;
|
||||||
|
|
||||||
/* Allocate 1024 bytes for PE Header */
|
/* Allocate 1024 bytes for PE Header */
|
||||||
ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
|
ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
|
||||||
|
@ -552,8 +558,9 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||||
/* Now read the MZ header to get the offset to the PE Header */
|
/* Now read the MZ header to get the offset to the PE Header */
|
||||||
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
|
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
|
||||||
|
|
||||||
/* Save the Image Base */
|
/* Get Kernel Base */
|
||||||
KernelBase = NtHeader->OptionalHeader.ImageBase;
|
KernelBase = NtHeader->OptionalHeader.ImageBase;
|
||||||
|
FrLdrGetKernelBase();
|
||||||
|
|
||||||
/* Save Entrypoint */
|
/* Save Entrypoint */
|
||||||
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
|
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
|
||||||
|
@ -604,8 +611,63 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now relocate the file */
|
/* Get the Relocation Data Directory */
|
||||||
/* FIXME: ADD RELOC CODE */
|
RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
|
|
||||||
|
/* Get the Relocation Section Start and End*/
|
||||||
|
RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
|
||||||
|
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
|
||||||
|
|
||||||
|
/* Calculate Difference between Real Base and Compiled Base*/
|
||||||
|
Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
|
||||||
|
|
||||||
|
/* Determine how far we shoudl relocate */
|
||||||
|
MaxAddress = KERNEL_BASE_PHYS + ImageSize;
|
||||||
|
|
||||||
|
/* Relocate until we've processed all the blocks */
|
||||||
|
while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
|
||||||
|
|
||||||
|
/* See how many Relocation Blocks we have */
|
||||||
|
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||||
|
|
||||||
|
/* Calculate the Address of this Directory */
|
||||||
|
Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
|
||||||
|
|
||||||
|
/* Calculate the Offset of the Type */
|
||||||
|
TypeOffset = (PUSHORT)(RelocationDir + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < Count; i++) {
|
||||||
|
|
||||||
|
ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
|
||||||
|
|
||||||
|
/* Don't relocate after the end of the loaded driver */
|
||||||
|
if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
|
||||||
|
|
||||||
|
switch (*TypeOffset >> 12) {
|
||||||
|
|
||||||
|
case IMAGE_REL_BASED_ABSOLUTE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_REL_BASED_HIGH:
|
||||||
|
*ShortPtr += HIWORD(Delta);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_REL_BASED_LOW:
|
||||||
|
*ShortPtr += LOWORD(Delta);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
LongPtr = (PULONG)ShortPtr;
|
||||||
|
*LongPtr += Delta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next Relocation Table */
|
||||||
|
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
|
||||||
|
}
|
||||||
|
|
||||||
/* Increase the next Load Base */
|
/* Increase the next Load Base */
|
||||||
NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
|
NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
|
||||||
|
|
Loading…
Reference in a new issue