diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 9d4b9f7..10b742b 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -229,7 +229,7 @@ yields(); return; } - void *bootSector = malloc(512); + void *bootSector = mallocAligned(512, 1); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; info = malloc(sizeof(FatInfo)); diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 9d4b9f7..10b742b 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -229,7 +229,7 @@ yields(); return; } - void *bootSector = malloc(512); + void *bootSector = mallocAligned(512, 1); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; info = malloc(sizeof(FatInfo)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c new file mode 100644 index 0000000..f6e90eb --- /dev/null +++ b/src/kernel/memory/paging.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +extern uintptr_t kernelEnd; + +PageTablePointer *kernelPageTables; +PagePointer *kernelPages; +uint32_t *allocatedPages; +// uint32_t *freePageChunks; // todo: hierarchical structure to find a free page +// more quickly (make one bit an indicator weacher any +// page in the next layer is free) need to find a compromise between size and +// speed + +void *getPage(); + +void identityMapPagesUntil(void *end) { + void *currentAddress = (void *)0; + while (currentAddress < end) { + currentAddress = getPage(); + } +} + +void enablePaging() { + asm volatile("mov %%eax, %%cr3" : : "a"(kernelPageTables)); + asm volatile("mov %cr0, %eax"); + asm volatile("orl $0x80000000, %eax"); + asm volatile("mov %eax, %cr0"); +} + +void initializePaging() { + void *currentPosition = (void *)((kernelEnd - 1) & ~0xFFF) + 0x1000; + kernelPageTables = currentPosition; + currentPosition += 0x4000; + kernelPages = currentPosition; + currentPosition += sizeof(uint32_t) * 1024 * 1024; + allocatedPages = currentPosition; + currentPosition += + sizeof(uint32_t) * 1024 * 1024 / 32; // 1024 tables with 1024 pages each + for (int i = 0; i < 1024; i++) { + kernelPageTables[i].present = 1; + kernelPageTables[i].writable = 1; + kernelPageTables[i].pagePointerAddress = + (uint32_t)(uintptr_t)(kernelPages + 1024 * i) >> 12; + } + for (uint32_t i = 0; i < 0x100000; i++) { + // mark all as inaccessible + kernelPages[i].present = 0; + } + identityMapPagesUntil(currentPosition); + enablePaging(); +} + +void allocatePage(uint32_t index32bit, uint8_t bit) { + allocatedPages[index32bit] |= 1 << bit; + uint32_t pageId = index32bit + bit; + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].pageId = pageId; +} + +void *getPage() { + // todo: add task handling etc. + for (uint32_t i = 0; i < 0x100000; i += 32) { + if (allocatedPages[i] == ~0) { + continue; + } + for (uint8_t bit = 0; bit < 32; bit++) { + if (allocatedPages[i] & (1 << bit)) { + continue; + } + allocatePage(i, bit); + return (void *)(uintptr_t)((i + bit) << 12); + } + } + return NULL; +} + +void freePage(void *pageAddress) { + uintptr_t pageId = (uintptr_t)pageAddress >> 12; + allocatedPages[pageId / 32] &= ~(1 << (pageId % 32)); + kernelPages[pageId].present = 0; +} + +void markMMIO(void *address) { + uintptr_t pageId = (uintptr_t)address >> 12; + allocatedPages[pageId / 32] |= 1 << (pageId % 32); + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].isVolatile = 1; + kernelPages[pageId].pageId = pageId; +} diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 9d4b9f7..10b742b 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -229,7 +229,7 @@ yields(); return; } - void *bootSector = malloc(512); + void *bootSector = mallocAligned(512, 1); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; info = malloc(sizeof(FatInfo)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c new file mode 100644 index 0000000..f6e90eb --- /dev/null +++ b/src/kernel/memory/paging.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +extern uintptr_t kernelEnd; + +PageTablePointer *kernelPageTables; +PagePointer *kernelPages; +uint32_t *allocatedPages; +// uint32_t *freePageChunks; // todo: hierarchical structure to find a free page +// more quickly (make one bit an indicator weacher any +// page in the next layer is free) need to find a compromise between size and +// speed + +void *getPage(); + +void identityMapPagesUntil(void *end) { + void *currentAddress = (void *)0; + while (currentAddress < end) { + currentAddress = getPage(); + } +} + +void enablePaging() { + asm volatile("mov %%eax, %%cr3" : : "a"(kernelPageTables)); + asm volatile("mov %cr0, %eax"); + asm volatile("orl $0x80000000, %eax"); + asm volatile("mov %eax, %cr0"); +} + +void initializePaging() { + void *currentPosition = (void *)((kernelEnd - 1) & ~0xFFF) + 0x1000; + kernelPageTables = currentPosition; + currentPosition += 0x4000; + kernelPages = currentPosition; + currentPosition += sizeof(uint32_t) * 1024 * 1024; + allocatedPages = currentPosition; + currentPosition += + sizeof(uint32_t) * 1024 * 1024 / 32; // 1024 tables with 1024 pages each + for (int i = 0; i < 1024; i++) { + kernelPageTables[i].present = 1; + kernelPageTables[i].writable = 1; + kernelPageTables[i].pagePointerAddress = + (uint32_t)(uintptr_t)(kernelPages + 1024 * i) >> 12; + } + for (uint32_t i = 0; i < 0x100000; i++) { + // mark all as inaccessible + kernelPages[i].present = 0; + } + identityMapPagesUntil(currentPosition); + enablePaging(); +} + +void allocatePage(uint32_t index32bit, uint8_t bit) { + allocatedPages[index32bit] |= 1 << bit; + uint32_t pageId = index32bit + bit; + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].pageId = pageId; +} + +void *getPage() { + // todo: add task handling etc. + for (uint32_t i = 0; i < 0x100000; i += 32) { + if (allocatedPages[i] == ~0) { + continue; + } + for (uint8_t bit = 0; bit < 32; bit++) { + if (allocatedPages[i] & (1 << bit)) { + continue; + } + allocatePage(i, bit); + return (void *)(uintptr_t)((i + bit) << 12); + } + } + return NULL; +} + +void freePage(void *pageAddress) { + uintptr_t pageId = (uintptr_t)pageAddress >> 12; + allocatedPages[pageId / 32] &= ~(1 << (pageId % 32)); + kernelPages[pageId].present = 0; +} + +void markMMIO(void *address) { + uintptr_t pageId = (uintptr_t)address >> 12; + allocatedPages[pageId / 32] |= 1 << (pageId % 32); + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].isVolatile = 1; + kernelPages[pageId].pageId = pageId; +} diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index c6ba9bf..5e06d2b 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -24,9 +24,11 @@ } } +extern uint32_t *kernelPageTables; + void initOSTasks() { setRunningTask(&mainTask); - createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); + createTask(&printerTask, (uint32_t)printLoop, 0x0, kernelPageTables); } inline Task *getPrinterTask() { return &printerTask; } diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 9d4b9f7..10b742b 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -229,7 +229,7 @@ yields(); return; } - void *bootSector = malloc(512); + void *bootSector = mallocAligned(512, 1); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; info = malloc(sizeof(FatInfo)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c new file mode 100644 index 0000000..f6e90eb --- /dev/null +++ b/src/kernel/memory/paging.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +extern uintptr_t kernelEnd; + +PageTablePointer *kernelPageTables; +PagePointer *kernelPages; +uint32_t *allocatedPages; +// uint32_t *freePageChunks; // todo: hierarchical structure to find a free page +// more quickly (make one bit an indicator weacher any +// page in the next layer is free) need to find a compromise between size and +// speed + +void *getPage(); + +void identityMapPagesUntil(void *end) { + void *currentAddress = (void *)0; + while (currentAddress < end) { + currentAddress = getPage(); + } +} + +void enablePaging() { + asm volatile("mov %%eax, %%cr3" : : "a"(kernelPageTables)); + asm volatile("mov %cr0, %eax"); + asm volatile("orl $0x80000000, %eax"); + asm volatile("mov %eax, %cr0"); +} + +void initializePaging() { + void *currentPosition = (void *)((kernelEnd - 1) & ~0xFFF) + 0x1000; + kernelPageTables = currentPosition; + currentPosition += 0x4000; + kernelPages = currentPosition; + currentPosition += sizeof(uint32_t) * 1024 * 1024; + allocatedPages = currentPosition; + currentPosition += + sizeof(uint32_t) * 1024 * 1024 / 32; // 1024 tables with 1024 pages each + for (int i = 0; i < 1024; i++) { + kernelPageTables[i].present = 1; + kernelPageTables[i].writable = 1; + kernelPageTables[i].pagePointerAddress = + (uint32_t)(uintptr_t)(kernelPages + 1024 * i) >> 12; + } + for (uint32_t i = 0; i < 0x100000; i++) { + // mark all as inaccessible + kernelPages[i].present = 0; + } + identityMapPagesUntil(currentPosition); + enablePaging(); +} + +void allocatePage(uint32_t index32bit, uint8_t bit) { + allocatedPages[index32bit] |= 1 << bit; + uint32_t pageId = index32bit + bit; + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].pageId = pageId; +} + +void *getPage() { + // todo: add task handling etc. + for (uint32_t i = 0; i < 0x100000; i += 32) { + if (allocatedPages[i] == ~0) { + continue; + } + for (uint8_t bit = 0; bit < 32; bit++) { + if (allocatedPages[i] & (1 << bit)) { + continue; + } + allocatePage(i, bit); + return (void *)(uintptr_t)((i + bit) << 12); + } + } + return NULL; +} + +void freePage(void *pageAddress) { + uintptr_t pageId = (uintptr_t)pageAddress >> 12; + allocatedPages[pageId / 32] &= ~(1 << (pageId % 32)); + kernelPages[pageId].present = 0; +} + +void markMMIO(void *address) { + uintptr_t pageId = (uintptr_t)address >> 12; + allocatedPages[pageId / 32] |= 1 << (pageId % 32); + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].isVolatile = 1; + kernelPages[pageId].pageId = pageId; +} diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index c6ba9bf..5e06d2b 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -24,9 +24,11 @@ } } +extern uint32_t *kernelPageTables; + void initOSTasks() { setRunningTask(&mainTask); - createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); + createTask(&printerTask, (uint32_t)printLoop, 0x0, kernelPageTables); } inline Task *getPrinterTask() { return &printerTask; } diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 67e3ffa..9ace674 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -2,8 +2,8 @@ #include #include #include - -#define STACK_SIZE 0x100000 +// one page +#define STACK_SIZE 4096 #define INTERRUPT_TASK 0x1 Task *currentTask; diff --git a/src/include/alloc.h b/src/include/alloc.h index 9aa86ba..91b1fc0 100644 --- a/src/include/alloc.h +++ b/src/include/alloc.h @@ -4,20 +4,10 @@ #include #include -typedef struct MemoryBlock { - struct MemoryBlock *last; - struct MemoryBlock *next; - uint32_t size; - Task *task; -} MemoryBlock; - -extern void initMemoryAllocation(uintptr_t kernelEnd); extern void *malloc(uintptr_t size); extern void *mallocAligned(uintptr_t size, uint8_t alignment); extern void *mallocTask(uintptr_t size, Task *task); extern void free(void *location); -extern void printMemoryStack(); extern void freeTaskAllocations(Task *task); -extern Task *getCurrentTask(); #endif diff --git a/src/include/paging.h b/src/include/paging.h new file mode 100644 index 0000000..c774cc8 --- /dev/null +++ b/src/include/paging.h @@ -0,0 +1,37 @@ +#ifndef PAGING_H +#define PAGING_H + +#include +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t writeThrough : 1; + uint32_t isVolatile : 1; // disables the cpu cache + uint32_t accessed : 1; + uint32_t reserved : 1; + uint32_t is4MBPage : 1; // always set to 0 for now, more work needed for 4MB + // pages (different structure,...) + uint32_t global : 1; + uint32_t available : 3; + uint32_t pageId : 20; +} PagePointer; + +typedef struct { + uint32_t present : 1; + uint32_t writable : 1; + uint32_t belongsToUserProcess : 1; + uint32_t reserved : 2; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t reserved2 : 2; + uint32_t available : 3; + uint32_t pagePointerAddress : 20; +} PageTablePointer; + +extern void freePage(void *page); +extern void *getPage(); +extern void initializePaging(); +extern void markMMIO(void *address); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 157a922..5445516 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -20,6 +20,8 @@ uint32_t timerTicks; } Task; +extern Task *currentTask; + extern void initTasking(); extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); diff --git a/src/kernel/drivers/interrupts/exceptions.asm b/src/kernel/drivers/interrupts/exceptions.asm index 9fd4f04..1b18036 100644 --- a/src/kernel/drivers/interrupts/exceptions.asm +++ b/src/kernel/drivers/interrupts/exceptions.asm @@ -71,4 +71,4 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + iret diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index d420c60..b418027 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -28,11 +28,11 @@ #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { - int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; - getCurrentTask()->ticksLeft = millis; + int32_t ticksLeft = currentTask->ticksLeft - millis; + currentTask->ticksLeft = millis; yield(); if (ticksLeft > 0) { - getCurrentTask()->ticksLeft = ticksLeft; + currentTask->ticksLeft = ticksLeft; } } diff --git a/src/kernel/drivers/pci/hardDrive/ahciController.c b/src/kernel/drivers/pci/hardDrive/ahciController.c index 98e7d02..ea1c706 100644 --- a/src/kernel/drivers/pci/hardDrive/ahciController.c +++ b/src/kernel/drivers/pci/hardDrive/ahciController.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOWER(ptr) (uint32_t)(uintptr_t) ptr @@ -60,14 +61,6 @@ continue; } uint8_t portType = CheckPortType(&hba->Ports[i]); - if (!portType) { - continue; - } - if (portType == SATAPI) { - printf("satapi devices not implemented yet!\n"); - yields(); - continue; - } if (portType != SATA) { continue; } @@ -77,13 +70,13 @@ configurePort(port); printf("reconfigured the port\n"); yields(); - // ahciCommand(port->HBAPortPtr, 0, &ident, 0, ATA_CMD_IDENTIFY); - ahciIdentify(port->HBAPortPtr, &ident); + ahciCommand(&hba->Ports[i], 0, &ident, 1, ATA_CMD_IDENTIFY); HardDrive *hardDrive = malloc(sizeof(HardDrive)); hardDrive->interface = port; hardDrive->access = accessAHCIDrive; addIdentifyData(hardDrive, &ident); listAdd(drives, hardDrive); + yields(); } } @@ -134,49 +127,6 @@ #define HBA_PxIS_TFES (1 << 30) -void ahciIdentify(HBAPort *hbaPort, void *buffer) { - hbaPort->InterruptStatus = (uint32_t)-1; - hbaPort->InterruptEnable = (uint32_t)-1; - HBACommandHeader *commandHeader = - (void *)(uintptr_t)hbaPort->CommandListBase; - commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); - commandHeader->Write = 0; - commandHeader->ClearBusy = 0; - commandHeader->PRDTLength = 1; - commandHeader->PRDBCount = 0; - - HBACommandTable *CommandTable = - (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); - CommandTable->PRDTEntry[0].DataBaseAddress = LOWER(buffer); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FisToDevice *CommandFIS = (FisToDevice *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->command = ATA_CMD_IDENTIFY; - CommandFIS->commandControl = 1; - CommandFIS->DeviceRegister = (1 << 6); - uint64_t Spin = 0; - while ((hbaPort->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && - Spin < 1000000) { - Spin++; - } - if (Spin == 1000000) { - printf("ahci command timeout\n"); - return; - } - hbaPort->CommandIssue = 1; - while (true) { - if (hbaPort->CommandIssue == 0) { - break; - } - if (hbaPort->InterruptStatus & HBA_PxIS_TFES) { - return; - } - } - printf("count: %i ", commandHeader->PRDBCount); -} - bool ahciCommand(HBAPort *hbaPort, uint64_t Sector, void *Buffer, uint32_t SectorCount, uint8_t command) { hbaPort->InterruptStatus = (uint32_t)-1; @@ -184,9 +134,7 @@ (void *)(uintptr_t)hbaPort->CommandListBase; commandHeader->CommandFISLength = sizeof(FisToDevice) / sizeof(uint32_t); commandHeader->Write = 0; - // commandHeader->ClearBusy = 1; commandHeader->PRDTLength = 1; - // commandHeader->PortMultiplier = 0; HBACommandTable *CommandTable = (void *)(uintptr_t)(commandHeader->CommandTableBaseAddress); @@ -241,6 +189,7 @@ return; } HBAMemory *hba = (void *)(uintptr_t)(pciDevice->bar5 & 0xFFFFFFF0); + markMMIO(hba); if (!(hba->GlobalHostControl & (1 << 31))) { printf("controller not in ahci mode!\n"); return; diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index 6e59023..0c26900 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -26,14 +26,6 @@ break; } } - void *buffer = malloc(512); - uint8_t i = 0; - foreach (drives) { - HardDrive *drive = current->data; - drive->access(drive, 0, buffer, 1, 0); - printf("drive %i start: %x end: %x\n", ++i, CONTENT(buffer), - CONTENT(buffer + 508)); - } - printf("count: %i\n", listCount(drives)); - mountDisk(listGet(&drives, 1)); + printf("found %i hard drives\n", listCount(drives)); + // mountDisk(listGet(&drives, 1)); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index a341d2f..541259e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,21 +13,17 @@ extern uint32_t kernelEnd; void kernelMain() { - initMemoryAllocation(kernelEnd); + initializePaging(); initOSTasks(); - getCurrentTask()->timerTicks = 1000; - getCurrentTask()->ticksLeft = 1000; + currentTask->timerTicks = 1000; + currentTask->ticksLeft = 1000; drawLogo(); yields(); printCPUData(); setupDevices(); - printFileSystemTree(); - File *file = readFile("/folder/content"); - printf("file size: %i\n", file->file->size); - printf("file content: %s\n", file->data); while (1) { - for (Message *message = popBeginning(&(getCurrentTask()->messages)); - message; message = popBeginning(&getCurrentTask()->messages)) { + for (Message *message = popBeginning(¤tTask->messages); message; + message = popBeginning(¤tTask->messages)) { switch (message->type) { case KEYBOARD_CHAR: printf("%c", message->data); diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 7f407e1..301f1c2 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -1,115 +1,27 @@ #include +#include #include #include - -MemoryBlock *firstBlock; - -void initMemoryAllocation(uintptr_t kernelEnd) { - firstBlock = (MemoryBlock *)kernelEnd; - firstBlock->next = NULL; - firstBlock->last = NULL; - firstBlock->task = NULL; - firstBlock->size = -1; -} - -#define getOffset() \ - (alignment ? alignmentMask & (alignmentBit - ((uintptr_t)(current + 1) & \ - (alignmentMask))) \ - : 0) - -void memmove(uint8_t *to, uint8_t *from, uintptr_t count) { - if (from > to) { - for (; count > 0; count--) { - *(to++) = *(from++); - } - return; - } - for (to += count - 1, from += count - 1; count > 0; count--) { - *(to--) = *(from--); - } -} +#include void *mallocTaskAligned(uintptr_t size, uint8_t alignment, Task *task) { - MemoryBlock *current = firstBlock; - uint32_t alignmentBit = 1 << alignment; - uint32_t alignmentMask = alignmentBit - 1; - uintptr_t additionalOffset = getOffset(); - while (current->task || current->size < size + additionalOffset) { - current = current->next; - additionalOffset = getOffset(); - } - uint32_t neededSize = size + additionalOffset; - if (current->size > neededSize + sizeof(MemoryBlock) * 2) { - MemoryBlock *next = current->next; - current->size = neededSize; - current->next = ((void *)(current + 1)) + neededSize; - current->next->last = current; - current->next->next = next; - if (next) { - current->next->size = (void *)next - (void *)(current->next + 1); - } else { - current->next->size = -1; - } - current->next->task = NULL; - if (next) { - next->last = current->next; - } - } - if (additionalOffset) { - memmove((uint8_t *)current + additionalOffset, (uint8_t *)current, - sizeof(MemoryBlock)); - current = (void *)current + additionalOffset; - current->size = (void *)current->next - (void *)(current + 1); - current->last->next = current; - current->last->size = (void *)current - (void *)(current->last + 1); - } - current->task = task; - return (void *)(current + 1); + // todo: do this nicer : have different 'buckets' for different allocation + // sizes + return getPage(); } void *mallocTask(uintptr_t size, Task *task) { return mallocTaskAligned(size, 0, task); } -void *malloc(uintptr_t size) { - return mallocTaskAligned(size, 0, getCurrentTask()); -} +void *malloc(uintptr_t size) { return mallocTaskAligned(size, 0, currentTask); } void *mallocAligned(uintptr_t size, uint8_t alignment) { - return mallocTaskAligned(size, alignment, getCurrentTask()); + return mallocTaskAligned(size, alignment, currentTask); } -void mergeNextIfPossible(MemoryBlock *current) { - if (current->next && !current->next->task) { - current->next = current->next->next; - current->size = (void *)current->next - (void *)(current + 1); - current->next->last = current; - } -} - -void free(void *location) { - MemoryBlock *current = ((MemoryBlock *)location) - 1; - current->task = NULL; - for (uint32_t i = 0; i < current->size; i++) { - ((uint8_t *)¤t[1])[i] = 0; - } - mergeNextIfPossible(current); - if (current->last && !current->last->task) { - current = current->last; - mergeNextIfPossible(current); - } - mergeNextIfPossible(current); -} +void free(void *location) { freePage(location); } void freeTaskAllocations(Task *task) { - MemoryBlock *current = firstBlock; - while (current->next != 0x00) { - if (current->task == task) { - free(current + 1); - } - current = current->next; - } - if (current->task == task) { - free(current + 1); - } + // todo } diff --git a/src/kernel/memory/fileSystem.c b/src/kernel/memory/fileSystem.c index 9d4b9f7..10b742b 100644 --- a/src/kernel/memory/fileSystem.c +++ b/src/kernel/memory/fileSystem.c @@ -229,7 +229,7 @@ yields(); return; } - void *bootSector = malloc(512); + void *bootSector = mallocAligned(512, 1); drive->access(drive, 0, bootSector, 1, 0); FatBootSector *boot = bootSector; info = malloc(sizeof(FatInfo)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c new file mode 100644 index 0000000..f6e90eb --- /dev/null +++ b/src/kernel/memory/paging.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +extern uintptr_t kernelEnd; + +PageTablePointer *kernelPageTables; +PagePointer *kernelPages; +uint32_t *allocatedPages; +// uint32_t *freePageChunks; // todo: hierarchical structure to find a free page +// more quickly (make one bit an indicator weacher any +// page in the next layer is free) need to find a compromise between size and +// speed + +void *getPage(); + +void identityMapPagesUntil(void *end) { + void *currentAddress = (void *)0; + while (currentAddress < end) { + currentAddress = getPage(); + } +} + +void enablePaging() { + asm volatile("mov %%eax, %%cr3" : : "a"(kernelPageTables)); + asm volatile("mov %cr0, %eax"); + asm volatile("orl $0x80000000, %eax"); + asm volatile("mov %eax, %cr0"); +} + +void initializePaging() { + void *currentPosition = (void *)((kernelEnd - 1) & ~0xFFF) + 0x1000; + kernelPageTables = currentPosition; + currentPosition += 0x4000; + kernelPages = currentPosition; + currentPosition += sizeof(uint32_t) * 1024 * 1024; + allocatedPages = currentPosition; + currentPosition += + sizeof(uint32_t) * 1024 * 1024 / 32; // 1024 tables with 1024 pages each + for (int i = 0; i < 1024; i++) { + kernelPageTables[i].present = 1; + kernelPageTables[i].writable = 1; + kernelPageTables[i].pagePointerAddress = + (uint32_t)(uintptr_t)(kernelPages + 1024 * i) >> 12; + } + for (uint32_t i = 0; i < 0x100000; i++) { + // mark all as inaccessible + kernelPages[i].present = 0; + } + identityMapPagesUntil(currentPosition); + enablePaging(); +} + +void allocatePage(uint32_t index32bit, uint8_t bit) { + allocatedPages[index32bit] |= 1 << bit; + uint32_t pageId = index32bit + bit; + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].pageId = pageId; +} + +void *getPage() { + // todo: add task handling etc. + for (uint32_t i = 0; i < 0x100000; i += 32) { + if (allocatedPages[i] == ~0) { + continue; + } + for (uint8_t bit = 0; bit < 32; bit++) { + if (allocatedPages[i] & (1 << bit)) { + continue; + } + allocatePage(i, bit); + return (void *)(uintptr_t)((i + bit) << 12); + } + } + return NULL; +} + +void freePage(void *pageAddress) { + uintptr_t pageId = (uintptr_t)pageAddress >> 12; + allocatedPages[pageId / 32] &= ~(1 << (pageId % 32)); + kernelPages[pageId].present = 0; +} + +void markMMIO(void *address) { + uintptr_t pageId = (uintptr_t)address >> 12; + allocatedPages[pageId / 32] |= 1 << (pageId % 32); + kernelPages[pageId].present = 1; + kernelPages[pageId].writable = 1; + kernelPages[pageId].isVolatile = 1; + kernelPages[pageId].pageId = pageId; +} diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index c6ba9bf..5e06d2b 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -24,9 +24,11 @@ } } +extern uint32_t *kernelPageTables; + void initOSTasks() { setRunningTask(&mainTask); - createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); + createTask(&printerTask, (uint32_t)printLoop, 0x0, kernelPageTables); } inline Task *getPrinterTask() { return &printerTask; } diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 67e3ffa..9ace674 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -2,8 +2,8 @@ #include #include #include - -#define STACK_SIZE 0x100000 +// one page +#define STACK_SIZE 4096 #define INTERRUPT_TASK 0x1 Task *currentTask; diff --git a/src/multiboot/boot.asm b/src/multiboot/boot.asm index 22eff15..b935f47 100644 --- a/src/multiboot/boot.asm +++ b/src/multiboot/boot.asm @@ -60,4 +60,4 @@ section .bss align 4 stack: - resb KERNEL_STACK_SIZE \ No newline at end of file + resb KERNEL_STACK_SIZE