diff --git a/MyOS_1/Build_Number.h b/MyOS_1/Build_Number.h
index ce02951..a32aa93 100644
--- a/MyOS_1/Build_Number.h
+++ b/MyOS_1/Build_Number.h
@@ -3,4 +3,4 @@
// Define a build number. This number will be incremented by a simple console program called by a post-build event
// It's put here in its own file to keep the other program from messing up the source
#define \
-BUILD_NUMBER 6507
+BUILD_NUMBER 6605
\ No newline at end of file
diff --git a/MyOS_1/Drivers/Virtio_Net.c b/MyOS_1/Drivers/Virtio_Net.c
index 9231c25..64e818b 100644
--- a/MyOS_1/Drivers/Virtio_Net.c
+++ b/MyOS_1/Drivers/Virtio_Net.c
@@ -12,6 +12,9 @@
#include "../Networking/IPv4.h"
#include "Virtio.h"
#include "../Timers/System_Clock.h"
+#include "../Console_Serial.h"
+#include "../paging.h"
+#include "../Tasks/Context.h"
// TODO: Support multiple NIC's
@@ -301,6 +304,8 @@ void _declspec(naked) VirtIO_Net_InterruptHandler()
bool VirtIO_Net_SharedInterruptHandler(void)
{
+ _disable();
+
if (debugLevel)
terminal_writestring(" --------- virtio-net interrupt fired! -------\n");
@@ -470,6 +475,14 @@ void VirtIO_Net_SendPacket(Ethernet_Header *packet, uint16_t dataSize)
return;
}
+
+ if (/*(uint32_t)(&transmitQueue.descriptors[descIndex2]) == 0x2800000 || (uint32_t)(&transmitQueue.descriptors[descIndex2].address) == 0x2800000
+ ||*/ (uint32_t)packetBuffer == 0x2800000)
+ {
+ //serial_printf("Got em - %s\n", tasks[currentTask].imageName);
+ //Paging_Print_Page_Table(tasks[currentTask].cr3);
+ }
+
memcpy(packetBuffer, packet, dataSize);
// (TODO: malloc returns identity-mapped addresses for now but later we'll need a function to convert virtual to physical)
diff --git a/MyOS_1/Interrupts/Interrupts.c b/MyOS_1/Interrupts/Interrupts.c
index 2a49973..36161c9 100644
--- a/MyOS_1/Interrupts/Interrupts.c
+++ b/MyOS_1/Interrupts/Interrupts.c
@@ -47,6 +47,7 @@ void _declspec(naked) default_interrupt_handler(void)
void _declspec(naked) irq11_shared_interrupt_handler(void)
{
+ _disable();
_asm pushad;
++interrupts_fired;
@@ -73,6 +74,7 @@ void _declspec(naked) irq11_shared_interrupt_handler(void)
void _declspec(naked) irq9_shared_interrupt_handler(void)
{
+ _disable();
_asm pushad;
++interrupts_fired;
diff --git a/MyOS_1/MyOS_1.vcxproj b/MyOS_1/MyOS_1.vcxproj
index 1de4db8..28dc691 100644
--- a/MyOS_1/MyOS_1.vcxproj
+++ b/MyOS_1/MyOS_1.vcxproj
@@ -307,6 +307,7 @@
+
UninitializedLocalUsageCheck
UninitializedLocalUsageCheck
@@ -362,6 +363,7 @@
+
diff --git a/MyOS_1/MyOS_1.vcxproj.filters b/MyOS_1/MyOS_1.vcxproj.filters
index d3813f3..d0dbde9 100644
--- a/MyOS_1/MyOS_1.vcxproj.filters
+++ b/MyOS_1/MyOS_1.vcxproj.filters
@@ -222,6 +222,9 @@
Source Files\Debugging
+
+ Source Files
+
@@ -374,6 +377,9 @@
Header Files\Debugging
+
+ Header Files
+
diff --git a/MyOS_1/Networking/TFTP.c b/MyOS_1/Networking/TFTP.c
index d0b9d4d..144f7e4 100644
--- a/MyOS_1/Networking/TFTP.c
+++ b/MyOS_1/Networking/TFTP.c
@@ -4,6 +4,7 @@
#include "Ethernet.h"
#include "../Drivers/Virtio_Net.h"
#include "../Tasks/Context.h"
+#include "../Console_Serial.h"
// TODO: Support multiple transactions
uint16_t transactionID;
@@ -166,6 +167,7 @@ uint16_t TFTP_RequestFile(uint32_t serverIP, const char *filename, const char *t
// TODO: Seems like Qemu and VirtualBox don't support writing files via TFTP so I can't finish this :(
uint16_t TFTP_WriteFile(uint32_t serverIP, const char *filename, const char *transferMode, uint8_t *sourceMAC)
{
+ return 1235; // Don't even bother
TFTP_RequestHeader *tftpData;
size_t filenameLength = strlen(filename) + 1; // length of filename plus null terminator
size_t transferModeLength = strlen(transferMode) + 1;
@@ -285,6 +287,7 @@ void TFTP_ProcessDataPacket(TFTP_DataHeader *dataPacket, uint16_t sourcePort, ui
}
else
{
+ //serial_printf("tftpTaskIndex: %d, currentTask: %d\n", tftpTaskIndex, currentTask);
// We need to swap out the page directory with the one for the task that requested the file
__writecr3(tasks[tftpTaskIndex].cr3);
diff --git a/MyOS_1/kmisc.c b/MyOS_1/kmisc.c
new file mode 100644
index 0000000..390a173
--- /dev/null
+++ b/MyOS_1/kmisc.c
@@ -0,0 +1,213 @@
+#include "paging.h"
+#include "printf.h"
+#include "Interrupts\System_Calls.h"
+#include "kmisc.h"
+#include "misc.h"
+#include "Console_Serial.h"
+#include "Tasks/Context.h"
+
+// Functions used by the kernel & drivers
+
+// TODO: This might all go out the window in favor of conditionally-compiling misc.c functions; I haven't decided yet.
+
+extern uint32_t memoryNextAvailableAddress;
+extern uint32_t pagedMemoryAvailable;
+
+// TODO: Change this to a more robust scheme (?)
+ALLOCATION_ARRAY kallocationArray = { 0 };
+unsigned int knextAllocationSlot = 0;
+
+// Very, very basic support for freeing memory:
+ALLOCATION_ARRAY kfreeMemoryArray = { 0 };
+unsigned int knextFreeMemorySlot = 0;
+
+#ifdef DEBUG_MEM
+#define noFileName "FILENAME NOT SET";
+char *dbgkMemFilename = noFileName;
+int dbgkMemLineNumber = 0;
+char *dbgkFreeFilename = noFileName;
+int dbgkFreeLineNumber = 0;
+#endif
+
+inline void addAllocationToKFreeMemoryArray(int allocationIndex)
+{
+ // Try to add this memory to the free memory array
+ if (knextFreeMemorySlot == MAX_ALLOCATIONS)
+ {
+ kprintf("NSLFM");
+ return;
+ }
+
+ kfreeMemoryArray.address[knextFreeMemorySlot] = kallocationArray.address[allocationIndex];
+ kfreeMemoryArray.size[knextFreeMemorySlot] = kallocationArray.size[allocationIndex];
+ kfreeMemoryArray.inUse[knextFreeMemorySlot++] = true;
+}
+
+#ifdef DEBUG_MEM
+void *dbg_kmalloc(size_t size, char *filename, int lineNumber)
+{
+ dbgkMemFilename = filename;
+ dbgkMemLineNumber = lineNumber;
+ serial_printf("Allocating %d bytes from %s, line %d for %s\n", size, filename, lineNumber, tasks[currentTask].imageName);
+ return kmalloc(size);
+}
+#endif
+
+// Allocate some kernel memory. Mostly this is meant to be used by drivers.
+// This will be mapped into every tasks page space and will be allocated contiguously
+// TODO: Is it better to have this crazy scheme with the two functions, or just modify malloc to make sure
+// it never reuses user-space memory when called from the kernel?
+
+void* kmalloc(size_t size)
+{
+ if (knextAllocationSlot >= MAX_ALLOCATIONS)
+ {
+ kprintf("Maximum memory allocations exceeded!\n");
+ return NULL;
+ }
+
+#ifdef DEBUG_MEM
+ kallocationArray.lineNumber[knextAllocationSlot] = dbgkMemLineNumber;
+ strncpy(kallocationArray.filename[knextAllocationSlot], dbgkMemFilename, MAX_DEBUG_FILENAME_LENGTH);
+ dbgkMemFilename = noFileName;
+ dbgkMemLineNumber = 0;
+#endif
+
+ // See if there's freed memory available to reallocate (first fit algorithm; memory will end up wasted)
+ for (size_t i = 0; i < knextFreeMemorySlot; ++i)
+ {
+ if (kfreeMemoryArray.size[i] >= size)
+ {
+ // We found a piece of free memory we can reuse
+
+ // Keep track of the memory in our allocations array
+ kallocationArray.address[knextAllocationSlot] = kfreeMemoryArray.address[i];
+ kallocationArray.size[knextAllocationSlot] = kfreeMemoryArray.size[i];
+ kallocationArray.inUse[knextAllocationSlot] = true;
+
+ // We want to keep kfreeMemoryArray from fragmenting, so we'll copy
+ // last used free memory entry of the array to the i position and decrease
+ // the used portion of the array by one
+ --knextFreeMemorySlot;
+ if (knextFreeMemorySlot)
+ {
+ kfreeMemoryArray.address[i] = kfreeMemoryArray.address[knextFreeMemorySlot];
+ kfreeMemoryArray.size[i] = kfreeMemoryArray.size[knextFreeMemorySlot];
+ }
+ // The last entry is no longer in use
+ kfreeMemoryArray.inUse[knextFreeMemorySlot] = false;
+
+#ifdef DEBUG_MEM
+ //printf("Reusing freed memory from slot %d, (reuse #%d)\n", i, ++reuses);
+#endif
+ return (void *)kallocationArray.address[knextAllocationSlot++];
+ }
+ }
+
+ uint32_t availableAddress = memoryNextAvailableAddress;
+
+#ifdef DEBUG_MEM
+ printf("Allocating new %d bytes\n", size);
+#endif
+
+ //if(debugLevel)
+ //printf("size: %d\nadrress: %d\n", size, memoryNextAvailableAddress);
+
+ /*terminal_writestring("Paged memory available: ");
+ terminal_print_int(pagedMemoryAvailable);
+ terminal_newline();*/
+
+ // see if we need to allocate a page
+ if (size > pagedMemoryAvailable)
+ {
+ // TODO: Support dynamic page granularity, not just large pages
+ unsigned int pagesToAllocate = size / FOUR_MEGABYTES;
+
+ // check for remainder from division
+ if (pagesToAllocate * FOUR_MEGABYTES < size)
+ ++pagesToAllocate;
+
+ // Allocate the pages
+ unsigned int pagesAllocated;
+ KPageAllocator(pagesToAllocate, &pagesAllocated, &availableAddress);
+
+ // We need to ensure the pages are in order
+ if (!availableAddress || (pagesAllocated < pagesToAllocate))
+ {
+ kprintf("Returning NULL, %d pages allocated out of %d\n", pagesAllocated, pagesToAllocate);
+ // TODO: Free allocated pages
+ return NULL;
+ }
+
+ // TODO: see if the page we allocated follows the previous page
+ // for now, we'll just ignore the old allocated memory
+ pagedMemoryAvailable = pagesAllocated * FOUR_MEGABYTES;
+
+ memoryNextAvailableAddress = availableAddress;
+ }
+
+ pagedMemoryAvailable -= size;
+ availableAddress = memoryNextAvailableAddress;
+ memoryNextAvailableAddress += size;
+
+ // Keep track of the memory in our allocations array
+ kallocationArray.address[knextAllocationSlot] = availableAddress;
+ kallocationArray.size[knextAllocationSlot] = size;
+ kallocationArray.inUse[knextAllocationSlot++] = true;
+
+ return (void *)availableAddress;
+}
+
+#ifdef DEBUG_MEM
+void dbg_kfree(void *ptr, char *filename, int lineNumber)
+{
+ dbgkFreeFilename = filename;
+ dbgkFreeLineNumber = lineNumber;
+ serial_printf("Freeing mem from %s, line %d for %s\n", filename, lineNumber, tasks[currentTask].imageName);
+ kfree(ptr);
+}
+#endif
+
+void kfree(void *ptr)
+{
+ // Find this pointer in the allocation array
+ for (size_t i = 0; i < knextAllocationSlot; ++i)
+ {
+ if (kallocationArray.address[i] == (uint32_t)ptr)
+ {
+ if (kallocationArray.inUse[i])
+ {
+ addAllocationToKFreeMemoryArray(i);
+
+ // We want to keep the allocation array from being fragmented, so we
+ // copy the final entry in allocation array to the i position and
+ // decrease the size of the allocation array
+ --knextAllocationSlot;
+ if (knextAllocationSlot)
+ {
+ kallocationArray.address[i] = kallocationArray.address[knextAllocationSlot];
+ kallocationArray.size[i] = kallocationArray.size[knextAllocationSlot];
+ }
+
+ kallocationArray.inUse[knextAllocationSlot] = false;
+ }
+ else
+ {
+ kprintf("free() called to free already-freed pointer, 0x%lX\n", ptr);
+ }
+
+ return;
+ }
+ }
+
+ kprintf("free() called with invalid pointer: 0x%lX", ptr);
+#ifdef DEBUG_MEM
+ printf(" from %s, line %d\n", dbgkFreeFilename, dbgkFreeLineNumber);
+ dbgkFreeFilename = noFileName;
+ dbgkFreeLineNumber = 0;
+ //for (;;)
+ // __halt();
+#else
+ kprintf("\n");
+#endif
+}
\ No newline at end of file
diff --git a/MyOS_1/kmisc.h b/MyOS_1/kmisc.h
new file mode 100644
index 0000000..517124d
--- /dev/null
+++ b/MyOS_1/kmisc.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include
+
+void* kmalloc(size_t size);
+void kfree(void *ptr);
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
diff --git a/MyOS_1/main.c b/MyOS_1/main.c
index 4c08f19..8b71859 100644
--- a/MyOS_1/main.c
+++ b/MyOS_1/main.c
@@ -133,7 +133,7 @@ void KeStartupPhase2(multiboot_info *multibootInfo)
//Mouse_Init();
// Execute autoexec.bat (if it exists)
- //Autoexec();
+ Autoexec();
// Say Hello
terminal_writestring("Hello world!\n");
diff --git a/MyOS_1/misc.c b/MyOS_1/misc.c
index 1a26097..b33f4b3 100644
--- a/MyOS_1/misc.c
+++ b/MyOS_1/misc.c
@@ -5,7 +5,9 @@
#include "printf.h"
#include "Interrupts\System_Calls.h"
#include "Interrupts/Interrupts.h"
+#include "Console_Serial.h"
#include
+#include "Tasks/Context.h"
uint32_t pagedMemoryAvailable = 0;
uint32_t memoryNextAvailableAddress = 0;
@@ -63,6 +65,7 @@ void dbg_free(void *ptr, char *filename, int lineNumber)
{
dbgFreeFilename = filename;
dbgFreeLineNumber = lineNumber;
+ serial_printf("Freeing mem from %s, line %d for %s\n", filename, lineNumber, tasks[currentTask].imageName);
free(ptr);
}
#endif
@@ -70,6 +73,10 @@ void dbg_free(void *ptr, char *filename, int lineNumber)
// TODO: Make thread-safe
void free(void *ptr)
{
+#ifdef MYOS_KERNEL
+ kfree(ptr);
+ return;
+#else
// Find this pointer in the allocation array
for (size_t i = 0; i < nextAllocationSlot; ++i)
{
@@ -110,6 +117,8 @@ void free(void *ptr)
#else
printf("\n");
#endif
+
+#endif // MYOS_KERNEL
}
char intToChar(int i)
@@ -121,6 +130,7 @@ char intToChar(int i)
}
// TODO: Test
+// TODO: Handle kernel-mode
void* realloc(void* ptr, size_t size)
{
if (!ptr)
@@ -128,6 +138,10 @@ void* realloc(void* ptr, size_t size)
void *ptrNew = malloc(size);
+#ifdef MYOS_KERNEL
+ serial_printf("realloc called\n");
+#endif
+
// Find ptr in allocation array
int index;
for (index = 0; index < MAX_ALLOCATIONS; ++index)
@@ -375,6 +389,7 @@ void *dbg_malloc(size_t size, char *filename, int lineNumber)
{
dbgMemFilename = filename;
dbgMemLineNumber = lineNumber;
+ serial_printf("Allocating %d bytes from %s, line %d for %s\n", size, filename, lineNumber, tasks[currentTask].imageName);
return malloc(size);
}
#endif
@@ -382,6 +397,9 @@ void *dbg_malloc(size_t size, char *filename, int lineNumber)
unsigned int reuses = 0;
void* malloc(size_t size)
{
+#ifdef MYOS_KERNEL
+ return kmalloc(size);
+#else
if (nextAllocationSlot >= MAX_ALLOCATIONS)
{
printf("Maximum memory allocations exceeded!\n");
@@ -397,7 +415,8 @@ void* malloc(size_t size)
// See if there's freed memory available to reallocate (first fit algorithm; memory will end up wasted)
- for(size_t i = 0; i < nextFreeMemorySlot; ++i)
+ // TODO: We have to guarantee that if we're calling this from the kernel, we don't try to reuse memory mapped to user space
+ for (size_t i = 0; i < nextFreeMemorySlot; ++i)
{
if (freeMemoryArray.size[i] >= size)
{
@@ -464,9 +483,9 @@ void* malloc(size_t size)
// So we can guarantee the pages will be allocated in order. (TODO: Now that I think of it, this logic should maybe be in PageAllocator?)
/*while (pagesToAllocate)
{
- unsigned int pagesAllocated;
- PageAllocator(pagesToAllocate, &pagesAllocated);
- pagesToAllocate -= pagesAllocated;
+ unsigned int pagesAllocated;
+ PageAllocator(pagesToAllocate, &pagesAllocated);
+ pagesToAllocate -= pagesAllocated;
}*/
unsigned int pagesAllocated;
@@ -503,6 +522,8 @@ void* malloc(size_t size)
allocationArray.inUse[nextAllocationSlot++] = true;
return (void *)availableAddress;
+
+#endif // MYOS_KERNEL
}
#pragma function(memcmp)
diff --git a/MyOS_1/misc.h b/MyOS_1/misc.h
index 4ab9a94..43fb739 100644
--- a/MyOS_1/misc.h
+++ b/MyOS_1/misc.h
@@ -7,7 +7,11 @@ extern "C" {
#include
#include
-//#define DEBUG_MEM
+#ifdef MYOS_KERNEL
+#include "kmisc.h"
+#endif
+
+#define DEBUG_MEM
#ifdef DEBUG_MEM
#define MAX_DEBUG_FILENAME_LENGTH 24
@@ -82,13 +86,23 @@ int strcasecmp(const char *s1, const char *s2);
int __cdecl strcmp(const char *str1, const char *str2);
#pragma intrinsic(strcmp)
-#ifdef DEBUG_MEM
-// TODO: Not thread safe, but it probably doesn't matter
-#define dbg_alloc(sz) dbg_malloc(sz, __FILE__, __LINE__)
-#define dbg_release(ptr) dbg_free(ptr, __FILE__, __LINE__)
+#ifdef MYOS_KERNEL
+ #ifdef DEBUG_MEM
+ // TODO: Not thread safe, but it probably doesn't matter
+ #define dbg_alloc(sz) dbg_kmalloc(sz, __FILE__, __LINE__)
+ #define dbg_release(ptr) dbg_kfree(ptr, __FILE__, __LINE__)
+ #else
+ #define dbg_alloc(sz) kmalloc(sz)
+ #define dbg_release(ptr) kfree(ptr)
+ #endif
#else
-#define dbg_alloc(sz) malloc(sz)
-#define dbg_release(ptr) free(ptr)
+ #ifdef DEBUG_MEM
+ #define dbg_alloc(sz) dbg_malloc(sz, __FILE__, __LINE__)
+ #define dbg_release(ptr) dbg_free(ptr, __FILE__, __LINE__)
+ #else
+ #define dbg_alloc(sz) malloc(sz)
+ #define dbg_release(ptr) free(ptr)
+ #endif
#endif
void *malloc(size_t size);
diff --git a/MyOS_1/paging.c b/MyOS_1/paging.c
index ec37dc1..07b1532 100644
--- a/MyOS_1/paging.c
+++ b/MyOS_1/paging.c
@@ -4,6 +4,7 @@
#include
#include "Interrupts/System_Calls.h"
#include "Tasks/Context.h"
+#include "Console_Serial.h"
// Allocate space for paging structures. We need enough space for three arrays with 0x1000 32-bit entries each.
// Each array must be aligned on a 0x1000-byte boundary.
@@ -14,8 +15,10 @@ uint32_t paging_space[0x3FFF];
uint32_t *pageDir;
-uint32_t pagingNextAvailableMemory; // physical address of the next available page
-uint32_t paging4MPagesAvailable; // number of 4M physical memory pages available to be mapped
+uint32_t pagingNextAvailableMemory; // physical address of the next available page
+uint32_t pagingNextAvailableKernelPage; // The index into the page directory where the next kernel page can go
+uint32_t pagingKernelNonPagedArea; // A page (4MiB) of non-paged, identity-mapped memory drivers can use (non-paged pool)
+uint32_t paging4MPagesAvailable; // number of 4M physical memory pages available to be mapped
uint32_t nextPageDirectory; // TEMPTEMP where the next created page directory will be stored
@@ -49,13 +52,27 @@ void KPageAllocator(unsigned int pages, unsigned int *pPagesAllocated, uint32_t
// limit the number of pages to allocate to the number available.
if (pages > paging4MPagesAvailable)
- pages = paging4MPagesAvailable;
+ {
+ // pages = paging4MPagesAvailable;
+ // NOPE: kmalloc expects all pages to be allocated
+ kprintf("Too few pages available to satisfy request\n");
+ return;
+ }
/*terminal_writestring("Need to allocate ");
terminal_print_int(pages);
terminal_writestring(" pages.\n");*/
- uint32_t nextPage = pagingNextAvailableMemory / FOUR_MEGABYTES;
+ uint32_t nextPage = /*pagingNextAvailableKernelPage;// */pagingNextAvailableMemory / FOUR_MEGABYTES;
+ uint32_t physicalAddress = pagingNextAvailableMemory;
+
+ // sanity check
+ if ((physicalAddress & PAGING_ADDRESS_BITS) != physicalAddress)
+ {
+ kprintf("Physical address does not lie on a 4M boundary!\nSystem halted.\n");
+ for (;;)
+ __halt();
+ }
// Get the page directory we'll be using
PAGE_DIRECTORY_ENTRY *pageDirectory = (PAGE_DIRECTORY_ENTRY *)tasks[currentTask].cr3;
@@ -64,26 +81,36 @@ void KPageAllocator(unsigned int pages, unsigned int *pPagesAllocated, uint32_t
for (size_t allocated = 0; allocated < pages; ++allocated)
{
// Add the current page to the page directory
- pageDirectory[nextPage] = ((nextPage * FOUR_MEGABYTES)
+ pageDirectory[nextPage] = ((physicalAddress)
| DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_USER_ACCESSIBLE | DIRECTORY_ENTRY_WRITABLE | DIRECTORY_ENTRY_4MB);
- // If we're mapping this into the kernel space, we need to copy that mapping into every running task
- if (pageDirectory == pageDir)
+ // Since we're mapping this into the kernel space, we need to copy that mapping into every running task
+ //if (pageDirectory == pageDir)
{
for (int i = 0; i < MAX_TASKS; ++i)
{
- if (!tasks[i].inUse || tasks[i].cr3 == (uint32_t)pageDir)
+ if (!tasks[i].inUse || tasks[i].cr3 == (uint32_t)pageDirectory)
continue;
PAGE_DIRECTORY_ENTRY *otherPageDir = (PAGE_DIRECTORY_ENTRY *)tasks[i].cr3;
- otherPageDir[nextPage] = ((nextPage * FOUR_MEGABYTES)
+ // make sure we aren't overwriting the app's mapping (TODO: not sure how we are guaranteeing that we won't)
+ if ((otherPageDir[nextPage] & DIRECTORY_ENTRY_PRESENT) == DIRECTORY_ENTRY_PRESENT)
+ {
+ kprintf("Tried to overwrite page mapping of %s at 0x%X\nSystem halted.\n", tasks[i].imageName, nextPage * FOUR_MEGABYTES);
+ for (;;)
+ __halt();
+ // TODO: How should this be handled?
+ }
+
+ otherPageDir[nextPage] = ((physicalAddress)
| DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_USER_ACCESSIBLE | DIRECTORY_ENTRY_WRITABLE | DIRECTORY_ENTRY_4MB);
}
}
// update pointers and stuff
++nextPage;
+ ++pagingNextAvailableKernelPage;
--paging4MPagesAvailable;
pagingNextAvailableMemory += FOUR_MEGABYTES;
++(*pPagesAllocated);
@@ -101,13 +128,14 @@ bool Paging_Print_Page_Table(PAGE_DIRECTORY_ENTRY *thePageDir)
done = true;
kprintf("Page table entries:\nLogical -> Physical -- flags\n");
- kprintf("continuing\n");
+ //serial_printf("Page table entries:\nLogical -> Physical -- flags\n");
for (int i = 0; i < 1024; ++i)
{
if (!(thePageDir[i] & PAGE_ENTRY_PRESENT))
continue;
done = false;
kprintf("0x%X -> 0x%X - 0x%X\n", i * FOUR_MEGABYTES, thePageDir[i] & 0xFFFFF000, thePageDir[i] & 0xFFF);
+ //serial_printf("0x%X -> 0x%X - 0x%X\n", i * FOUR_MEGABYTES, thePageDir[i] & 0xFFFFF000, thePageDir[i] & 0xFFF);
}
return done;
}
diff --git a/MyOS_1/paging.h b/MyOS_1/paging.h
index ccc09b2..36d392e 100644
--- a/MyOS_1/paging.h
+++ b/MyOS_1/paging.h
@@ -21,10 +21,14 @@ typedef /*__declspec(align(4096))*/ uint32_t PAGE_TABLE_ENTRY;
#define FOUR_MEGABYTES 0x400000
#define PAGING_ADDRESS_BITS 0xFFFFF000
+#define PAGING_ADDRESS_BITS 0xFFFFF000
+
extern uint32_t paging_space[0x3FFF];
extern uint32_t *pageDir;
extern uint32_t pagingNextAvailableMemory;
+extern uint32_t pagingNextAvailableKernelPage;
+extern uint32_t pagingKernelNonPagedArea;
extern uint32_t paging4MPagesAvailable;
extern uint32_t nextPageDirectory; // TEMPTEMP
@@ -71,9 +75,12 @@ inline void Paging_Enable(multiboot_info *multibootInfo)
// Identity map the next four megs (this is used by the GUI shell)
pageDirectory[3] = (PAGE_DIRECTORY_ENTRY)((uint32_t)0xC00000 | DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_WRITABLE | DIRECTORY_ENTRY_4MB | DIRECTORY_ENTRY_USER_ACCESSIBLE);
- // Identity map the next four megs
+ // Identity map the next four megs (this is used for applications' page tables)
pageDirectory[4] = (PAGE_DIRECTORY_ENTRY)((uint32_t)0x1000000 | DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_WRITABLE | DIRECTORY_ENTRY_4MB | DIRECTORY_ENTRY_USER_ACCESSIBLE);
+ // Another 4 megs - this one is used by the non-paged pool (for drivers)
+ pageDirectory[5] = (PAGE_DIRECTORY_ENTRY)((uint32_t)0x1400000 | DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_WRITABLE | DIRECTORY_ENTRY_4MB | DIRECTORY_ENTRY_USER_ACCESSIBLE);
+
// Map the kernel (4 megs starting at 0x10 0000) to 0xC000 0000
for (i = 0; i < 1024; ++i)
{
@@ -83,6 +90,9 @@ inline void Paging_Enable(multiboot_info *multibootInfo)
// put the kernel page table in the page directory into entry 768, which will map it to 0xC000 0000
pageDirectory[768] = (PAGE_DIRECTORY_ENTRY)((uint32_t)initialKernelTable | DIRECTORY_ENTRY_PRESENT | DIRECTORY_ENTRY_WRITABLE);
+ // The next kernel page we allocate can go to this index in the page directory
+ pagingNextAvailableKernelPage = 769;
+
// TEMPTEMP HACKHACK! - identity map the linear frame buffer, which on my Qemu starts at 0xFD00 0000
uint32_t lfbAddress = 0xFD000000;
@@ -119,20 +129,23 @@ inline void Paging_Enable(multiboot_info *multibootInfo)
// save a pointer to pageDirectory
pageDir = pageDirectory;
- // determine available pages
- pagingNextAvailableMemory = FOUR_MEGABYTES * 5; // TEMP: Next available page will (likely) start at 20 Megs
- // We'll assume we have 64 megs available
- paging4MPagesAvailable = 16; // TODO: Calculate based on the memory map Grub gave us
-
// TEMPTEMP: put page directories between 16 - 20 megs
nextPageDirectory = FOUR_MEGABYTES * 4;
+ // TEMPTEMP: put a non-paged pool of memory between 20 - 24 megs
+ pagingKernelNonPagedArea = FOUR_MEGABYTES * 5;
+
// Walk through the mem map grub gave us
// TODO: Assert that grub gave us a memory map
// TODO: Don't assume we have memory at the beginning of RAM
// TODO: Use all the entries we get from GRUB
multiboot_mmap_entry *entry = (multiboot_mmap_entry *)multibootInfo->mmap_addr;
-
+
+ // determine available pages
+ pagingNextAvailableMemory = FOUR_MEGABYTES * 6; // TEMP: Next available page will (likely) start at 24 Megs
+ // We'll assume we have 64 megs available
+ //paging4MPagesAvailable = 16; // TODO: Calculate based on the memory map Grub gave us
+
// examine each mmap entry
for (uint32_t offset = 0; offset <= multibootInfo->mmap_length && entry->size; offset += entry->size + 4)
{
@@ -144,10 +157,10 @@ inline void Paging_Enable(multiboot_info *multibootInfo)
// determine how many pages we really have available
uint64_t addrEnd = entry->addr + entry->len;
uint64_t bytesAvailable = addrEnd - pagingNextAvailableMemory;
- paging4MPagesAvailable = bytesAvailable / FOUR_MEGABYTES;
+ paging4MPagesAvailable = (uint32_t)(bytesAvailable / (uint64_t)FOUR_MEGABYTES);
return;
}
- }
+ }
// advance pointer to next entry
entry = (multiboot_mmap_entry*)((uint32_t)entry + entry->size + 4);
diff --git a/Release/MyOS_1.dll b/Release/MyOS_1.dll
index aca4a47..2a485ab 100644
Binary files a/Release/MyOS_1.dll and b/Release/MyOS_1.dll differ