forked from PoliEcho-holding-org/kern
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:
@@ -24,12 +24,12 @@ filesystem: bootloader kernel $(C_FILES) $(FONTS)
|
|||||||
@dd if=/dev/zero of=kern.iso bs=512 count=2880 status=none
|
@dd if=/dev/zero of=kern.iso bs=512 count=2880 status=none
|
||||||
# TODO: Make this not so manual
|
# 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)/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)/filetable.bin of=kern.iso bs=512 seek=15 conv=notrunc status=none
|
||||||
@dd if=$(BUILD)/kernel.bin of=kern.iso bs=512 seek=6 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=46 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=50 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=54 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=55 conv=notrunc status=none
|
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=65 conv=notrunc status=none
|
||||||
|
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@[ -d $(BUILD) ] || mkdir $(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
|
@$(AS) -fbin -o $(BUILD)/stage1.bin $(SRC)/stage1.asm
|
||||||
@echo "Assembling $(SRC)/stage2.asm..."
|
@echo "Assembling $(SRC)/stage2.asm..."
|
||||||
@$(AS) -fbin -o $(BUILD)/stage2.bin $(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: This target is responsible for creating kernel.bin
|
||||||
kernel: $(SRC)/kernel.c
|
kernel: $(SRC)/kernel.c
|
||||||
@echo "Compiling $(SRC)/kernel.c..."
|
@echo "Compiling $(SRC)/kernel.c..."
|
||||||
@$(CC) $(CFLAGS) -Iinclude -o $(BUILD)/kernel.o -c $(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
|
@$(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):
|
$(C_FILES):
|
||||||
@echo "Compiling $(SRC)/$@.c..."
|
@echo "Compiling $(SRC)/$@.c..."
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ Graphics test: \
|
|||||||
_These images may be outdated, Idk_
|
_These images may be outdated, Idk_
|
||||||
|
|
||||||
## Known issues
|
## 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)
|
- 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 :(
|
- 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
|
- Not really an issue, bit QEMU's PIT is really slow and inacurate
|
||||||
|
|
||||||
## [Old Version](https://github.com/Tom-on64/old-kern)
|
## [Old Version](https://github.com/Tom-on64/old-kern)
|
||||||
|
|||||||
@@ -48,14 +48,15 @@ void updateFiletable() {
|
|||||||
// TODO: Update the filetable by writing data from memory to disk!
|
// 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);
|
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);
|
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);
|
fileEntry_t* file = findFile(filetable);
|
||||||
if (file == NULL) { // File exists -> override
|
if (file == NULL) { // File exists -> override
|
||||||
// File doesn't exist -> create new file
|
// 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
|
diskWrite(file->startAddress, file->length, buffer); // Write the file
|
||||||
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFiletable(char* ft) {
|
void printFiletable(char* ft) {
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
#ifndef ADDRESSES_H
|
#ifndef ADDRESSES_H
|
||||||
#define ADDRESSES_H
|
#define ADDRESSES_H
|
||||||
|
|
||||||
#define MEMMAP_AREA 0x30000
|
// Locations
|
||||||
#define KERNEL_LOC 0x50000
|
#define KERNEL_LOC 0x100000
|
||||||
#define FILETABLE_LOC 0x7000
|
#define FILETABLE_LOC 0x7000
|
||||||
#define SMAP_ENTRY_COUNT 0x8500
|
|
||||||
#define SMAP_ENTRIES 0x8504
|
// 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
|
#endif
|
||||||
|
|||||||
+9
-7
@@ -10,13 +10,15 @@
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
filetable:
|
filetable:
|
||||||
db "boot",0,0,0,0,0,0, "bin",0,0,5
|
db "boot",0,0,0,0,0,0, "bin",0,0,1
|
||||||
db "filetable",0, "tab",0,5,1
|
db "stage2",0,0,0,0, "bin",0,1,4
|
||||||
db "kernel",0,0,0,0, "bin",0,6,40
|
db "stage3",0,0,0,0, "bin",0,5,10
|
||||||
db "term16n",0,0,0, "fnt",0,46,4
|
db "filetable",0, "tab",0,15,1
|
||||||
db "testfont",0,0, "fnt",0,50,4
|
db "kernel",0,0,0,0, "bin",0,16,40
|
||||||
db "test",0,0,0,0,0,0, "txt",0,54,1
|
db "term16n",0,0,0, "fnt",0,56,4
|
||||||
db "calc",0,0,0,0,0,0, "bin",0,55,2
|
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
|
times 512-($-$$) db 0
|
||||||
|
|
||||||
|
|||||||
+7
-31
@@ -29,7 +29,12 @@ void printPhysicalMemmap();
|
|||||||
|
|
||||||
__attribute__ ((section("entry")))
|
__attribute__ ((section("entry")))
|
||||||
void main() {
|
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
|
// Interrupt setup
|
||||||
setupIdt();
|
setupIdt();
|
||||||
setupExceptions();
|
setupExceptions();
|
||||||
@@ -42,40 +47,11 @@ void main() {
|
|||||||
setupTimer();
|
setupTimer();
|
||||||
setupRtc();
|
setupRtc();
|
||||||
setupKeyboard();
|
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
|
// Screen setup
|
||||||
readFile("term16n.fnt", font);
|
readFile("term16n.fnt", font);
|
||||||
clear();
|
clear();
|
||||||
print("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
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
SECTIONS {
|
SECTIONS {
|
||||||
.text 0x50000 : {
|
.text 0xC0000000 : {
|
||||||
*(entry);
|
*(entry);
|
||||||
*(.text*);
|
*(.text*);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-7
@@ -3,8 +3,7 @@
|
|||||||
[global start]
|
[global start]
|
||||||
|
|
||||||
%define VIDMEM 0xb800
|
%define VIDMEM 0xb800
|
||||||
%define FILETAB_LOC 0x7000 ; TODO: Read kernel size and location from ft
|
%define FILETAB_LOC 0x7000
|
||||||
%define KERNEL_SIZE 40 ; 20kB
|
|
||||||
|
|
||||||
start:
|
start:
|
||||||
mov [driveNum], dl ; Store the drive number
|
mov [driveNum], dl ; Store the drive number
|
||||||
@@ -37,7 +36,7 @@ start:
|
|||||||
mov ah, 2 ; Read from disk
|
mov ah, 2 ; Read from disk
|
||||||
int 0x13 ; Read interrupt
|
int 0x13 ; Read interrupt
|
||||||
|
|
||||||
jnc loadKernel
|
jnc loadPrekernel
|
||||||
|
|
||||||
dec byte [counter]
|
dec byte [counter]
|
||||||
jnz .read
|
jnz .read
|
||||||
@@ -58,20 +57,20 @@ diskErr:
|
|||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
loadKernel:
|
loadPrekernel:
|
||||||
mov byte [counter], 3
|
mov byte [counter], 3
|
||||||
|
|
||||||
.read:
|
.read:
|
||||||
; Location
|
; 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
|
mov es, ax
|
||||||
xor bx, bx
|
xor bx, bx
|
||||||
|
|
||||||
; CHS Location
|
; CHS Location
|
||||||
mov al, KERNEL_SIZE
|
mov al, 10 ; Prekernel size
|
||||||
mov ch, 0 ; Cylinder
|
mov ch, 0 ; Cylinder
|
||||||
mov dh, 0 ; Head
|
mov dh, 0 ; Head
|
||||||
mov cl, 7 ; Sector
|
mov cl, 6 ; Sector
|
||||||
mov dl, [driveNum]
|
mov dl, [driveNum]
|
||||||
|
|
||||||
mov ah, 2 ; Read from disk
|
mov ah, 2 ; Read from disk
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
[bits 16]
|
[bits 16]
|
||||||
[org 0x7e00]
|
[org 0x7e00]
|
||||||
|
|
||||||
%define KERNEL_LOC 0x50000
|
%define STAGE3_LOC 0x50000
|
||||||
%define VIDMEM 0xb800
|
%define VIDMEM 0xb800
|
||||||
|
|
||||||
start:
|
start:
|
||||||
@@ -324,7 +324,7 @@ protected_start:
|
|||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
; Perform The far jump
|
; Perform The far jump
|
||||||
jmp CODE_SEG:KERNEL_LOC
|
jmp CODE_SEG:STAGE3_LOC
|
||||||
|
|
||||||
;; Data
|
;; Data
|
||||||
driveNum: db 0
|
driveNum: db 0
|
||||||
|
|||||||
@@ -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)();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/* Third stage "prekernel" */
|
||||||
|
SECTIONS {
|
||||||
|
.text 0x50000 : {
|
||||||
|
*(entry);
|
||||||
|
*(.text*);
|
||||||
|
}
|
||||||
|
.data : {
|
||||||
|
*(.data*);
|
||||||
|
}
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata*);
|
||||||
|
}
|
||||||
|
.bss : {
|
||||||
|
*(.bss*);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user