Got the OS to boot from new disk image

- 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
This commit is contained in:
2024-06-02 19:09:33 +02:00
parent 2a9d33d733
commit 9c96636436
8 changed files with 258 additions and 174 deletions
+1
View File
@@ -1,2 +1,3 @@
build build
kern.iso kern.iso
makedisk
+5 -16
View File
@@ -14,24 +14,11 @@ FONTS = testfont term16n
.PHONY: os clean run .PHONY: os clean run
# Main compilation target # Main compilation target
os: $(BUILD) filesystem os: $(BUILD) bootloader kernel $(C_FILES) $(FONTS)
@cc ./makedisk.c -o ./makedisk
@./makedisk # TODO: List of files
@echo "\nDone!\n" @echo "\nDone!\n"
# Filesystem
filesystem: bootloader kernel $(C_FILES) $(FONTS)
@echo "Building filesystem..."
@$(AS) -fbin -o $(BUILD)/filetable.bin $(SRC)/filetable.asm
@dd if=/dev/zero of=kern.iso bs=512 count=2880 status=none
# TODO: Make this not so manual
@dd if=$(BUILD)/boot.bin of=kern.iso bs=512 seek=0 conv=notrunc status=none
@dd if=$(BUILD)/filetable.bin of=kern.iso bs=512 seek=15 conv=notrunc status=none
@dd if=$(BUILD)/kernel.bin of=kern.iso bs=512 seek=16 conv=notrunc status=none
@dd if=$(BUILD)/term16n.fnt of=kern.iso bs=512 seek=56 conv=notrunc status=none
@dd if=$(BUILD)/testfont.fnt of=kern.iso bs=512 seek=60 conv=notrunc status=none
@dd if=$(SRC)/fs/test.txt of=kern.iso bs=512 seek=64 conv=notrunc status=none
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=65 conv=notrunc status=none
@dd if=$(BUILD)/editor.bin of=kern.iso bs=512 seek=71 conv=notrunc status=none
$(BUILD): $(BUILD):
@[ -d $(BUILD) ] || mkdir $(BUILD) @[ -d $(BUILD) ] || mkdir $(BUILD)
@rm -rf $(BUILD)/* @rm -rf $(BUILD)/*
@@ -55,12 +42,14 @@ kernel: $(SRC)/kernel.c
@$(LD) -T$(SRC)/kernel.ld -z notext --oformat binary -o $(BUILD)/kernel.bin $(BUILD)/kernel.o @$(LD) -T$(SRC)/kernel.ld -z notext --oformat binary -o $(BUILD)/kernel.bin $(BUILD)/kernel.o
@rm $(BUILD)/kernel.o @rm $(BUILD)/kernel.o
# This target compiles *.c (except kernel.c)
$(C_FILES): $(C_FILES):
@echo "Compiling $(SRC)/$@.c..." @echo "Compiling $(SRC)/$@.c..."
@$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c @$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c
@$(LD) -T$(SRC)/$@.ld -z notext --oformat binary -o $(BUILD)/$@.bin $(BUILD)/$@.o @$(LD) -T$(SRC)/$@.ld -z notext --oformat binary -o $(BUILD)/$@.bin $(BUILD)/$@.o
@rm $(BUILD)/$@.o @rm $(BUILD)/$@.o
# This target builds all fonts inside src/fonts
$(FONTS): $(FONTS):
@echo "Assembling $(SRC)/fonts/$@.asm..." @echo "Assembling $(SRC)/fonts/$@.asm..."
@$(AS) -fbin -o $(BUILD)/$@.fnt $(SRC)/fonts/$@.asm @$(AS) -fbin -o $(BUILD)/$@.fnt $(SRC)/fonts/$@.asm
+25 -12
View File
@@ -2,25 +2,28 @@
#define ADDRESSES_H #define ADDRESSES_H
/* /*
* Memory layout of addresses 0x0000 - 0xA000 * Memory layout of addresses 0x0000 - 0x12000
* 0x0000-0x0fff - Probably shouldn't mess with this? idk it feels wrong * 0x0000-0x0fff - Probably shouldn't mess with this? idk it feels wrong
* 0x1000-0x17ff - Free * 0x1000-0x17ff - Free
* 0x1800-0x1fff - Global Variables * 0x1800-0x1fff - Global Variables
* 0x2000-0x2fff - Larger structs * 0x2000-0x2fff - Larger structs
* 0x3000-0x3fff - Filesystem area * 0x3000-0x3fff - Free
* 0x4000-0x4fff - Font area * 0x4000-0x4fff - Font area
* 0x6000-0x84ff - Free * 0x6000-0x6fff - VBE info area
* 0x8500-0x8fff - SMAP Area * 0x7000-0x7bff - SMAP Area
* 0x9000-0x9fff - VBE info area * 0x7c00-0x8bff - Bootblock
* 0x8c00-0x9bff - Superblock (i think)
* 0x9c00-0xafff - Free
* 0xb000-0xbfff - Bootloader first INode
*/ */
// Global Variables // Global Variables 0x1800-0x1fff
#define SLEEP_TIMER 0x1800 #define SLEEP_TIMER 0x1800
#define CURRENT_PAGE_DIR_ADDR 0x1804 #define CURRENT_PAGE_DIR_ADDR 0x1804
#define PHYS_MEM_MAX_BLOCKS 0x1808 #define PHYS_MEM_MAX_BLOCKS 0x1808
#define PHYS_MEM_USED_BLOCKS 0x180C #define PHYS_MEM_USED_BLOCKS 0x180C
// Some structs // Some structs 0x2000-0x2fff
#define TERMINAL_INFO_LOC 0x2000 #define TERMINAL_INFO_LOC 0x2000
#define KEYBOARD_STATE_LOC 0x2100 #define KEYBOARD_STATE_LOC 0x2100
#define DATETIME_LOC 0x2200 #define DATETIME_LOC 0x2200
@@ -33,12 +36,22 @@
#define FONT_WIDTH (FONT_LOC) #define FONT_WIDTH (FONT_LOC)
#define FONT_HEIGHT (FONT_LOC + 1) #define FONT_HEIGHT (FONT_LOC + 1)
// Smap Area 0x8500 - 0x8fff // VBE Info Area 0x6000 - 0x6fff
#define SMAP_ENTRY_COUNT 0x8500 #define MODE_INFO_BLOCK_LOC 0x6000 // 512 Bytes
#define SMAP_ENTRIES 0x8504
// VBE Info Area 0x9000 - 0x9fff // Smap Area 0x7000 - 0x7bff
#define MODE_INFO_BLOCK_LOC 0x9000 // 512 Bytes #define SMAP_ENTRY_COUNT 0x7000
#define SMAP_ENTRIES 0x7004
// Bootblock 0x7c00-0x9bff
#define BOOTBLOCK_LOC 0x7c00
// Superblock 0x9c00-0xabff
#define SUPERBLOCK_LOC 0x8c00
// First INode from bootloader
#define BOOT_FIRST_INODE_LOC 0xb000
#define SCRATCH_BLOCK_LOC 0xc000
// Other addresses // Other addresses
#define KERNEL_LOC 0x100000 #define KERNEL_LOC 0x100000
+10 -7
View File
@@ -83,10 +83,9 @@ int main(int argc, char** argv) {
printf("Free blocks: %d (%d Bytes)\n", bytesToBlocks(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE); printf("Free blocks: %d (%d Bytes)\n", bytesToBlocks(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE);
// Pad out to the whole disk size // Pad out to the whole disk size
/*
for (uint32_t i = 0; i < bytesToBlocks(diskSize) - writtenBlocks; i++) { for (uint32_t i = 0; i < bytesToBlocks(diskSize) - writtenBlocks; i++) {
assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1); assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1);
} */ }
// Cleanup // Cleanup
for (uint32_t i = 0; i < fileCount; i++) { for (uint32_t i = 0; i < fileCount; i++) {
@@ -120,9 +119,9 @@ void writeSuperblock() {
superblock.inodeCount = fileCount; // 2 reserved INodes (0 - Invalid, 1 - Root) superblock.inodeCount = fileCount; // 2 reserved INodes (0 - Invalid, 1 - Root)
superblock.firstInodeBitmapBlock = 2; // Block 0 - Boot, Block 1 - Superblock superblock.firstInodeBitmapBlock = 2; // Block 0 - Boot, Block 1 - Superblock
superblock.inodeBitmapBlockCount = superblock.inodeCount / (FS_BLOCK_SIZE * 8) + ((superblock.inodeCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0); superblock.inodeBitmapBlockCount = superblock.inodeCount / (FS_BLOCK_SIZE * 8) + ((superblock.inodeCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0);
superblock.firstDataBitmapBlock = superblock.firstInodeBlock + superblock.inodeBitmapBlockCount; superblock.firstDataBitmapBlock = superblock.firstInodeBitmapBlock + superblock.inodeBitmapBlockCount;
superblock.inodeBlockCount = bytesToBlocks(superblock.inodeCount * sizeof(inode_t)); superblock.inodeBlockCount = bytesToBlocks(superblock.inodeCount * sizeof(inode_t));
dataBlocks = bytesToBlocks(diskSize); dataBlocks = bytesToBlocks(diskSize);
dataBitCount = (dataBlocks - superblock.firstDataBitmapBlock - superblock.inodeBlockCount); dataBitCount = (dataBlocks - superblock.firstDataBitmapBlock - superblock.inodeBlockCount);
@@ -195,13 +194,16 @@ void writeINodeBlocks() {
.id = 1, .id = 1,
.filetype = FILETYPE_DIR, .filetype = FILETYPE_DIR,
.sizeBytes = sizeof(dirEntry_t) * fileCount, .sizeBytes = sizeof(dirEntry_t) * fileCount,
.sizeSectors = bytesToSectors(inode.sizeBytes), // .sizeSectors = bytesToSectors(inode.sizeBytes), Set below
.timestamp = defaultTimestamp, .timestamp = defaultTimestamp,
.extent[0] = (extent_t) { .extent[0] = (extent_t) {
.firstBlock = superblock.firstDataBlock, .firstBlock = superblock.firstDataBlock,
.length = bytesToBlocks(inode.sizeBytes), // .length = bytesToBlocks(inode.sizeBytes), Set below
}, },
}; };
inode.sizeSectors = bytesToSectors(inode.sizeBytes);
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1); assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
@@ -216,8 +218,9 @@ void writeINodeBlocks() {
inode.timestamp = defaultTimestamp; inode.timestamp = defaultTimestamp;
inode.extent[0] = (extent_t) { inode.extent[0] = (extent_t) {
.firstBlock = block, .firstBlock = block,
.length = bytesToBlocks(inode.sizeBytes), // .length = bytesToBlocks(inode.sizeBytes),
}; };
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1); assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
+17 -44
View File
@@ -25,10 +25,10 @@
#include <color.h> #include <color.h>
#include <fs/fs.h> #include <fs/fs.h>
#define PROMPT "#> " #define PROMPT "/ #> "
// Function declarations // Function declarations
void printFiletable(char* ft); void listFiles();
void printPhysicalMemmap(); void printPhysicalMemmap();
__attribute__ ((section("entry"))) __attribute__ ((section("entry")))
@@ -71,13 +71,11 @@ void main() {
mallocVirtualAddr = kernelMallocVirtualAddr; mallocVirtualAddr = kernelMallocVirtualAddr;
mallocPhysicalAddr = kernelMallocPhysicalAddr; mallocPhysicalAddr = kernelMallocPhysicalAddr;
mallocPages = kernelMallocPages; mallocPages = kernelMallocPages;
// Screen setup
loadFont("term16n.fnt");
terminal->fg = FG_COLOR; terminal->fg = FG_COLOR;
terminal->bg = BG_COLOR; terminal->bg = BG_COLOR;
clear(); clear();
printf("kern.\n\n"); print("kern.\n\n");
// Run Interactive Shell Program // Run Interactive Shell Program
// TODO: Make it in another file // TODO: Make it in another file
@@ -174,14 +172,14 @@ void main() {
printf(" exit | Exits shell\n"); printf(" exit | Exits shell\n");
printf(" gfx | Does a graphics test\n"); printf(" gfx | Does a graphics test\n");
printf(" help | Prints this message\n"); printf(" help | Prints this message\n");
printf(" ls | Lists all available files\n"); printf(" ls | Lists files in current directory\n");
printf(" memmap | Prints the memory map and info\n"); printf(" memmap | Prints the memory map and info\n");
printf(" reboot | Reboots the system\n"); printf(" reboot | Reboots the system\n");
printf(" sleep | Sleeps for input number of seconds\n"); printf(" sleep | Sleeps for input number of seconds\n");
printf(" soundtest | Plays a tune :)\n"); printf(" soundtest | Plays a tune :)\n");
printf(" test | Performs tests\n"); printf(" test | Performs tests\n");
} else if (strcmp(argv[0], "ls") == 0) { } else if (strcmp(argv[0], "ls") == 0) {
printFiletable(filetable); listFiles();
} else if (strcmp(argv[0], "memmap") == 0) { } else if (strcmp(argv[0], "memmap") == 0) {
printPhysicalMemmap(); printPhysicalMemmap();
} else if (strcmp(argv[0], "reboot") == 0) { } else if (strcmp(argv[0], "reboot") == 0) {
@@ -269,8 +267,6 @@ void main() {
mallocVirtualAddr = kernelMallocVirtualAddr; mallocVirtualAddr = kernelMallocVirtualAddr;
mallocPhysicalAddr = kernelMallocPhysicalAddr; mallocPhysicalAddr = kernelMallocPhysicalAddr;
mallocPages = kernelMallocPages; mallocPages = kernelMallocPages;
} else if (strcmp(file->filetype, "tab") == 0) {
printFiletable(entryPoint);
} else if (strcmp(file->filetype, "fnt") == 0) { } else if (strcmp(file->filetype, "fnt") == 0) {
printf("Loading %s...\n", file->filename); printf("Loading %s...\n", file->filename);
memcpy(entryPoint, (char*)FONT_LOC, file->length * 512); memcpy(entryPoint, (char*)FONT_LOC, file->length * 512);
@@ -299,40 +295,17 @@ void main() {
while (1); // Just hang while (1); // Just hang
} }
void printFiletable(char* ft) { void listFiles() {
while (*ft != '\0') { // TODO: Make this real
char filename[15] = { 0 }; printf("Total 8\n");
uint8_t offset = 0; printf(". [dir]\n");
for (uint8_t i = 0; i < 14; i++) { printf(".. [dir]\n");
if (i == 9) { printf("stage3.bin 2868B\n");
filename[offset++] = '.'; printf("kernel.bin 13536B\n");
continue; printf("testfont.fnt 2048B\n");
} printf("term16n.fnt 2048B\n");
if (*ft != '\0') { filename[offset++] = *ft; } printf("calc.bin 1724B\n");
ft++; printf("editor.bin 1280B\n");
}
ft++; // RESERVED
uint8_t sector = *ft++;
uint8_t size = *ft++;
// TODO: Use printf() here for padding
if (sector < 10) putc('0');
if (sector == 0) putc('0');
else printf("%d", sector);
printf(": %s", filename);
for (uint8_t i = 14 - strlen(filename); i > 0; i--) {
printf(" ");
}
printf(" | ");
if (size >> 1) {
printf("%d%skB\n", size >> 1, (size & 0x01) ? ".5" : "");
} else {
printf("%dB\n", size * 512);
}
}
} }
void printPhysicalMemmap() { void printPhysicalMemmap() {
+147 -77
View File
@@ -1,97 +1,167 @@
[bits 16] [bits 16]
[org 0x7c00] [org 0x7c00]
[global start]
%define VIDMEM 0xb800 %define SUPERBLOCK 0x8c00
%define FILETAB_LOC 0x7000 %define FIRST_INODE_BLOCK (SUPERBLOCK) + 12
%define STAGE3_INODE 0xb000 + 128
%define EXTENT0 (STAGE3_INODE) + 21 ; Offset of extent[0] in inode_t
start: start:
mov [driveNum], dl ; Store the drive number
xor ax, ax xor ax, ax
mov es, ax mov es, ax
mov ds, ax mov ds, ax
mov byte [driveNum], dl
; Clear screen ; Clear screen
mov ax, 0x03 mov ax, 0x03
int 0x10 int 0x10
; Reset disk ;; Read in the boot block and the superblock to memory for 2nd stage bootloader
mov ah, 0x0 mov al, 15 ; 8 - 1 for boot block - bootsector & 8 for super block
mov dl, [driveNum] mov bl, al
int 0x13 dec bl ; Number of sectors - 1
mov di, 0x7E00 ; Destination 0x7c00-0x8c00 = boot block, 0x8c00-0x9c00 = superblock
.read: mov dx, 0x1F6 ; flags
; Location mov al, 0xE0 ; 0b0111 0000, bits: 0-3 = LBA bits 24-27, 4 = drive, 5 = always set, 6 = set for LBA, 7 = always set
mov ax, 0 out dx, al
mov es, ax
mov bx, 0x7e00 ; 2nd stage bootloader location mov dx, 0x1F2 ; Sector count port
mov al, 15 ; number of sectors to read
out dx, al
inc dx ; 0x1F3 - LBA low
mov al, 1 ; LBA 1 = 2nd disk sector (0-based), bits 0-7 of LBA
out dx, al
inc dx ; 0x1F4 - LBA mid
xor ax, ax ; bits 8-15 of LBA
out dx, al
inc dx ; 0x1F5 - LBA high
; xor ax, ax ; bits 16-23 of LBA
out dx, al
inc dx
inc dx ; 0x1F7 - Command port
mov al, 0x20 ; Read with retry
out dx, al
call loadSectorLoop
;; Parse superblock for first inode block, offset to reserved bootloader
;; Read first inode block to memory
;; Each disk block is 4KB or 8 sectors of 512 bytes
imul cx, [FIRST_INODE_BLOCK], 8 ; CX = disk sector/LBA of first inode block
mov bl, 7 ; 8 sectors for a block - 1
mov di, 0xb000 ; Address to read into, first inode block = 0xB000-0xC000
mov dx, 0x1F6 ; flags
mov al, 0xE0
out dx, al
mov dx, 0x1F2
mov al, 8
out dx, al
inc dx
mov al, cl
out dx, al
inc dx
mov al, ch
out dx, al
inc dx
xor ax, ax
out dx, al
inc dx
inc dx
mov al, 0x20
out dx, al
call loadSectorLoop
;; Read boot loader inode to memory
;; inode 2, each inode is 64 bytes in size
imul ecx, [EXTENT0], 8 ; first_block translated to disk sector/LBA
imul ebx, [EXTENT0+4], 8 ; length_blocks translated to disk sectors/LBAs
mov dx, 0x1F2
mov al, bl
out dx, al
inc dx
mov al, cl
out dx, al
inc dx
mov al, ch
out dx, al
inc dx
shr ecx, 16
mov al, cl
out dx, al
inc dx
and ch, 0x0F
mov al, ch
or al, 0xE0
out dx, al
inc dx
mov al, 0x20
out dx, al
dec bl
mov ax, 0x5000
mov es, ax
xor di, di
call loadSectorLoop
xor ax, ax
mov es, ax ; ES = 0x0000
;; Jump to 2nd stage bootloader here, does not return
mov dl, [driveNum]
jmp 0x0000:0x7E00
;; Poll status port after reading 1 sector
loadSectorLoop:
in al, dx ; Status register (reading port 1F7h)
test al, 8 ; Sector buffer requires servicing
je loadSectorLoop ; Keep trying until sector buffer is ready
mov cx, 256 ; # of words to read for 1 sector
mov dx, 0x1F0 ; Data port, reading
rep insw ; Read bytes from DX port # into DI, CX # of times
; CHS Location ;; 400ns delay - Read alternate status register
mov al, 4 ; Number of sectors to read (4 = 2kB) mov dx, 0x3F6
mov ch, 0 ; Cylinder in al, dx
mov dh, 0 ; Head in al, dx
mov cl, 2 ; Sector in al, dx
mov dl, [driveNum] in al, dx
mov ah, 2 ; Read from disk cmp bl, 0 ; Sector # to still read
int 0x13 ; Read interrupt je .return
jnc loadPrekernel dec bl
mov dx, 0x1F7
dec byte [counter] jmp loadSectorLoop
jnz .read .return:
ret
diskErr:
mov si, diskErrMsg ;; VARIABLES
mov bl, 0x04
mov ax, VIDMEM
mov es, ax
xor di, di
.printLoop:
movsb
mov [es:di], bl
inc di
cmp byte [si], 0
jne .printLoop
cli
hlt
loadPrekernel:
mov byte [counter], 3
.read:
; Location
mov ax, 0x5000 ; Making es 0x5000 will load the prekernel at 0x50000
mov es, ax
xor bx, bx
; CHS Location
mov al, 10 ; Prekernel size
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 6 ; Sector
mov dl, [driveNum]
mov ah, 2 ; Read from disk
int 0x13 ; Read interrupt
jnc nextStage
dec byte [counter]
jnz .read
;; Far jump to second stage bootloader
nextStage:
mov dl, [driveNum]
jmp 0x0000:0x7e00
;; Data
driveNum: db 0 driveNum: db 0
counter: db 3
; Strings ;; Boot sector magic
diskErrMsg: db "Failed while reading from disk!", 0 times 510-($-$$) db 0 ; Padding
times 510-($-$$) db 0
dw 0xaa55 dw 0xaa55
+6 -7
View File
@@ -2,8 +2,7 @@
[org 0x7e00] [org 0x7e00]
%define STAGE3_LOC 0x50000 %define STAGE3_LOC 0x50000
%define VIDMEM 0xb800 %define MODE_INFO_BLOCK_LOC 0x6000
%define MODE_INFO_BLOCK_LOC 0x9000
start: start:
mov [driveNum], dl mov [driveNum], dl
@@ -12,9 +11,9 @@ start:
xor ax, ax xor ax, ax
mov es, ax mov es, ax
memMapEntries equ 0x8500 memMapEntries equ 0x7000
getMemoryMap: getMemoryMap:
mov di, 0x8504 ; 4 bytes after memMapEntries mov di, memMapEntries + 4 ; 4 bytes after memMapEntries
xor ebx, ebx xor ebx, ebx
xor bp, bp xor bp, bp
mov edx, "PAMS" ; SMAP in little endian mov edx, "PAMS" ; SMAP in little endian
@@ -370,9 +369,9 @@ DATA_SEG equ GDT.dataDescriptor - GDT.start
;; VBE Stuff ;; VBE Stuff
;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !! ;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !!
width: dw 1920 width: dw 0
height: dw 1080 height: dw 0
bpp: db 32 bpp: db 0
offset: dw 0 offset: dw 0
_segment: dw 0 ; segment is a keyword _segment: dw 0 ; segment is a keyword
+47 -11
View File
@@ -2,34 +2,40 @@
#include <memory/virtual.h> #include <memory/virtual.h>
#include <memory/addresses.h> #include <memory/addresses.h>
#include <disk/disk.h> #include <disk/disk.h>
#include <disk/filesys.h> //#include <disk/filesys.h>
#include <screen/gfxmode.h> #include <screen/gfxmode.h>
#include <fs/fs.h>
uint8_t loadFile(char* filename, void* dest);
__attribute__ ((section("entry"))) __attribute__ ((section("entry")))
void main() { void main() {
diskRead(15, 1, filetable); // Load filetable into memory; TODO: Make a filetableUpdate() function that just keeps the stored and memory verisons in sync
// Physical memory manager setup // Physical memory manager setup
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT; uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES;
uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1; smapEntries += smapEntryCount - 1;
uint32_t totalMemory = smapEntries->baseAddress + smapEntries->length - 1;
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory); setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
smapEntries = (smapEntry_t*)SMAP_ENTRIES;
for (uint32_t i = 0; i < smapEntryCount; i++) { for (uint32_t i = 0; i < smapEntryCount; i++) {
if (smapEntries[i].type == 1) { if (smapEntries[i].type == 1) {
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length); initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
} }
} }
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000) deinitMemoryRegion(0x1000, 0x11000); // Reserve kernel memory (under 0x12000)
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE); deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
// Load kernel into memory // Load root dir, find kernel INode and parse it
if (readFile("kernel.bin", (void*)KERNEL_LOC) != 0) { // Check if kernel.bin was loaded superBlock_t* superblock = (superBlock_t*)SUPERBLOCK_LOC;
// TODO: Add error messages superblock->rootInodePtr = BOOT_FIRST_INODE_LOC + sizeof(inode_t);
while (1); 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 // Virtual memory manager setup
if (setupVirtualMemoryManager() != 0) { if (setupVirtualMemoryManager() != 0) {
@@ -60,3 +66,33 @@ void main() {
((void(*)(void))0xC0000000)(); ((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;
}