Started using virtual memory manager in kernel. Also changes read() function to accept a char* to write to

This commit is contained in:
2024-05-24 15:47:45 +02:00
parent 978ada55ca
commit f009bbdac9
8 changed files with 63 additions and 71 deletions
+2 -4
View File
@@ -5,10 +5,8 @@ void print(const char* s) { // Use Syscall(1) - Puts()
__asm__ volatile ("int $0x80" : : "a"(1), "b"(s)); __asm__ volatile ("int $0x80" : : "a"(1), "b"(s));
} }
char* read() { // Use Syscall(2) - Gets() void read(char* s) { // Use Syscall(2) - Gets()
char* s; __asm__ volatile ("int $0x80" : : "a"(2), "b"(s));
__asm__ volatile ("int $0x80" : "=b"(s) : "a"(2));
return s;
} }
#endif #endif
+9 -9
View File
@@ -24,22 +24,22 @@ void sys_sleep() {
void sys_puts() { void sys_puts() {
char* s; char* s;
__asm__ volatile ("movl %%ebx, %0" : "=r"(s)); __asm__ volatile ("movl %%ebx, %0" : "=r"(s));
print(s); print(s);
} }
// TODO: Use a Read() sycall and read from stdin // TODO: Use a Read() sycall and read from stdin
// Returns: ebx - char* string // Args: ebx - char* buffer
void sys_gets() { void sys_gets() {
char* s = read(); char* s;
__asm__ volatile ("movl %0, %%ebx" :: "r"(s)); __asm__ volatile ("movl %%ebx, %0" : "=r"(s));
read(s);
} }
// System call table // System call table
void* syscalls[MAX_SYSCALLS] = { void* syscalls[MAX_SYSCALLS] = {
sys_sleep, sys_sleep, // Syscall(0)
sys_puts, sys_puts, // Syscall(1)
sys_gets, sys_gets, // Syscall(2)
}; };
// int 0x80 - Syscall interrupt, handled by this function // int 0x80 - Syscall interrupt, handled by this function
@@ -50,7 +50,7 @@ void syscallHandler(void) {
// We should also push these regs: ax, gs, fs, es, ds, bp, di, si, dx, cx, bx // We should also push these regs: ax, gs, fs, es, ds, bp, di, si, dx, cx, bx
__asm__ volatile ( __asm__ volatile (
".intel_syntax noprefix\n" // We use intel syntax ".intel_syntax noprefix\n" // We use intel syntax
".equ MAX_SYSCALLS, 2\n" // Define MAX_SYSCALLS again ".equ MAX_SYSCALLS, 3\n" // Define MAX_SYSCALLS again TODO: I don't want to have to do this
// Check if syscall exists // Check if syscall exists
"cmp eax, MAX_SYSCALLS - 1\n" "cmp eax, MAX_SYSCALLS - 1\n"
@@ -82,7 +82,7 @@ void syscallHandler(void) {
"pop fs\n" "pop fs\n"
"pop gs\n" "pop gs\n"
"add esp, 4\n" // Save eax value "add esp, 4\n" // Save eax value
"iretd\n" // Return from interrupt "iretd\n" // Return from interrupt (32 bit)
// TODO: Send an error or something here // TODO: Send an error or something here
"invalidSyscall:\n" "invalidSyscall:\n"
+4 -6
View File
@@ -43,8 +43,7 @@ char getc() {
} }
// Reads until a newline // Reads until a newline
char* read() { void read(char* buffer) {
static char inputBuffer[MAX_INPUT_LENGTH];
char c; char c;
uint8_t len = 0; uint8_t len = 0;
@@ -54,15 +53,14 @@ char* read() {
len--; len--;
putc(c); putc(c);
} else if (len + 1 != MAX_INPUT_LENGTH) { // Check if we can add a new character (this method avoids overflow issues) } else if (len + 1 != MAX_INPUT_LENGTH) { // Check if we can add a new character (this method avoids overflow issues)
inputBuffer[len++] = c; buffer[len++] = c;
putc(c); putc(c);
} }
} }
inputBuffer[len++] = c; // Add newline buffer[len++] = c; // Add newline
putc(c); putc(c);
inputBuffer[len] = '\0'; // Null terminate buffer[len] = '\0'; // Null terminate
return inputBuffer;
} }
void setupKeyboard() { void setupKeyboard() {
+3
View File
@@ -3,5 +3,8 @@
#define MEMMAP_AREA 0x30000 #define MEMMAP_AREA 0x30000
#define KERNEL_LOC 0x50000 #define KERNEL_LOC 0x50000
#define FILETABLE_LOC 0x7000
#define SMAP_ENTRY_COUNT 0x8500
#define SMAP_ENTRIES 0x8504
#endif #endif
+9 -9
View File
@@ -16,7 +16,7 @@
#define SET_ATTR(_entry, _attr) (*(_entry) |= (_attr)) #define SET_ATTR(_entry, _attr) (*(_entry) |= (_attr))
#define CLEAR_ATTR(_entry, _attr) (*(_entry) &= ~(_attr)) #define CLEAR_ATTR(_entry, _attr) (*(_entry) &= ~(_attr))
#define TEST_ATTR(_entry, _attr) (*(_entry) & (_attr)) #define TEST_ATTR(_entry, _attr) (*(_entry) & (_attr))
#define SET_FRAME(_entry, _address) (*(_entry) = (*(_entry) & ~0x7ffff000) | (_address)) #define SET_FRAME(_entry, _address) (*(_entry) = (*(_entry) & ~0xfffff000) | (_address))
typedef uint32_t ptEntry_t; typedef uint32_t ptEntry_t;
typedef uint32_t pdEntry_t; typedef uint32_t pdEntry_t;
@@ -96,13 +96,13 @@ void freePage(ptEntry_t* page) {
} }
uint8_t setPageDirectory(pageDirectory_t* pd) { uint8_t setPageDirectory(pageDirectory_t* pd) {
if (!pd) { return 0; } // Nuh uh if (!pd) { return 1; } // Nuh uh
currentPd = pd; currentPd = pd;
// cr3 (Control register 3) - current page dir address // cr3 (Control register 3) - current page dir address
__asm__ volatile("movl %%eax, %%cr3" : : "a"(currentPd)); __asm__ volatile("movl %%eax, %%cr3" : : "a"(currentPd));
return 1; // Success return 0; // Success
} }
void flushTlbEntry(uint32_t virtualAddress) { void flushTlbEntry(uint32_t virtualAddress) {
@@ -116,7 +116,7 @@ uint8_t mapPage(void* physicalAddr, void* virtualAddr) {
if (!TEST_ATTR(entry, PTE_PRESENT)) { if (!TEST_ATTR(entry, PTE_PRESENT)) {
// Assuming that the page is not allocated since it's not present // Assuming that the page is not allocated since it's not present
pageTable_t* table = (pageTable_t*)allocBlocks(1); pageTable_t* table = (pageTable_t*)allocBlocks(1);
if (!table) return 0; // Out of memory!! if (!table) return 1; // Out of memory!!
// Clear page table (may be slow?) // Clear page table (may be slow?)
memset(table, 0, sizeof(pageTable_t)); memset(table, 0, sizeof(pageTable_t));
@@ -134,7 +134,7 @@ uint8_t mapPage(void* physicalAddr, void* virtualAddr) {
SET_ATTR(page, PTE_PRESENT); SET_ATTR(page, PTE_PRESENT);
SET_FRAME(page, (uint32_t)physicalAddr); SET_FRAME(page, (uint32_t)physicalAddr);
return 1; // Success return 0; // Success
} }
void unmapPage(void* virtualAddress) { void unmapPage(void* virtualAddress) {
@@ -148,7 +148,7 @@ uint8_t setupVirtualMemoryManager() {
// Create a default page dir // Create a default page dir
pageDirectory_t* dir = (pageDirectory_t*)allocBlocks(3); pageDirectory_t* dir = (pageDirectory_t*)allocBlocks(3);
if (!dir) { return 0; } // Out of memory if (!dir) { return 1; } // Out of memory
memset(dir, 0, sizeof(pageDirectory_t)); memset(dir, 0, sizeof(pageDirectory_t));
for (uint32_t i = 0; i < 1024; i++) { for (uint32_t i = 0; i < 1024; i++) {
@@ -157,11 +157,11 @@ uint8_t setupVirtualMemoryManager() {
// Alloc default page table // Alloc default page table
pageTable_t* table = (pageTable_t*)allocBlocks(1); pageTable_t* table = (pageTable_t*)allocBlocks(1);
if (!table) { return 0; } // Out of memory if (!table) { return 1; } // Out of memory
// Alloc a 3GB page // Alloc a 3GB page
pageTable_t* table3gb = (pageTable_t*)allocBlocks(1); pageTable_t* table3gb = (pageTable_t*)allocBlocks(1);
if (!table) { return 0; } // Out of memory if (!table) { return 1; } // Out of memory
memset(table, 0, sizeof(pageTable_t)); memset(table, 0, sizeof(pageTable_t));
memset(table3gb, 0, sizeof(pageTable_t)); memset(table3gb, 0, sizeof(pageTable_t));
@@ -200,7 +200,7 @@ uint8_t setupVirtualMemoryManager() {
// ENABLE PAGING!!! Set PG bit 31 and PE bit 0 in cr0 // ENABLE PAGING!!! Set PG bit 31 and PE bit 0 in cr0
__asm__ volatile("movl %cr0, %eax; orl $0x80000001, %eax; movl %eax, %cr0"); __asm__ volatile("movl %cr0, %eax; orl $0x80000001, %eax; movl %eax, %cr0");
return 1; return 0; // Success
} }
#endif #endif
+1 -4
View File
@@ -1,12 +1,9 @@
#include <time.h>
#include <stdio.h> #include <stdio.h>
__attribute__ ((section ("entry"))) __attribute__ ((section ("entry")))
void main() { void main() {
char* msg = read(); char msg[8] = { 'H','e','l','l','o','!','\n',0 };
print(msg); print(msg);
sleep(4500);
return; return;
} }
+30 -34
View File
@@ -19,7 +19,7 @@
#define PROMPT "#> " #define PROMPT "#> "
char* filetable = (char*)0x7000; // Pretty sure we don't have to care about the bootloader at 0x7c00 char* filetable = (char*)FILETABLE_LOC; // Pretty sure we don't have to care about the bootloader at 0x7c00
// Function declarations // Function declarations
void printFiletable(char* ft); void printFiletable(char* ft);
@@ -40,8 +40,8 @@ void main() {
setupKeyboard(); setupKeyboard();
// Physical memory manager setup // Physical memory manager setup
uint32_t smapEntryCount = *(uint32_t*)0x8500; uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
smapEntry_t* smapEntries = (smapEntry_t*)0x8504; smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t
uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1; uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1;
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory); setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
@@ -79,7 +79,8 @@ void main() {
// TODO: Make it in another file // TODO: Make it in another file
while (1) { while (1) {
print(PROMPT); print(PROMPT);
char* input = read(); char input[MAX_INPUT_LENGTH];
read(input);
if (input[0] == '\n') continue; if (input[0] == '\n') continue;
@@ -284,56 +285,51 @@ void main() {
char* fileType = strchr(filename, '.') + 1; char* fileType = strchr(filename, '.') + 1;
uint32_t neededBlocks = (size * 512) / BLOCK_SIZE + 1; uint32_t neededPages = (size * 512) / PAGE_SIZE;
if ((size * 512) % PAGE_SIZE > 0) { neededPages++; }
/* Debug printing char* entryPoint = (char*)0x400000; // Right after first 4MB
print("Allocating "); for (uint32_t i = 0; i < neededPages; i++) {
print(itoa(neededBlocks, 10)); ptEntry_t page = 0;
print(" Block"); uint32_t physicalAddress = (uint32_t)allocPage(&page);
if (neededBlocks > 1) putc('s');
*/
char* address = allocBlocks(neededBlocks); if (mapPage((void*)physicalAddress, (void*)(entryPoint + i * PAGE_SIZE)) != 0) {
fgColor = RED;
if (address == NULL) {
print("\nNot enough memory to allocate!\n"); print("\nNot enough memory to allocate!\n");
fgColor = FG_COLOR;
break; break;
} }
}
/* Debug printing diskRead(sector, size, entryPoint);
print("\nAllocated to address 0x");
print(itoa((uint32_t)address, 16));
print("!\n");
*/
diskRead(sector, size, address); if (strcmp(fileType, "bin") == 0) { // TODO: Improve this
((void(*)(void))entryPoint)(); // Call program
if (strcmp(fileType, "bin") == 0) {
clear();
((void(*)(void))address)(); // Call program
clear();
} else if (strcmp(fileType, "tab") == 0) { } else if (strcmp(fileType, "tab") == 0) {
printFiletable(address); printFiletable(entryPoint);
} else if (strcmp(fileType, "fnt") == 0) { } else if (strcmp(fileType, "fnt") == 0) {
print("Loading "); print("Loading ");
print(filename); print(filename);
print("...\n"); print("...\n");
memcpy(address, font, size * 512); memcpy(entryPoint, font, size * 512);
print("Font loaded\n"); print("Font loaded\n");
} else { } else {
for (size_t i = 0; i < size * 512; i++) { for (size_t i = 0; i < size * 512; i++) {
if (address[i] != '\0') { if (entryPoint[i] != '\0') {
putc(address[i]); putc(entryPoint[i]);
} }
} }
putc('\n'); putc('\n');
} }
// Debug printing for (uint32_t i = 0, virtualAddr = (uint32_t)entryPoint; i < neededPages; i++, virtualAddr += PAGE_SIZE) {
// print("Freeing allocated memory...\n"); ptEntry_t* page = getPage(virtualAddr);
freeBlocks(address, neededBlocks); if (PAGE_PHYS_ADDRESS(page) && TEST_ATTR(page, PTE_PRESENT)) { // Check if the page is used
// print("Done!\n"); freePage(page);
unmapPage((void*)virtualAddr);
flushTlbEntry(virtualAddr); // Invalidate unused page
}
}
break; break;
} }