diff --git a/Makefile b/Makefile index dba475a..73fc60d 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ kernel: $(SRC)/kernel.c $(SRC)/entry.asm $(C_FILES): @echo "Compiling $(SRC)/$@.c..." - @$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c + @$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c @$(LD) -T$(SRC)/$@.ld --oformat binary -o $(BUILD)/$@.bin $(BUILD)/$@.o @rm $(BUILD)/$@.o diff --git a/include/c/stdio.h b/include/c/stdio.h index aaf259d..018458c 100644 --- a/include/c/stdio.h +++ b/include/c/stdio.h @@ -5,10 +5,8 @@ void print(const char* s) { // Use Syscall(1) - Puts() __asm__ volatile ("int $0x80" : : "a"(1), "b"(s)); } -char* read() { // Use Syscall(2) - Gets() - char* s; - __asm__ volatile ("int $0x80" : "=b"(s) : "a"(2)); - return s; +void read(char* s) { // Use Syscall(2) - Gets() + __asm__ volatile ("int $0x80" : : "a"(2), "b"(s)); } #endif diff --git a/include/interrupt/syscall.h b/include/interrupt/syscall.h index 6376934..183d705 100644 --- a/include/interrupt/syscall.h +++ b/include/interrupt/syscall.h @@ -24,22 +24,22 @@ void sys_sleep() { void sys_puts() { char* s; __asm__ volatile ("movl %%ebx, %0" : "=r"(s)); - print(s); } // TODO: Use a Read() sycall and read from stdin -// Returns: ebx - char* string +// Args: ebx - char* buffer void sys_gets() { - char* s = read(); - __asm__ volatile ("movl %0, %%ebx" :: "r"(s)); + char* s; + __asm__ volatile ("movl %%ebx, %0" : "=r"(s)); + read(s); } // System call table void* syscalls[MAX_SYSCALLS] = { - sys_sleep, - sys_puts, - sys_gets, + sys_sleep, // Syscall(0) + sys_puts, // Syscall(1) + sys_gets, // Syscall(2) }; // 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 __asm__ volatile ( ".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 "cmp eax, MAX_SYSCALLS - 1\n" @@ -82,7 +82,7 @@ void syscallHandler(void) { "pop fs\n" "pop gs\n" "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 "invalidSyscall:\n" diff --git a/include/keyboard/keyboard.h b/include/keyboard/keyboard.h index 9b179d7..e6e9038 100644 --- a/include/keyboard/keyboard.h +++ b/include/keyboard/keyboard.h @@ -43,8 +43,7 @@ char getc() { } // Reads until a newline -char* read() { - static char inputBuffer[MAX_INPUT_LENGTH]; +void read(char* buffer) { char c; uint8_t len = 0; @@ -54,15 +53,14 @@ char* read() { len--; putc(c); } 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); } } - inputBuffer[len++] = c; // Add newline + buffer[len++] = c; // Add newline putc(c); - inputBuffer[len] = '\0'; // Null terminate - return inputBuffer; + buffer[len] = '\0'; // Null terminate } void setupKeyboard() { diff --git a/include/memory/addresses.h b/include/memory/addresses.h index b3baa96..9eb0da7 100644 --- a/include/memory/addresses.h +++ b/include/memory/addresses.h @@ -3,5 +3,8 @@ #define MEMMAP_AREA 0x30000 #define KERNEL_LOC 0x50000 +#define FILETABLE_LOC 0x7000 +#define SMAP_ENTRY_COUNT 0x8500 +#define SMAP_ENTRIES 0x8504 #endif diff --git a/include/memory/virtual.h b/include/memory/virtual.h index 05bf1a7..3c5d533 100644 --- a/include/memory/virtual.h +++ b/include/memory/virtual.h @@ -16,7 +16,7 @@ #define SET_ATTR(_entry, _attr) (*(_entry) |= (_attr)) #define CLEAR_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 pdEntry_t; @@ -96,13 +96,13 @@ void freePage(ptEntry_t* page) { } uint8_t setPageDirectory(pageDirectory_t* pd) { - if (!pd) { return 0; } // Nuh uh + if (!pd) { return 1; } // Nuh uh currentPd = pd; // cr3 (Control register 3) - current page dir address __asm__ volatile("movl %%eax, %%cr3" : : "a"(currentPd)); - return 1; // Success + return 0; // Success } void flushTlbEntry(uint32_t virtualAddress) { @@ -116,7 +116,7 @@ uint8_t mapPage(void* physicalAddr, void* virtualAddr) { if (!TEST_ATTR(entry, PTE_PRESENT)) { // Assuming that the page is not allocated since it's not present 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?) memset(table, 0, sizeof(pageTable_t)); @@ -134,7 +134,7 @@ uint8_t mapPage(void* physicalAddr, void* virtualAddr) { SET_ATTR(page, PTE_PRESENT); SET_FRAME(page, (uint32_t)physicalAddr); - return 1; // Success + return 0; // Success } void unmapPage(void* virtualAddress) { @@ -148,7 +148,7 @@ uint8_t setupVirtualMemoryManager() { // Create a default page dir 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)); for (uint32_t i = 0; i < 1024; i++) { @@ -157,11 +157,11 @@ uint8_t setupVirtualMemoryManager() { // Alloc default page table 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 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(table3gb, 0, sizeof(pageTable_t)); @@ -200,7 +200,7 @@ uint8_t setupVirtualMemoryManager() { // ENABLE PAGING!!! Set PG bit 31 and PE bit 0 in cr0 __asm__ volatile("movl %cr0, %eax; orl $0x80000001, %eax; movl %eax, %cr0"); - return 1; + return 0; // Success } #endif diff --git a/src/calc.c b/src/calc.c index 3612f01..2913ecd 100644 --- a/src/calc.c +++ b/src/calc.c @@ -1,12 +1,9 @@ -#include #include __attribute__ ((section ("entry"))) void main() { - char* msg = read(); + char msg[8] = { 'H','e','l','l','o','!','\n',0 }; print(msg); - - sleep(4500); return; } diff --git a/src/kernel.c b/src/kernel.c index 4e31a3a..065bf00 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -19,7 +19,7 @@ #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 void printFiletable(char* ft); @@ -40,8 +40,8 @@ void main() { setupKeyboard(); // Physical memory manager setup - uint32_t smapEntryCount = *(uint32_t*)0x8500; - smapEntry_t* smapEntries = (smapEntry_t*)0x8504; + uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT; + smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1; setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory); @@ -74,12 +74,13 @@ void main() { print("kern.\n\n"); diskRead(5, 1, filetable); // Read the filetable and store it in memory - + // Run Interactive Shell Program // TODO: Make it in another file while (1) { print(PROMPT); - char* input = read(); + char input[MAX_INPUT_LENGTH]; + read(input); if (input[0] == '\n') continue; @@ -284,56 +285,51 @@ void main() { 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 - print("Allocating "); - print(itoa(neededBlocks, 10)); - print(" Block"); - if (neededBlocks > 1) putc('s'); - */ - - char* address = allocBlocks(neededBlocks); - - if (address == NULL) { - print("\nNot enough memory to allocate!\n"); - break; + char* entryPoint = (char*)0x400000; // Right after first 4MB + for (uint32_t i = 0; i < neededPages; i++) { + ptEntry_t page = 0; + uint32_t physicalAddress = (uint32_t)allocPage(&page); + + if (mapPage((void*)physicalAddress, (void*)(entryPoint + i * PAGE_SIZE)) != 0) { + fgColor = RED; + print("\nNot enough memory to allocate!\n"); + fgColor = FG_COLOR; + break; + } } - /* Debug printing - print("\nAllocated to address 0x"); - print(itoa((uint32_t)address, 16)); - print("!\n"); - */ + diskRead(sector, size, entryPoint); - diskRead(sector, size, address); - - if (strcmp(fileType, "bin") == 0) { - clear(); - ((void(*)(void))address)(); // Call program - clear(); + if (strcmp(fileType, "bin") == 0) { // TODO: Improve this + ((void(*)(void))entryPoint)(); // Call program } else if (strcmp(fileType, "tab") == 0) { - printFiletable(address); + printFiletable(entryPoint); } else if (strcmp(fileType, "fnt") == 0) { print("Loading "); print(filename); print("...\n"); - memcpy(address, font, size * 512); + memcpy(entryPoint, font, size * 512); print("Font loaded\n"); } else { for (size_t i = 0; i < size * 512; i++) { - if (address[i] != '\0') { - putc(address[i]); + if (entryPoint[i] != '\0') { + putc(entryPoint[i]); } } putc('\n'); } - - // Debug printing - // print("Freeing allocated memory...\n"); - freeBlocks(address, neededBlocks); - // print("Done!\n"); + for (uint32_t i = 0, virtualAddr = (uint32_t)entryPoint; i < neededPages; i++, virtualAddr += PAGE_SIZE) { + ptEntry_t* page = getPage(virtualAddr); + if (PAGE_PHYS_ADDRESS(page) && TEST_ATTR(page, PTE_PRESENT)) { // Check if the page is used + freePage(page); + unmapPage((void*)virtualAddr); + flushTlbEntry(virtualAddr); // Invalidate unused page + } + } break; }