Skip to content

Commit 8a8229b

Browse files
committed
Fix relocations, task PD setup & constants
1 parent 5729a65 commit 8a8229b

11 files changed

Lines changed: 159 additions & 92 deletions

File tree

kernel/inc/shared/memory/constants.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838

3939

4040
// TODO new constants
41-
#define G_MEM_LOWER_END 0x0000000000100000
42-
#define G_MEM_LOWER_HALF_END 0x00007fffffffffff
41+
#define G_MEM_LOWER_END 0x100000
42+
#define G_MEM_LOWER_HALF_END 0x7fffffffffff
4343

4444
/**
4545
* Due to the Higher Half Direct Map feature, every physical address is mapped
@@ -48,11 +48,11 @@
4848
#define G_MEM_HIGHER_HALF_DIRECT_MAP_OFFSET 0xffff800000000000
4949
#define G_MEM_PHYS_TO_VIRT(phys) ((G_MEM_HIGHER_HALF_DIRECT_MAP_OFFSET) + (g_address) phys)
5050

51-
#define G_MEM_KERN_VIRT_RANGES_START 0x00000009f0000000
52-
#define G_MEM_KERN_VIRT_RANGES_END 0x00000009ffc00000
53-
#define G_MEM_HEAP_START 0x0000000a00000000
54-
#define G_MEM_HEAP_INITIAL_SIZE 0x0000000000100000
55-
#define G_KERNEL_HEAP_EXPAND_STEP 0x0000000000100000
51+
#define G_MEM_KERN_VIRT_RANGES_START 0xffffff8090000000
52+
#define G_MEM_KERN_VIRT_RANGES_END 0xffffff89ffc00000
53+
#define G_MEM_HEAP_START 0xffffff8a00000000
54+
#define G_MEM_HEAP_INITIAL_SIZE 0x100000
55+
#define G_MEM_KERN_HEAP_EXPAND_STEP 0x100000
5656

5757

5858
#endif

kernel/inc/shared/memory/paging.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
#define G_PDPT_INDEX(addr) (((addr) >> 30) & 0x1FF)
5050
#define G_PD_INDEX(addr) (((addr) >> 21) & 0x1FF)
5151
#define G_PT_INDEX(addr) (((addr) >> 12) & 0x1FF)
52+
#define G_PML4_VIRT_ADDRESS(pml4, pdpt, pd, pt) \
53+
((((uint64_t)(pml4) << 39) | ((uint64_t)(pdpt) << 30) | ((uint64_t)(pd) << 21) | ((uint64_t)(pt) << 12)) | \
54+
((((uint64_t)(pml4) & 0x100) ? 0xFFFF000000000000ULL : 0)))
5255

5356
/**
5457
* Switches to the given page directory.

kernel/src/kernel/memory/gdt.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ void gdtInitializeLocal()
5353
_gdtWriteEntry(&localGdt->entry[0], 0, 0, 0, 0);
5454

5555
// Kernel code segment descriptor, position 0x08
56-
_gdtWriteEntry(&localGdt->entry[1], 0, 0, G_ACCESS_BYTE__KERNEL_CODE_SEGMENT,
56+
_gdtWriteEntry(&localGdt->entry[1], 0, 0xFFFFFFFF, G_ACCESS_BYTE__KERNEL_CODE_SEGMENT,
5757
G_GDT_GRANULARITY_4KB | G_GDT_GRANULARITY_64BIT);
5858

5959
// Kernel data segment descriptor, position 0x10
60-
_gdtWriteEntry(&localGdt->entry[2], 0, 0, G_ACCESS_BYTE__KERNEL_DATA_SEGMENT,
60+
_gdtWriteEntry(&localGdt->entry[2], 0, 0xFFFFFFFF, G_ACCESS_BYTE__KERNEL_DATA_SEGMENT,
6161
G_GDT_GRANULARITY_4KB | G_GDT_GRANULARITY_64BIT);
6262

6363
// User code segment descriptor, position 0x18
64-
_gdtWriteEntry(&localGdt->entry[3], 0, 0, G_ACCESS_BYTE__USER_CODE_SEGMENT,
64+
_gdtWriteEntry(&localGdt->entry[3], 0, 0xFFFFFFFF, G_ACCESS_BYTE__USER_CODE_SEGMENT,
6565
G_GDT_GRANULARITY_4KB | G_GDT_GRANULARITY_64BIT);
6666

6767
// User data segment descriptor, position 0x20
68-
_gdtWriteEntry(&localGdt->entry[4], 0, 0, G_ACCESS_BYTE__USER_DATA_SEGMENT,
68+
_gdtWriteEntry(&localGdt->entry[4], 0, 0xFFFFFFFF, G_ACCESS_BYTE__USER_DATA_SEGMENT,
6969
G_GDT_GRANULARITY_4KB | G_GDT_GRANULARITY_64BIT);
7070

7171
// TSS descriptor, position 0x28

kernel/src/kernel/memory/heap.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ uint32_t heapGetUsedAmount()
123123

124124
bool _heapExpand()
125125
{
126-
for(g_virtual_address virt = heapEnd; virt < heapEnd + G_KERNEL_HEAP_EXPAND_STEP; virt += G_PAGE_SIZE)
126+
for(g_virtual_address virt = heapEnd; virt < heapEnd + G_MEM_KERN_HEAP_EXPAND_STEP; virt += G_PAGE_SIZE)
127127
{
128128
g_physical_address phys = memoryPhysicalAllocate(true);
129129
if(phys == 0)
@@ -135,8 +135,8 @@ bool _heapExpand()
135135
pagingMapPage(virt, phys, G_PAGE_TABLE_KERNEL_DEFAULT, G_PAGE_KERNEL_DEFAULT);
136136
}
137137

138-
memoryAllocatorExpand(&heapAllocator, G_KERNEL_HEAP_EXPAND_STEP);
139-
heapEnd += G_KERNEL_HEAP_EXPAND_STEP;
138+
memoryAllocatorExpand(&heapAllocator, G_MEM_KERN_HEAP_EXPAND_STEP);
139+
heapEnd += G_MEM_KERN_HEAP_EXPAND_STEP;
140140

141141
logDebug("%! expanded to end %h (%ikb in use)", "kernheap", heapEnd, heapAmountInUse / 1024);
142142

kernel/src/kernel/memory/memory.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,10 @@
3131

3232
g_address_range_pool* memoryVirtualRangePool = nullptr;
3333

34-
// TODO Not sure why this is necessary. Why are kernel pages mapped with user flag initially?
35-
void pagingRemoveUserPermissions()
36-
{
37-
auto pml4 = (g_address*) G_MEM_PHYS_TO_VIRT(pagingGetCurrentSpace());
38-
for(int i = 0; i < 512; i++)
39-
{
40-
if(pml4[i])
41-
pml4[i] &= ~G_PAGE_USER_FLAG;
42-
}
43-
}
44-
4534
void memoryInitialize(limine_memmap_response* memoryMap)
4635
{
4736
logInfo("%! initializing kernel memory with map at %x", "mem", memoryMap);
4837

49-
logInfo("%! initial data", "paging");
50-
pagingRemoveUserPermissions();
51-
5238
bitmapPageAllocatorInitialize(&memoryPhysicalAllocator, memoryMap);
5339
logInfo("%! available: %i MiB", "memory", (memoryPhysicalAllocator.freePageCount * G_PAGE_SIZE) / 1024 / 1024);
5440

kernel/src/kernel/system/interrupts/exceptions.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void exceptionsDumpState(g_task* task, volatile g_processor_state* state)
166166
bool exceptionsHandlePageFault(g_task* task, volatile g_processor_state* state)
167167
{
168168
g_virtual_address accessed = exceptionsGetCR2();
169-
g_physical_address physPage = pagingVirtualToPhysical(G_PAGE_ALIGN_DOWN(accessed));
169+
g_physical_address pageEntryValue = pagingVirtualToPageEntry(G_PAGE_ALIGN_DOWN(accessed));
170170

171171
if(task)
172172
{
@@ -176,8 +176,8 @@ bool exceptionsHandlePageFault(g_task* task, volatile g_processor_state* state)
176176
if(memoryOnDemandHandlePageFault(task, accessed))
177177
return true;
178178

179-
logInfo("%! (task %i, core %i) RIP: %x (accessed %h, mapped page %h)", "pagefault", task->id,
180-
processorGetCurrentId(), state->rip, accessed, physPage);
179+
logInfo("%! (task %i, core %i) RIP: %x (accessed %h, mapping value: %h)", "pagefault", task->id,
180+
processorGetCurrentId(), state->rip, accessed, pageEntryValue);
181181

182182
exceptionsDumpState(task, state);
183183

@@ -194,8 +194,8 @@ bool exceptionsHandlePageFault(g_task* task, volatile g_processor_state* state)
194194
return true;
195195
}
196196

197-
logInfo("%! RIP: %x (accessed %h, mapped page %h)", "pagefault", processorGetCurrentId(), state->rip, accessed,
198-
physPage);
197+
logInfo("%! RIP: %x (accessed %h, mapping value: %h)", "pagefault", processorGetCurrentId(), state->rip, accessed,
198+
pageEntryValue);
199199
return false;
200200
}
201201

kernel/src/kernel/tasking/elf/elf_object.cpp

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,9 @@ void elfObjectApplyRelocations(g_fd file, g_elf_object* object)
349349

350350
// Symbol lookup
351351
if(type == R_X86_64_32 || type == R_X86_64_PC32 ||
352-
type == R_X86_64_GLOB_DAT || type == R_X86_64_JMP_SLOT ||
353-
type == R_X86_64_GOT32 || type == R_X86_64_TLS_TPOFF ||
354-
type == R_X86_64_TLS_DTPMOD32 || type == R_X86_64_TLS_DTPOFF32 ||
352+
type == R_X86_64_GLOB_DAT || type == R_X86_64_JUMP_SLOT ||
353+
type == R_X86_64_GOT32 || type == R_X86_64_TPOFF64 ||
354+
type == R_X86_64_DTPMOD64 || type == R_X86_64_DTPOFF64 ||
355355
type == R_X86_64_COPY)
356356
{
357357
Elf64_Sym* symbol = &object->dynamicSymbolTable[symbolIndex];
@@ -401,59 +401,65 @@ void elfObjectApplyRelocations(g_fd file, g_elf_object* object)
401401
if(type == R_X86_64_32)
402402
{
403403
int32_t cA = *((int32_t*) cP);
404-
*((uint32_t*) cP) = cS + cA;
404+
*((uint32_t*) cP) = (uint32_t) (cS + cA);
405405
}
406406
else if(type == R_X86_64_PC32)
407407
{
408408
int32_t cA = *((int32_t*) cP);
409-
*((uint32_t*) cP) = cS + cA - cP;
409+
*((uint32_t*) cP) = (uint32_t) ((uint64_t) cS + cA - (uint64_t) cP);
410410
}
411411
else if(type == R_X86_64_COPY)
412412
{
413413
if(cS)
414414
memoryCopy((void*) cP, (void*) cS, symbolSize);
415415
}
416-
else if(type == R_X86_64_GLOB_DAT)
416+
else if(type == R_X86_64_GLOB_DAT || type == R_X86_64_JUMP_SLOT)
417417
{
418-
*((uint32_t*) cP) = cS;
419-
}
420-
else if(type == R_X86_64_JMP_SLOT)
421-
{
422-
*((uint32_t*) cP) = cS;
418+
*((uint64_t*) cP) = cS;
423419
}
424420
else if(type == R_X86_64_RELATIVE)
425421
{
426-
uint32_t cB = object->baseAddress;
422+
uint64_t cB = object->baseAddress;
427423
int32_t cA = *((int32_t*) cP);
428-
*((uint32_t*) cP) = cB + cA;
424+
*((uint64_t*) cP) = cB + cA;
425+
}
426+
else if(type == R_X86_64_64)
427+
{
428+
int64_t cA = *((int64_t*) cP);
429+
*((uint64_t*) cP) = cS + cA;
429430
}
430-
else if(type == R_X86_64_TLS_TPOFF)
431+
else if(type == R_X86_64_TPOFF64)
431432
{
432-
/**
433-
* For TLS_TPOFF we insert the offset relative to the g_user_threadlocal which is put
434-
* into the segment referenced in GS.
435-
*/
436433
if(cS)
437-
*((uint32_t*) cP) = symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
434+
*((uint64_t*) cP) = symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
438435
symbolInfo.value;
439436
}
440-
else if(type == R_X86_64_TLS_DTPMOD32)
437+
else if(type == R_X86_64_TPOFF32)
441438
{
442-
/**
443-
* DTPMOD32 expects the module ID to be written which will be passed to ___tls_get_addr.
444-
*/
445439
if(cS)
446-
*((uint32_t*) cP) = symbolInfo.object->id;
440+
*((uint32_t*) cP) = (uint32_t) (
441+
symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
442+
symbolInfo.value);
447443
}
448-
else if(type == R_X86_64_TLS_DTPOFF32)
444+
else if(type == R_X86_64_DTPMOD64)
449445
{
450-
/**
451-
* DTPOFF32 expects the symbol offset to be written which will be passed to ___tls_get_addr.
452-
*/
453446
if(cS)
454-
*((uint32_t*) cP) = symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
447+
*((uint64_t*) cP) = symbolInfo.object->id;
448+
}
449+
else if(type == R_X86_64_DTPOFF64)
450+
{
451+
if(cS)
452+
*((uint64_t*) cP) = symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
455453
symbolInfo.value;
456454
}
455+
else if(type == R_X86_64_DTPOFF32)
456+
{
457+
if(cS)
458+
*((uint32_t*) cP) = (uint32_t) (
459+
symbolInfo.object->tlsPart.offset - rootObject->tlsMaster.userThreadOffset +
460+
symbolInfo.value);
461+
}
462+
457463

458464
entry++;
459465
}

kernel/src/kernel/tasking/tasking_memory.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void taskingMemoryInitializeUtility(g_task* task)
129129
void taskingMemoryInitializeStacks(g_task* task)
130130
{
131131
// Interrupt stack for ring 3 & VM86 tasks
132-
if(task->securityLevel != G_SECURITY_LEVEL_KERNEL || task->type == G_TASK_TYPE_VM86)
132+
if(task->securityLevel != G_SECURITY_LEVEL_KERNEL)
133133
{
134134
task->interruptStack = taskingMemoryCreateStack(memoryVirtualRangePool, G_PAGE_TABLE_KERNEL_DEFAULT,
135135
G_PAGE_KERNEL_DEFAULT, G_TASKING_MEMORY_INTERRUPT_STACK_PAGES);
@@ -246,10 +246,10 @@ g_physical_address taskingMemoryCreatePageSpace()
246246
g_physical_address newPml4Phys = memoryPhysicalAllocate();
247247
auto newPml4 = (g_address*) G_MEM_PHYS_TO_VIRT(newPml4Phys);
248248

249-
// Copy all kernel privilege mappings
249+
// Copy all higher-level mappings
250250
for(size_t i = 0; i < 512; i++)
251251
{
252-
if((currentPml4[i] & G_PAGE_USER_FLAG) == 0)
252+
if(i >= 256 && currentPml4[i])
253253
newPml4[i] = currentPml4[i];
254254
else
255255
newPml4[i] = 0;
@@ -309,7 +309,8 @@ void taskingMemoryInitializeTls(g_task* task)
309309
// Allocate required virtual range
310310
uint32_t requiredSize = process->tlsMaster.size;
311311
uint32_t requiredPages = G_PAGE_ALIGN_UP(requiredSize) / G_PAGE_SIZE;
312-
if(requiredPages < 1) requiredPages = 1;
312+
if(requiredPages < 1)
313+
requiredPages = 1;
313314

314315
g_virtual_address tlsStart = addressRangePoolAllocate(process->virtualRangePool, requiredPages);
315316
g_virtual_address tlsEnd = tlsStart + requiredPages * G_PAGE_SIZE;

kernel/src/kernel/utils/debug.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "kernel/utils/debug.hpp"
2222
#include "kernel/system/timing/pit.hpp"
2323
#include "shared/logger/logger.hpp"
24+
#include "kernel/memory/paging.hpp"
25+
#include "shared/memory/constants.hpp"
2426

2527
void debugHardSleep(uint64_t millis)
2628
{
@@ -70,3 +72,53 @@ void hexDump64(void* location, int minus, int plus)
7072
{
7173
hexDump(location, minus, plus, 8);
7274
}
75+
76+
void debugDumpPageSpace()
77+
{
78+
logInfo("%! debug logging initial space:", "paging");
79+
auto pml4 = (g_address*) G_MEM_PHYS_TO_VIRT(pagingGetCurrentSpace());
80+
for(int first = 0; first < 512; first++)
81+
{
82+
if(!pml4[first])
83+
continue;
84+
85+
logInfo("%# %i: %h -> %h %s", first, G_PML4_VIRT_ADDRESS(first, 0, 0, 0), pml4[first],
86+
pml4[first] & G_PAGE_USER_FLAG ? "user" :"kernel");
87+
auto pdpt = (g_address*) G_MEM_PHYS_TO_VIRT(G_PAGE_ALIGN_DOWN(pml4[first]));
88+
for(int second = 0; second < 512; second++)
89+
{
90+
if(!pdpt[second])
91+
continue;
92+
93+
logInfo("%# %i > %i: %h -> %h %s", first, second, G_PML4_VIRT_ADDRESS(first, second, 0, 0), pdpt[second],
94+
pdpt[second]& G_PAGE_USER_FLAG ? "user":"kernel");
95+
auto pd = (g_address*) G_MEM_PHYS_TO_VIRT(G_PAGE_ALIGN_DOWN(pdpt[second]));
96+
for(int third = 0; third < 512; third++)
97+
{
98+
if(!pd[third])
99+
continue;
100+
101+
logInfo("%# %i > %i > %i: %h -> %h %s", first, second, third,
102+
G_PML4_VIRT_ADDRESS(first, second, third, 0),
103+
pd[third], pd[third]& G_PAGE_USER_FLAG ? "user":"kernel");
104+
if(pd[third] & G_PAGE_LARGE_PAGE_FLAG)
105+
{
106+
logInfo("%# up to %h", G_PML4_VIRT_ADDRESS(first, second, third, 0) + 0x200000);
107+
}
108+
else
109+
{
110+
auto pt = (g_address*) G_MEM_PHYS_TO_VIRT(G_PAGE_ALIGN_DOWN(pd[third]));
111+
for(int fourth = 0; fourth < 512; fourth++)
112+
{
113+
if(!pt[fourth])
114+
continue;
115+
116+
logInfo("%# %i > %i > %i > %i: %h -> %h %s", first, second, third, fourth,
117+
G_PML4_VIRT_ADDRESS(first, second, third, fourth),
118+
pt[fourth], pt[fourth]& G_PAGE_USER_FLAG ? "user":"kernel");
119+
}
120+
}
121+
}
122+
}
123+
}
124+
}

kernel/src/kernel/utils/debug.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ void hexDump8(void* location, int minus = 0, int plus = 0);
2929

3030
void hexDump64(void* location, int minus = 0, int plus = 0);
3131

32+
void debugDumpPageSpace();
33+
3234
#endif

0 commit comments

Comments
 (0)