forked from PoliEcho-holding-org/kern
- Pretty much rewrote stage1.asm - Changed some addresses in stage2.asm and in memory/adresses.h - Changed stage3.c to read root INode and it's dirEntries to find kernel.bin and term16n.fnt - Made a fake ls command in kernel.c, just so it prints something - Fixed makedisk.c to make the disk image properly - Changed Makefile to compile makedisk.c and then run makedisk - Added makedisk executable to .gitignore
99 lines
3.2 KiB
C
99 lines
3.2 KiB
C
#include <memory/physical.h>
|
|
#include <memory/virtual.h>
|
|
#include <memory/addresses.h>
|
|
#include <disk/disk.h>
|
|
//#include <disk/filesys.h>
|
|
#include <screen/gfxmode.h>
|
|
|
|
#include <fs/fs.h>
|
|
|
|
uint8_t loadFile(char* filename, void* dest);
|
|
|
|
__attribute__ ((section("entry")))
|
|
void main() {
|
|
// Physical memory manager setup
|
|
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
|
|
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES;
|
|
smapEntries += smapEntryCount - 1;
|
|
uint32_t totalMemory = smapEntries->baseAddress + smapEntries->length - 1;
|
|
|
|
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
|
|
|
|
smapEntries = (smapEntry_t*)SMAP_ENTRIES;
|
|
for (uint32_t i = 0; i < smapEntryCount; i++) {
|
|
if (smapEntries[i].type == 1) {
|
|
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
|
|
}
|
|
}
|
|
|
|
deinitMemoryRegion(0x1000, 0x11000); // Reserve kernel memory (under 0x12000)
|
|
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
|
|
|
|
// Load root dir, find kernel INode and parse it
|
|
superBlock_t* superblock = (superBlock_t*)SUPERBLOCK_LOC;
|
|
superblock->rootInodePtr = BOOT_FIRST_INODE_LOC + sizeof(inode_t);
|
|
diskRead(superblock->firstDataBlock * 8, 8, (void*)SCRATCH_BLOCK_LOC);
|
|
|
|
if (loadFile("kernel.bin", (void*)KERNEL_LOC) != 0) __asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
|
if (loadFile("term16n.fnt", (void*)FONT_LOC) != 0) __asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
|
|
|
// Virtual memory manager setup
|
|
if (setupVirtualMemoryManager() != 0) {
|
|
while (1);
|
|
}
|
|
|
|
// Identity map VBE framebuffer
|
|
uint32_t fbSize = (gfxMode->yRes * gfxMode->linearBytesPerScanline) / PAGE_SIZE;
|
|
if (fbSize % PAGE_SIZE > 0) { fbSize++; }
|
|
fbSize *= 2; // Double for hardware
|
|
for (uint32_t i = 0, fbStart = gfxMode->physicalBasePtr; i < fbSize; i++, fbStart += PAGE_SIZE) {
|
|
mapPage((void*)fbStart, (void*)fbStart);
|
|
}
|
|
deinitMemoryRegion(gfxMode->physicalBasePtr, fbSize * BLOCK_SIZE);
|
|
|
|
*(uint32_t*)PHYS_MEM_MAX_BLOCKS = maxBlocks;
|
|
*(uint32_t*)PHYS_MEM_USED_BLOCKS = usedBlocks;
|
|
|
|
for (uint32_t virt = KERNEL_LOC; virt < 0x400000; virt += PAGE_SIZE) {
|
|
unmapPage((void*)virt);
|
|
}
|
|
|
|
__asm__ volatile ("movl %cr3, %ecx; movl %ecx, %cr3");
|
|
|
|
*(uint32_t*)CURRENT_PAGE_DIR_ADDR = (uint32_t)currentPd;
|
|
|
|
// Call/jump to kernel
|
|
((void(*)(void))0xC0000000)();
|
|
}
|
|
|
|
uint8_t loadFile(char* filename, void* dest) {
|
|
dirEntry_t* dirEntry = (dirEntry_t*)SCRATCH_BLOCK_LOC;
|
|
while (dirEntry->name[0] != '\0') {
|
|
if (strcmp(dirEntry->name, filename) == 0) break;
|
|
dirEntry++;
|
|
}
|
|
|
|
if (dirEntry->name[0] == '\0') return 1;
|
|
|
|
inode_t* inode = (inode_t*)BOOT_FIRST_INODE_LOC;
|
|
while (inode->id != dirEntry->id) {
|
|
inode++;
|
|
}
|
|
|
|
uint32_t totalBlocks = bytesToBlocks(inode->sizeBytes);
|
|
uint32_t addressOffset = 0;
|
|
|
|
for (uint8_t i = 0; i < 4 && totalBlocks > 0; i++) {
|
|
diskRead(inode->extent[i].firstBlock * 8, inode->extent[i].length * 8, dest + addressOffset);
|
|
addressOffset += inode->extent[i].length * FS_BLOCK_SIZE;
|
|
totalBlocks -= inode->extent[i].length;
|
|
}
|
|
|
|
if (totalBlocks > 0) {
|
|
// TODO: Indirect extents
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|