Implemented Higher Half Kernel!

- Minor makefile chnages
- stage3.c "prekernel", sets up memory stuff and jumps to kernel
- kernel is now at 0xC0000000 - 3GB+ "higher half"
- Added some global variables in memory/addresses.h
This commit is contained in:
2024-05-26 15:49:48 +02:00
parent 01323c5874
commit e9abfc2e4a
11 changed files with 135 additions and 65 deletions
+12 -8
View File
@@ -24,12 +24,12 @@ filesystem: bootloader kernel $(C_FILES) $(FONTS)
@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=5 conv=notrunc status=none
@dd if=$(BUILD)/kernel.bin of=kern.iso bs=512 seek=6 conv=notrunc status=none
@dd if=$(BUILD)/term16n.bin of=kern.iso bs=512 seek=46 conv=notrunc status=none
@dd if=$(BUILD)/testfont.bin of=kern.iso bs=512 seek=50 conv=notrunc status=none
@dd if=$(SRC)/fs/test.txt of=kern.iso bs=512 seek=54 conv=notrunc status=none
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=55 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.bin of=kern.iso bs=512 seek=56 conv=notrunc status=none
@dd if=$(BUILD)/testfont.bin 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
$(BUILD):
@[ -d $(BUILD) ] || mkdir $(BUILD)
@@ -41,14 +41,18 @@ bootloader: $(SRC)/stage1.asm $(SRC)/stage2.asm
@$(AS) -fbin -o $(BUILD)/stage1.bin $(SRC)/stage1.asm
@echo "Assembling $(SRC)/stage2.asm..."
@$(AS) -fbin -o $(BUILD)/stage2.bin $(SRC)/stage2.asm
@cat $(BUILD)/stage1.bin $(BUILD)/stage2.bin > $(BUILD)/boot.bin
@echo "Compiling $(SRC)/stage3.c..."
@$(CC) $(CFLAGS) -Iinclude -o $(BUILD)/stage3.o -c $(SRC)/stage3.c
@$(LD) -T$(SRC)/stage3.ld -z notext --oformat binary -o $(BUILD)/stage3.bin $(BUILD)/stage3.o
@cat $(BUILD)/stage1.bin $(BUILD)/stage2.bin $(BUILD)/stage3.bin > $(BUILD)/boot.bin
@rm $(BUILD)/stage3.o
# Kernel: This target is responsible for creating kernel.bin
kernel: $(SRC)/kernel.c
@echo "Compiling $(SRC)/kernel.c..."
@$(CC) $(CFLAGS) -Iinclude -o $(BUILD)/kernel.o -c $(SRC)/kernel.c
@$(LD) -T$(SRC)/kernel.ld -z notext --oformat binary -o $(BUILD)/kernel.bin $(BUILD)/kernel.o
@rm $(BUILD)/*.o
@rm $(BUILD)/kernel.o
$(C_FILES):
@echo "Compiling $(SRC)/$@.c..."
+2 -1
View File
@@ -53,9 +53,10 @@ Graphics test: \
_These images may be outdated, Idk_
## Known issues
- If you run kernel.bin from shell, it will clear the memory map so when you load anything it will override the kernel code
- If you run any of the bootloader stages or kernel form the shell, it will most likely break. (Maybe add an executable flag?)
- fillCircle() in graphics.h is broken. No idea why, so no filled circles for you (i commented out the boundaryFill call in the function)
- convertColor() doesn't work right, because i should be using floating point, but -mgeneral-regs-only doesn't let me :(
- The soundtest command is very likely to get stuck on a note and play it forever. (Maybe a Sleep() bug?)
- Not really an issue, bit QEMU's PIT is really slow and inacurate
## [Old Version](https://github.com/Tom-on64/old-kern)
+5 -3
View File
@@ -48,14 +48,15 @@ void updateFiletable() {
// TODO: Update the filetable by writing data from memory to disk!
}
void readFile(char* filename, void* buffer) { // Hopefully the buffer is large enought :/
uint8_t readFile(char* filename, void* buffer) { // Hopefully the buffer is large enought :/
fileEntry_t* file = findFile(filename);
if (file == NULL) { return; } // File doesn't exist!
if (file == NULL) { return 1; } // File doesn't exist!
diskRead(file->startAddress, file->length, buffer);
return 0; // Success
}
void writeFile(char* filename, void* buffer) { // TODO: Add length so we don't write too much/too little
uint8_t writeFile(char* filename, void* buffer) { // TODO: Add length so we don't write too much/too little
fileEntry_t* file = findFile(filetable);
if (file == NULL) { // File exists -> override
// File doesn't exist -> create new file
@@ -74,6 +75,7 @@ void writeFile(char* filename, void* buffer) { // TODO: Add length so we don't w
}
diskWrite(file->startAddress, file->length, buffer); // Write the file
return 0; // Success
}
void printFiletable(char* ft) {
+13 -5
View File
@@ -1,10 +1,18 @@
#ifndef ADDRESSES_H
#define ADDRESSES_H
#define MEMMAP_AREA 0x30000
#define KERNEL_LOC 0x50000
#define FILETABLE_LOC 0x7000
#define SMAP_ENTRY_COUNT 0x8500
#define SMAP_ENTRIES 0x8504
// Locations
#define KERNEL_LOC 0x100000
#define FILETABLE_LOC 0x7000
// Physical memory manager
#define MEMMAP_AREA 0x30000
#define SMAP_ENTRY_COUNT 0x8500
#define SMAP_ENTRIES 0x8504
#define PHYS_MEM_MAX_BLOCKS 0x1804
#define PHYS_MEM_USED_BLOCKS 0x1808
// Virtual memory manager
#define CURRENT_PAGE_DIR_ADDR 0x1800
#endif
+9 -7
View File
@@ -10,13 +10,15 @@
;;
filetable:
db "boot",0,0,0,0,0,0, "bin",0,0,5
db "filetable",0, "tab",0,5,1
db "kernel",0,0,0,0, "bin",0,6,40
db "term16n",0,0,0, "fnt",0,46,4
db "testfont",0,0, "fnt",0,50,4
db "test",0,0,0,0,0,0, "txt",0,54,1
db "calc",0,0,0,0,0,0, "bin",0,55,2
db "boot",0,0,0,0,0,0, "bin",0,0,1
db "stage2",0,0,0,0, "bin",0,1,4
db "stage3",0,0,0,0, "bin",0,5,10
db "filetable",0, "tab",0,15,1
db "kernel",0,0,0,0, "bin",0,16,40
db "term16n",0,0,0, "fnt",0,56,4
db "testfont",0,0, "fnt",0,60,4
db "test",0,0,0,0,0,0, "txt",0,64,1
db "calc",0,0,0,0,0,0, "bin",0,65,2
times 512-($-$$) db 0
+7 -31
View File
@@ -29,7 +29,12 @@ void printPhysicalMemmap();
__attribute__ ((section("entry")))
void main() {
diskRead(5, 1, filetable);
// Retrieve global variables
currentPd = (pageDirectory_t*)*(uint32_t*)CURRENT_PAGE_DIR_ADDR; // Don't ask
memoryMap = (uint32_t*)MEMMAP_AREA;
maxBlocks = *(uint32_t*)PHYS_MEM_MAX_BLOCKS;
usedBlocks = *(uint32_t*)PHYS_MEM_USED_BLOCKS;
// Interrupt setup
setupIdt();
setupExceptions();
@@ -42,40 +47,11 @@ void main() {
setupTimer();
setupRtc();
setupKeyboard();
// Physical memory manager setup
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t
uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1;
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
for (uint32_t i = 0; i < smapEntryCount; i++) {
if (smapEntries[i].type == 1) {
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
}
}
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000)
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
// Virtual memory manager setup
setupVirtualMemoryManager(); // TODO: Check if it succeeds
// 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);
// Screen setup
readFile("term16n.fnt", font);
clear();
print("kern.\n\n");
// Run Interactive Shell Program
// TODO: Make it in another file
+1 -1
View File
@@ -1,5 +1,5 @@
SECTIONS {
.text 0x50000 : {
.text 0xC0000000 : {
*(entry);
*(.text*);
}
+6 -7
View File
@@ -3,8 +3,7 @@
[global start]
%define VIDMEM 0xb800
%define FILETAB_LOC 0x7000 ; TODO: Read kernel size and location from ft
%define KERNEL_SIZE 40 ; 20kB
%define FILETAB_LOC 0x7000
start:
mov [driveNum], dl ; Store the drive number
@@ -37,7 +36,7 @@ start:
mov ah, 2 ; Read from disk
int 0x13 ; Read interrupt
jnc loadKernel
jnc loadPrekernel
dec byte [counter]
jnz .read
@@ -58,20 +57,20 @@ diskErr:
cli
hlt
loadKernel:
loadPrekernel:
mov byte [counter], 3
.read:
; Location
mov ax, 0x5000 ; Making es 0x5000 will load the kernel at 0x50000
mov ax, 0x5000 ; Making es 0x5000 will load the prekernel at 0x50000
mov es, ax
xor bx, bx
; CHS Location
mov al, KERNEL_SIZE
mov al, 10 ; Prekernel size
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 7 ; Sector
mov cl, 6 ; Sector
mov dl, [driveNum]
mov ah, 2 ; Read from disk
+2 -2
View File
@@ -1,7 +1,7 @@
[bits 16]
[org 0x7e00]
%define KERNEL_LOC 0x50000
%define STAGE3_LOC 0x50000
%define VIDMEM 0xb800
start:
@@ -324,7 +324,7 @@ protected_start:
rep movsd
; Perform The far jump
jmp CODE_SEG:KERNEL_LOC
jmp CODE_SEG:STAGE3_LOC
;; Data
driveNum: db 0
+62
View File
@@ -0,0 +1,62 @@
#include <memory/physical.h>
#include <memory/virtual.h>
#include <memory/addresses.h>
#include <disk/disk.h>
#include <disk/filesys.h>
#include <screen/text.h>
__attribute__ ((section("entry")))
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
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t
uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1;
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
for (uint32_t i = 0; i < smapEntryCount; i++) {
if (smapEntries[i].type == 1) {
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
}
}
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000)
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
// Load kernel into memory
if (readFile("kernel.bin", (void*)KERNEL_LOC) != 0) { // Check if kernel.bin was loaded
// TODO: Add error messages
while (1);
}
// 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)();
}
+16
View File
@@ -0,0 +1,16 @@
/* Third stage "prekernel" */
SECTIONS {
.text 0x50000 : {
*(entry);
*(.text*);
}
.data : {
*(.data*);
}
.rodata : {
*(.rodata*);
}
.bss : {
*(.bss*);
}
}