Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ build:
i686-elf-gcc -c kstd.c -o kstd.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-elf-gcc -c console.c -o console.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-elf-gcc -c paging.c -o paging.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra

i686-elf-gcc -c pmm.c -o pmm.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra

i686-elf-gcc -T linker.ld -o myos -ffreestanding -O2 -nostdlib \
boot.o kernel.o terminal.o gdt.o gdtflush.o loadidt.o isr0.o isr.o idt.o irq.o kstd.o console.o paging.o -lgcc
boot.o kernel.o terminal.o gdt.o gdtflush.o loadidt.o isr0.o isr.o idt.o irq.o kstd.o console.o paging.o pmm.o -lgcc

mkdir -p isodir/boot/grub
cp myos isodir/boot/myos
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o myos.iso isodir

run:
qemu-system-i386 -kernel myos
qemu-system-i386 -cdrom myos.iso
clean:
rm -rf boot.o isodir kernel.o myos myos.iso terminal.o gdt.o gdtflush.o loadidt.o isr0.o idt.o isr.o irq.o kstd.o console.o paging.o
rm -rf boot.o isodir kernel.o myos myos.iso terminal.o gdt.o gdtflush.o loadidt.o isr0.o idt.o isr.o irq.o kstd.o console.o paging.o pmm.o
6 changes: 6 additions & 0 deletions console.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "kstd.h"
#include "vga.h"
#include "paging.h"
extern uint8_t _kernel_end[];
extern uint8_t _kernel_start[];

Expand Down Expand Up @@ -51,6 +52,11 @@ void handle_shell(char *input){
return;
}

if (count > 1 && strcmp(tokens[0], "wait")){
int time = stoia(tokens[1]);
kwait(time);
return;
}


terminal_writestring("Invalid command\n");
Expand Down
31 changes: 24 additions & 7 deletions isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "gdt.h" // if needed
#include "kstd.h"
#include "paging.h"

#include "pmm.h"
// Declare all 32 ISR stubs from your assembly file
extern void isr0(void);
extern void isr1(void);
Expand Down Expand Up @@ -46,6 +46,13 @@ static void (*isr_routines[32])(void) = {
isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31
};

static inline void flush_tlb(void)
{
uint32_t cr3;
__asm__ volatile("mov %%cr3, %0" : "=r"(cr3));
__asm__ volatile("mov %0, %%cr3" :: "r"(cr3));
}

// Initialize IDT entries 0–31
void isr_init(void) {
for (uint8_t i = 0; i < 32; i++) {
Expand Down Expand Up @@ -76,20 +83,30 @@ void isr_handler(int num, uint32_t err) {
terminal_writestring((err & 0x4) ? "|U" : "|S");
terminal_writestring((err & 0x8) ? "|RSVD" : "");
terminal_writestring((err & 0x10) ? "|IF" : "");
terminal_writestring("]");
terminal_writestring("]\n");

if (cr2 >= HEAP_BASE && cr2 < HEAP_LIMIT) {
uint32_t fault_addr = cr2;

uint32_t pde_index = fault_addr >> 22;
uint32_t pte_index = (fault_addr >> 12) & 0x3FF;
uint32_t phys = alloc_4mb_chunk();

page_directory[pde_index] = phys | 0x83;
if (!(page_directory[pde_index] & 1)) {
uint32_t pt_phys = pmm_alloc_frame();
memset((void*)pt_phys, 0, 4096);

page_directory[pde_index] = pt_phys | 0x3;
}

uint32_t* page_table =
(uint32_t*)(page_directory[pde_index] & 0xFFFFF000);

// Flush TLB
__asm__ volatile("mov %%cr3, %%eax; mov %%eax, %%cr3" ::: "eax");
if (!(page_table[pte_index] & 1)) {
uint32_t page_phys = pmm_alloc_frame();
page_table[pte_index] = page_phys | 0x3;
}

terminal_writestring(" Heap page mapped\n");
flush_tlb();
return;
}
}
Expand Down
31 changes: 19 additions & 12 deletions kernel.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "pmm.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Expand All @@ -8,18 +9,25 @@
#include "kstd.h"
#include "paging.h"
#include "console.h"

#include "multiboot.h"
extern uint8_t kernel_stack[];
// GDT flush expects this symbol; reserve a 16 KiB kernel stack.
uint8_t kernel_stack[16384] __attribute__((aligned(16)));
void kernel_main(uint32_t magic, void* mb_info){
if (magic != 0x2BADB002) {
terminal_writestring("Not booted with multiboot2!\n");
while (1);
}
uint64_t max[400000];
terminal_initialize();
femboysay("Welcome to eOS, Epstein OS\n");
if (magic != 0x2BADB002 && magic != 0x36D76289) {
terminal_writestring("Unknown boot magic, halting.\n");
while (1) __asm__ volatile("hlt");
}
pmm_init((uint32_t)mb_info);

uint32_t a = pmm_alloc_frame();
uint32_t b = pmm_alloc_frame();
uint32_t c = pmm_alloc_frame();


pmm_free_frame(b);
uint32_t d = pmm_alloc_frame();
femboysay("Will init GDT\n");
gdt_init();
femboysay("GDT initialized\n");
Expand All @@ -43,15 +51,14 @@ void kernel_main(uint32_t magic, void* mb_info){
femboysay("Accurate timing implemented\n");
femboysay("Will enable interrupts\n");
__asm__ volatile("sti");
wait(1);
kwait(1);
femboysay("Interrupts enabled\n");
femboysay("Will init paging\n");
init_paging();
femboysay("Paging init\n");
volatile uint32_t *x = (uint32_t*)0x00300000;
*x = 0xDEADBEEF;
terminal_writestring("4KB identity mapping works\n");
kmalloc(400000);
uint32_t* heap_test = (uint32_t*)0x40000000;
*heap_test = 1234;
terminal_writestring("Heap page allocated\n");
changeout(handle_shell,0);
while (1)
{
Expand Down
20 changes: 6 additions & 14 deletions kstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,27 +216,19 @@ void* memcpy(void* dst, const void* src, size_t n) {
//Depends on waitmode.
//If waitmode is set to 0 it will count assuming the speed is 18.2 Hz
//If waitmode is set to 1,The int passed = number of milliseconds to wait
void wait(int seconds){
void kwait (int seconds){
if(waitmode == 0){
uint64_t current = ticks;
uint64_t target = 18.2*seconds + current;
while (1)
{
if(ticks >= target){
break;
}
}
terminal_writestring("Waiting using waitmode 0 is decaprecated");
return;
}
else if (waitmode == 1)
{
uint64_t current = ticks;
uint64_t target = current+seconds;
while (1)
while (ticks < target)
{
if (ticks >= target)
{
break;
}

__asm__ volatile ("sti;hlt");

}

Expand Down
2 changes: 1 addition & 1 deletion kstd.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ size_t readbuf(uint8_t *buf);
void append_ibuf(uint8_t c);
void* memset(void* dst, int v, size_t n);
void* memcpy(void* dst, const void* src, size_t n);
void wait(int seconds);
void kwait(int seconds);
void itoa(int value, char* str, int base);
void outb(uint16_t port, uint8_t val);
uint8_t inb(uint16_t port);
Expand Down
72 changes: 25 additions & 47 deletions linker.ld
Original file line number Diff line number Diff line change
@@ -1,58 +1,36 @@
/* The bootloader will look at this image and start execution at the symbol
designated as the entry point. */

ENTRY(_start)

/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS
{
/* It used to be universally recommended to use 1M as a start offset,
as it was effectively guaranteed to be available under BIOS systems.
However, UEFI has made things more complicated, and experimental data
strongly suggests that 2M is a safer place to load. In 2016, a new
feature was introduced to the multiboot2 spec to inform bootloaders
that a kernel can be loaded anywhere within a range of addresses and
will be able to relocate itself to run from such a loader-selected
address, in order to give the loader freedom in selecting a span of
memory which is verified to be available by the firmware, in order to
work around this issue. This does not use that feature, so 2M was
chosen as a safer option than the traditional 1M. */
//. = 2M;
/* Load kernel at 2MB */
. = 2M;
_kernel_start = .;
/* First put the multiboot header, as it is required to be put very early
in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}

/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}

/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* First loadable section */
.text ALIGN(4K) :
{
/* Multiboot header must be first thing in first loadable segment */
KEEP(*(.multiboot))
*(.text*)
}

/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
.rodata ALIGN(4K) :
{
*(.rodata*)
}

/* The compiler may produce other sections, by default it will put them in
a segment with the same name. Simply add stuff here as needed. */
.data ALIGN(4K) :
{
*(.data*)
}

/*
Linker flag for kernel end
*/
.bss ALIGN(4K) :
{
*(COMMON)
*(.bss*)
}

_kernel_end = .;
}
_kernel_end = .;
}
26 changes: 26 additions & 0 deletions multiboot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef MULTIBOOT_H
#define MULTIBOOT_H

#include <stdint.h>

typedef struct {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mods_count;
uint32_t mods_addr;
uint32_t syms[4];
uint32_t mmap_length;
uint32_t mmap_addr;
} multiboot_info_t;

typedef struct {
uint32_t size;
uint64_t base_addr;
uint64_t length;
uint32_t type;
} multiboot_memory_map_t;

#endif
7 changes: 6 additions & 1 deletion paging.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ uint32_t first_page_table[1024] __attribute__((aligned(4096)));
static uint32_t placement = 0;
static uint32_t heap_brk = HEAP_BASE;

void* kmalloc(uint32_t size)
{
size = (size + 7) & ~7;

void* kmalloc(uint32_t size) {
uint32_t addr = heap_brk;
heap_brk += size;

if (heap_brk + size >= HEAP_LIMIT) panic("heap exhausted");

return (void*)addr;
}

Expand Down
5 changes: 2 additions & 3 deletions paging.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#ifndef PAGING_H
#define PAGING_H

#define HEAP_BASE 0x01000000 // 16MB
#define HEAP_LIMIT 0x04000000
#define HEAP_BASE 0x40000000
#define HEAP_LIMIT 0x80000000
extern uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t alloc_4mb_chunk();
void init_paging(void);
Expand Down
Loading