Fix 32-bit compilation

This commit is contained in:
Alex
2023-08-23 16:59:21 +03:00
parent 8898791257
commit bef0897442
58 changed files with 4419 additions and 3418 deletions

View File

@@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global DetectCPUID
DetectCPUID:

View File

@@ -16,7 +16,7 @@
*/
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.align 32
.global gdtr

View File

@@ -16,7 +16,7 @@
*/
.code64
.section .bootstrap.data
.section .bootstrap.data, "a"
/* Access bits */
A = 0x1

View File

@@ -19,7 +19,7 @@
.extern Multiboot2_start
/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */
.section .multiboot2
.section .multiboot2, "a"
.align 0x1000
MULTIBOOT2_HEADER_START:
.long 0xE85250D6

View File

@@ -19,140 +19,140 @@
union __attribute__((packed)) PageTableEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Dirty : 1; // 6
bool PageAttributeTable : 1; // 7
bool Global : 1; // 8
uint8_t Available0 : 3; // 9-11
uint64_t Address : 40; // 12-51
uint32_t Available1 : 7; // 52-58
uint8_t ProtectionKey : 4; // 59-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Dirty : 1; // 6
bool PageAttributeTable : 1; // 7
bool Global : 1; // 8
uint8_t Available0 : 3; // 9-11
uint64_t Address : 40; // 12-51
uint32_t Available1 : 7; // 52-58
uint8_t ProtectionKey : 4; // 59-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageTableEntryPtr
{
PageTableEntry Entries[512];
PageTableEntry Entries[512];
};
union __attribute__((packed)) PageDirectoryEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryEntryPtr
{
PageDirectoryEntry Entries[512];
PageDirectoryEntry Entries[512];
};
union __attribute__((packed)) PageDirectoryPointerTableEntry
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool PageSize : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr
{
PageDirectoryPointerTableEntry Entries[512];
PageDirectoryPointerTableEntry Entries[512];
};
union __attribute__((packed)) PageMapLevel4
{
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool Reserved0 : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
struct
{
bool Present : 1; // 0
bool ReadWrite : 1; // 1
bool UserSupervisor : 1; // 2
bool WriteThrough : 1; // 3
bool CacheDisable : 1; // 4
bool Accessed : 1; // 5
bool Available0 : 1; // 6
bool Reserved0 : 1; // 7
uint8_t Available1 : 4; // 8-11
uint64_t Address : 40; // 12-51
uint32_t Available2 : 11; // 52-62
bool ExecuteDisable : 1; // 63
};
uint64_t raw;
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address)
{
_Address &= 0x000000FFFFFFFFFF;
this->raw &= 0xFFF0000000000FFF;
this->raw |= (_Address << 12);
}
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
__always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; }
};
struct PageTable4
{
PageMapLevel4 Entries[512];
PageMapLevel4 Entries[512];
} __attribute__((aligned(0x1000)));
extern "C" char BootPageTable[];
@@ -163,139 +163,139 @@ __attribute__((section(".bootstrap.data"))) static size_t BPT_Allocated = 0x4000
__always_inline inline SafeFunction NIF void *RequestPage()
{
void *Page = (void *)(BootPageTable + BPT_Allocated);
BPT_Allocated += 0x1000;
if (BPT_Allocated >= 0x10000) /* The length of BootPageTable */
{
while (true)
;
}
return Page;
void *Page = (void *)(BootPageTable + BPT_Allocated);
BPT_Allocated += 0x1000;
if (BPT_Allocated >= 0x10000) /* The length of BootPageTable */
{
while (true)
;
}
return Page;
}
class PageMapIndexer
{
public:
uintptr_t PMLIndex = 0;
uintptr_t PDPTEIndex = 0;
uintptr_t PDEIndex = 0;
uintptr_t PTEIndex = 0;
__always_inline inline SafeFunction NIF PageMapIndexer(uintptr_t VirtualAddress)
{
uintptr_t Address = VirtualAddress;
Address >>= 12;
this->PTEIndex = Address & 0x1FF;
Address >>= 9;
this->PDEIndex = Address & 0x1FF;
Address >>= 9;
this->PDPTEIndex = Address & 0x1FF;
Address >>= 9;
this->PMLIndex = Address & 0x1FF;
}
uintptr_t PMLIndex = 0;
uintptr_t PDPTEIndex = 0;
uintptr_t PDEIndex = 0;
uintptr_t PTEIndex = 0;
__always_inline inline SafeFunction NIF PageMapIndexer(uintptr_t VirtualAddress)
{
uintptr_t Address = VirtualAddress;
Address >>= 12;
this->PTEIndex = Address & 0x1FF;
Address >>= 9;
this->PDEIndex = Address & 0x1FF;
Address >>= 9;
this->PDPTEIndex = Address & 0x1FF;
Address >>= 9;
this->PMLIndex = Address & 0x1FF;
}
};
__attribute__((section(".bootstrap.text"))) SafeFunction NIF void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
{
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
uint64_t DirectoryFlags = Flags & 0x3F;
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
uint64_t DirectoryFlags = Flags & 0x3F;
PageMapLevel4 PML4 = BPTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
if (!PML4.Present)
{
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage();
if (PDPTEPtr == nullptr)
return;
{
void *ptr = PDPTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PML4.Present = true;
PML4.SetAddress((uintptr_t)PDPTEPtr >> 12);
}
else
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
PML4.raw |= DirectoryFlags;
BPTable->Entries[Index.PMLIndex] = PML4;
PageMapLevel4 PML4 = BPTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
if (!PML4.Present)
{
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage();
if (PDPTEPtr == nullptr)
return;
{
void *ptr = PDPTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PML4.Present = true;
PML4.SetAddress((uintptr_t)PDPTEPtr >> 12);
}
else
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
PML4.raw |= DirectoryFlags;
BPTable->Entries[Index.PMLIndex] = PML4;
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
PageDirectoryEntryPtr *PDEPtr = nullptr;
if (!PDPTE.Present)
{
PDEPtr = (PageDirectoryEntryPtr *)RequestPage();
if (PDEPtr == nullptr)
return;
{
void *ptr = PDEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDPTE.Present = true;
PDPTE.SetAddress((uintptr_t)PDEPtr >> 12);
}
else
PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12);
PDPTE.raw |= DirectoryFlags;
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
PageDirectoryEntryPtr *PDEPtr = nullptr;
if (!PDPTE.Present)
{
PDEPtr = (PageDirectoryEntryPtr *)RequestPage();
if (PDEPtr == nullptr)
return;
{
void *ptr = PDEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDPTE.Present = true;
PDPTE.SetAddress((uintptr_t)PDEPtr >> 12);
}
else
PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12);
PDPTE.raw |= DirectoryFlags;
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
PageTableEntryPtr *PTEPtr = nullptr;
if (!PDE.Present)
{
PTEPtr = (PageTableEntryPtr *)RequestPage();
if (PTEPtr == nullptr)
return;
{
void *ptr = PTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDE.Present = true;
PDE.SetAddress((uintptr_t)PTEPtr >> 12);
}
else
PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.GetAddress() << 12);
PDE.raw |= DirectoryFlags;
PDEPtr->Entries[Index.PDEIndex] = PDE;
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
PageTableEntryPtr *PTEPtr = nullptr;
if (!PDE.Present)
{
PTEPtr = (PageTableEntryPtr *)RequestPage();
if (PTEPtr == nullptr)
return;
{
void *ptr = PTEPtr;
uint8_t value = 0;
size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++)
p[i] = value;
}
PDE.Present = true;
PDE.SetAddress((uintptr_t)PTEPtr >> 12);
}
else
PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.GetAddress() << 12);
PDE.raw |= DirectoryFlags;
PDEPtr->Entries[Index.PDEIndex] = PDE;
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
PTE.Present = true;
PTE.raw |= Flags;
PTE.SetAddress((uintptr_t)PhysicalAddress >> 12);
PTEPtr->Entries[Index.PTEIndex] = PTE;
asmv("invlpg (%0)"
:
: "r"(VirtualAddress)
: "memory");
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
PTE.Present = true;
PTE.raw |= Flags;
PTE.SetAddress((uintptr_t)PhysicalAddress >> 12);
PTEPtr->Entries[Index.PTEIndex] = PTE;
asmv("invlpg (%0)"
:
: "r"(VirtualAddress)
: "memory");
}
EXTERNC __attribute__((section(".bootstrap.text"))) SafeFunction NIF __attribute__((section(".bootstrap.text"))) void UpdatePageTable64()
{
BPTable = (PageTable4 *)BootPageTable;
BPTable = (PageTable4 *)BootPageTable;
uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelEnd = (uintptr_t)&_kernel_end;
uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000;
for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000)
{
MB2_64_Map((void *)i, (void *)PhysicalStart, 0x3);
PhysicalStart += 0x1000;
}
uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelEnd = (uintptr_t)&_kernel_end;
uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000;
for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000)
{
MB2_64_Map((void *)i, (void *)PhysicalStart, 0x3);
PhysicalStart += 0x1000;
}
asmv("mov %%cr3, %%rax\n"
"mov %%rax, %%cr3\n"
:
:
: "rax");
asmv("mov %%cr3, %%rax\n"
"mov %%rax, %%cr3\n"
:
:
: "rax");
}

View File

@@ -18,13 +18,13 @@
PAGE_TABLE_SIZE = 0x4
.code32
.section .bootstrap.data
.section .bootstrap.data, "a"
.align 0x1000
.global BootPageTable
BootPageTable:
.space 0x10000 /* 0x4000 bytes will be used in UpdatePageTable */
.section .bootstrap.text
.section .bootstrap.text, "a"
.global UpdatePageTable
UpdatePageTable:
mov $(BootPageTable + 0x0000), %edi /* First PML4E */

View File

@@ -30,14 +30,14 @@ KERNEL_STACK_SIZE = 0x4000 /* 16KB */
.extern GDT64.Code
.extern GDT64.Data
.section .bootstrap.data
.section .bootstrap.data, "a"
MB_HeaderMagic:
.quad 0
MB_HeaderInfo:
.quad 0
.section .bootstrap.text
.section .bootstrap.text, "a"
.global Multiboot2_start
Multiboot2_start:
@@ -113,7 +113,7 @@ HigherHalfStart:
hlt
jmp .Hang
.section .bootstrap.bss
.section .bootstrap.bss, "a"
.align 16
KernelStack:
.space KERNEL_STACK_SIZE