mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Started using virtual memory manager in kernel. Also changes read() function to accept a char* to write to
This commit is contained in:
+2
-4
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user