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:
@@ -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
|
||||
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-4
@@ -1,12 +1,9 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
__attribute__ ((section ("entry")))
|
||||
void main() {
|
||||
char* msg = read();
|
||||
char msg[8] = { 'H','e','l','l','o','!','\n',0 };
|
||||
print(msg);
|
||||
|
||||
sleep(4500);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+34
-38
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user