mm stuff
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,3 +9,5 @@
|
|||||||
|
|
||||||
build
|
build
|
||||||
isodir
|
isodir
|
||||||
|
|
||||||
|
compiler*/
|
||||||
@@ -1,19 +1,308 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"file": "kernel/kmain.c",
|
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
"-c",
|
"-c",
|
||||||
"kernel/kmain.c",
|
|
||||||
"-o",
|
|
||||||
"obj/kernel/kmain.o",
|
|
||||||
"-ffreestanding",
|
"-ffreestanding",
|
||||||
"-O2",
|
"-O2",
|
||||||
"-Wall",
|
"-Wall",
|
||||||
"-Wextra",
|
"-Wextra",
|
||||||
"-Ikernel"
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/globals.o",
|
||||||
|
"kernel/globals.c"
|
||||||
],
|
],
|
||||||
"directory": "/home/slinky/source/RockOS",
|
"directory": "/home/slinky/source/RockOS",
|
||||||
"output": "obj/kernel/kmain.o"
|
"file": "/home/slinky/source/RockOS/kernel/globals.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/globals.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/kmain.o",
|
||||||
|
"kernel/kmain.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/kmain.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/kmain.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/idt.o",
|
||||||
|
"kernel/idt.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/idt.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/idt.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/pic/pic.o",
|
||||||
|
"kernel/drivers/pic/pic.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/vga/vga_stream_writer.o",
|
||||||
|
"kernel/drivers/vga/vga_stream_writer.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga_stream_writer.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga_stream_writer.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/ps2/ps2.o",
|
||||||
|
"kernel/drivers/ps2/ps2.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/gdt.o",
|
||||||
|
"kernel/gdt.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/gdt.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/gdt.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/memory/mm.o",
|
||||||
|
"kernel/memory/mm.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/memory/mm.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/interrupts.o",
|
||||||
|
"kernel/interrupts.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/interrupts.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/interrupts.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/stream.o",
|
||||||
|
"kernel/lib/stream.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/stream.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/stream.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/print.o",
|
||||||
|
"kernel/lib/print.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/print.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/print.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/pic/pic_stubs.o",
|
||||||
|
"kernel/drivers/pic/pic_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic_stubs.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/pit/pit_stubs.o",
|
||||||
|
"kernel/drivers/pit/pit_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit_stubs.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/ps2/ps2_stubs.o",
|
||||||
|
"kernel/drivers/ps2/ps2_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2_stubs.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/boot/boot.o",
|
||||||
|
"kernel/boot/boot.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/boot/boot.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/boot/boot.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/gdt_stubs.o",
|
||||||
|
"kernel/gdt_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/gdt_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/gdt_stubs.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/common_stubs.o",
|
||||||
|
"kernel/common_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/common_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/common_stubs.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/idt_stubs.o",
|
||||||
|
"kernel/idt_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/idt_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/idt_stubs.o"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -21,6 +21,8 @@ stack_top:
|
|||||||
_start:
|
_start:
|
||||||
cli
|
cli
|
||||||
mov $stack_top, %esp
|
mov $stack_top, %esp
|
||||||
|
push %ebx
|
||||||
|
push %eax
|
||||||
call kmain
|
call kmain
|
||||||
loop:
|
loop:
|
||||||
jmp loop
|
jmp loop
|
||||||
|
|||||||
@@ -14,13 +14,3 @@ enable_interrupts:
|
|||||||
io_wait:
|
io_wait:
|
||||||
outb %al, $0x80
|
outb %al, $0x80
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global load_grub_boot_struct
|
|
||||||
load_grub_boot_struct:
|
|
||||||
mov %ebx, grub_boot_struct_ptr
|
|
||||||
|
|
||||||
.section .bss
|
|
||||||
.align 4
|
|
||||||
.global grub_boot_struct_ptr
|
|
||||||
grub_boot_struct_ptr:
|
|
||||||
.int 0
|
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "multiboot.h"
|
||||||
|
|
||||||
print_stream_t* kout;
|
print_stream_t* kout;
|
||||||
|
multiboot_info* grub_boot_struct_ptr = NULL;
|
||||||
|
|
||||||
|
extern char __kernel_start;
|
||||||
|
extern char __kernel_end;
|
||||||
|
size_t kernel_size() {
|
||||||
|
return (size_t)(&__kernel_end - &__kernel_start);
|
||||||
|
}
|
||||||
@@ -44,9 +44,7 @@ void common_interrupt_handler(struct registers *args) {
|
|||||||
case 14:
|
case 14:
|
||||||
case 15:
|
case 15:
|
||||||
case 16:
|
case 16:
|
||||||
kprint("CPU Error: ");
|
kprintf("CPU Error: %s", err_messages[args->int_no]);
|
||||||
kprint(err_messages[args->int_no]);
|
|
||||||
kprint("\n");
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
// wake the PIT timer driver
|
// wake the PIT timer driver
|
||||||
@@ -58,7 +56,7 @@ void common_interrupt_handler(struct registers *args) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
kprint("Received unhandled interrupt\n");
|
kprintf("Received unhandled interrupt: %d\n", args->int_no);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
|
#include "multiboot.h"
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
|
|
||||||
#include <idt.h>
|
#include <idt.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "memory/mm.h"
|
||||||
|
|
||||||
extern void init_idt();
|
extern void init_idt();
|
||||||
extern void init_gdt();
|
extern void init_gdt();
|
||||||
extern void init_pic();
|
extern void init_pic();
|
||||||
@@ -12,40 +16,51 @@ extern void init_pit();
|
|||||||
extern int init_ps2();
|
extern int init_ps2();
|
||||||
extern void enable_interrupts();
|
extern void enable_interrupts();
|
||||||
|
|
||||||
extern void load_grub_boot_struct(void);
|
void* page = NULL;
|
||||||
|
|
||||||
extern void* grub_boot_struct_ptr;
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
|
|
||||||
void kmain(void)
|
|
||||||
{
|
|
||||||
extern print_stream_t vga_print_stream;
|
extern print_stream_t vga_print_stream;
|
||||||
extern print_stream_t* kout;
|
extern print_stream_t* kout;
|
||||||
kout = &vga_print_stream;
|
kout = &vga_print_stream;
|
||||||
kout->trunc();
|
kout->trunc();
|
||||||
|
|
||||||
kprint("RockOS booting...\n");
|
kprintf("RockOS booting...\n");
|
||||||
|
|
||||||
init_gdt();
|
init_gdt();
|
||||||
kprint("GDT set\n");
|
kprintf("GDT set\n");
|
||||||
|
|
||||||
init_idt();
|
init_idt();
|
||||||
kprint("IDT set\n");
|
kprintf("IDT set\n");
|
||||||
|
|
||||||
init_pic();
|
init_pic();
|
||||||
kprint("PIC initialized\n");
|
kprintf("PIC initialized\n");
|
||||||
|
|
||||||
init_pit();
|
init_pit();
|
||||||
kprint("PIT initialized\n");
|
kprintf("PIT initialized\n");
|
||||||
|
|
||||||
int result = init_ps2();
|
int result = init_ps2();
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
kprint("PS2 init failed\n");
|
kprintf("PS2 init failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
kprint("PS2 initialized\n");
|
kprintf("PS2 initialized\n");
|
||||||
|
|
||||||
|
if (!(mbi->flags & (1 << 6))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_mm((void*)mbi->mmap_addr, mbi->mmap_length);
|
||||||
|
uint32_t mem_size = total_free_memory();
|
||||||
|
kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024);
|
||||||
|
|
||||||
|
page = alloc_page();
|
||||||
|
kprintf("Allocated page at: 0x%x\n", (uint32_t)page);
|
||||||
|
|
||||||
|
free_page(page);
|
||||||
|
kprintf("Freed page");
|
||||||
|
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
kprint("Interrupts enabled\n");
|
kprintf("Interrupts enabled\n");
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,91 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
extern print_stream_t* kout;
|
extern print_stream_t* kout;
|
||||||
|
static char* hex_chars = "0123456789abcdef";
|
||||||
|
|
||||||
void kprint(const char *str) {
|
static void kprint(const char *str) {
|
||||||
while (*str) {
|
while (*str) {
|
||||||
kout->putchar(*str);
|
kout->putchar(*str);
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kputd(int d) {
|
||||||
|
if (d == 0) {
|
||||||
|
kout->putchar('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buffer[12];
|
||||||
|
int i = 0;
|
||||||
|
while (d > 0) {
|
||||||
|
buffer[i++] = '0' + (d % 10);
|
||||||
|
d /= 10;
|
||||||
|
}
|
||||||
|
for (int j = i - 1; j >= 0; j--) {
|
||||||
|
kout->putchar(buffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kputx(unsigned int x) {
|
||||||
|
if (x == 0) {
|
||||||
|
kout->putchar('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buffer[8];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (x > 0) {
|
||||||
|
buffer[i++] = hex_chars[x & 0xF];
|
||||||
|
x >>= 4;
|
||||||
|
}
|
||||||
|
for (int j = i - 1; j >= 0; j--) {
|
||||||
|
kout->putchar(buffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kputc(const char c) {
|
void kputc(const char c) {
|
||||||
kout->putchar(c);
|
kout->putchar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kprintf(const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
while (*fmt) {
|
||||||
|
if (*fmt == '%') {
|
||||||
|
fmt++;
|
||||||
|
switch (*fmt) {
|
||||||
|
case 's': {
|
||||||
|
const char* str = va_arg(args, const char*);
|
||||||
|
kprint(str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd': {
|
||||||
|
int d = va_arg(args, int);
|
||||||
|
kputd(d);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x': {
|
||||||
|
unsigned int x = va_arg(args, unsigned int);
|
||||||
|
kputx(x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '%':
|
||||||
|
kout->putchar('%');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
kout->putchar('%');
|
||||||
|
kout->putchar(*fmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fmt++;
|
||||||
|
} else {
|
||||||
|
kout->putchar(*fmt);
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef KLIBPRINT_H
|
#ifndef KLIBPRINT_H
|
||||||
#define KLIBPRINT_H
|
#define KLIBPRINT_H
|
||||||
|
|
||||||
void kprint(const char* str);
|
|
||||||
void kputc(const char c);
|
void kputc(const char c);
|
||||||
|
void kprintf(const char* fmt, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3,6 +3,7 @@ ENTRY(_start)
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 2M;
|
. = 2M;
|
||||||
|
__kernel_start = .;
|
||||||
|
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
@@ -25,4 +26,5 @@ SECTIONS
|
|||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss)
|
*(.bss)
|
||||||
}
|
}
|
||||||
|
__kernel_end = .;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,46 @@
|
|||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
extern uint8_t __kernel_start;
|
||||||
|
extern uint8_t __kernel_end;
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define MAX_RAM 0xFFFFFFFF // 4GB
|
||||||
|
#define BITMAP_SIZE ((MAX_RAM / PAGE_SIZE) / 8)
|
||||||
|
|
||||||
static uint32_t max_address = 0;
|
static uint32_t max_address = 0;
|
||||||
static uint32_t total_available_memory = 0;
|
static uint32_t total_available_memory = 0;
|
||||||
|
static uint8_t memory_bitmap[BITMAP_SIZE];
|
||||||
|
|
||||||
void parse_mmap(void* base, uint32_t limit) {
|
static void mark_free(uint32_t addr) {
|
||||||
|
uint32_t page_index = addr / PAGE_SIZE;
|
||||||
|
uint32_t byte_index = page_index / 8;
|
||||||
|
uint32_t bit_index = page_index % 8;
|
||||||
|
memory_bitmap[byte_index] &= ~(1 << bit_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mark_used(uint32_t addr) {
|
||||||
|
uint32_t page_index = addr / PAGE_SIZE;
|
||||||
|
uint32_t byte_index = page_index / 8;
|
||||||
|
uint32_t bit_index = page_index % 8;
|
||||||
|
memory_bitmap[byte_index] |= (1 << bit_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t align(uint32_t addr, uint32_t len, uint32_t* usable_start, uint32_t* usable_end) {
|
||||||
|
uint32_t start = addr;
|
||||||
|
uint32_t end = addr + len;
|
||||||
|
*usable_start = (start + 4095) & ~0xFFF;
|
||||||
|
*usable_end = end & ~0xFFF;
|
||||||
|
return *usable_end - *usable_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_multiboot_mmap(void* base, uint32_t limit) {
|
||||||
multiboot_mmap_entry* entry = (multiboot_mmap_entry*)base;
|
multiboot_mmap_entry* entry = (multiboot_mmap_entry*)base;
|
||||||
void* end = (void*)((uint32_t)base + limit);
|
void* end = (void*)((uint32_t)base + limit);
|
||||||
|
total_available_memory = 0;
|
||||||
while ((void*)entry < end) {
|
while ((void*)entry < end) {
|
||||||
|
uint32_t entry_size = entry->size + sizeof(entry->size);
|
||||||
if (entry->type == 1) {
|
if (entry->type == 1) {
|
||||||
uint32_t region_start = (uint32_t)(entry->addr);
|
uint32_t region_start = (uint32_t)(entry->addr);
|
||||||
uint32_t region_end = (uint32_t)(entry->addr + entry->len);
|
uint32_t region_end = (uint32_t)(entry->addr + entry->len);
|
||||||
@@ -15,23 +48,67 @@ void parse_mmap(void* base, uint32_t limit) {
|
|||||||
max_address = region_end;
|
max_address = region_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_available_memory += entry->len;
|
uint32_t usable_start, usable_end, usable_size;
|
||||||
|
usable_size = align(region_start, entry->len, &usable_start, &usable_end);
|
||||||
// start breaking up the address range
|
if (usable_size <= 4096) {
|
||||||
// if it's safe (not kernel, not BIOS structures, etc..), find the corresponding page in our PMM, mark it free
|
|
||||||
// need to align start and end to 4kb
|
|
||||||
if (entry->len < 4096) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t addr = region_start; addr < region_end; addr += 4096) {
|
for (uint32_t addr = usable_start; addr < usable_end; addr += 4096) {
|
||||||
// check for physical kernel address range
|
if (addr <= (uint32_t)&__kernel_end && addr >= (uint32_t)&__kernel_start) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// check if this address range contains our multiboot structure
|
if (addr >= (uint32_t)entry && addr <= (uint32_t)entry + entry_size) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// don't allow pages under 1MB
|
if (addr <= 0x200000) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_available_memory += 4096;
|
||||||
|
|
||||||
|
mark_free(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry = (multiboot_mmap_entry*)((uint32_t)entry + entry->size + sizeof(entry->size));
|
entry = (multiboot_mmap_entry*)((uint32_t)entry + entry_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_mm(void* mmap_base, uint32_t mmap_limit) {
|
||||||
|
for (int i = 0; i < BITMAP_SIZE; i++) {
|
||||||
|
memory_bitmap[i] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmap_base != NULL && mmap_limit > 0) {
|
||||||
|
parse_multiboot_mmap(mmap_base, mmap_limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t total_free_memory() {
|
||||||
|
return total_available_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* alloc_page() {
|
||||||
|
for (uint32_t i = 0; i < BITMAP_SIZE; i++) {
|
||||||
|
uint8_t b = memory_bitmap[i];
|
||||||
|
if (b == 0xFF) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int bit = 0; bit < 8; bit++) {
|
||||||
|
if ((b & (1 << bit)) == 0) {
|
||||||
|
uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE;
|
||||||
|
mark_used(page_addr);
|
||||||
|
return (void*)page_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_page(void* addr) {
|
||||||
|
mark_free((uint32_t)addr);
|
||||||
|
}
|
||||||
16
kernel/memory/mm.h
Normal file
16
kernel/memory/mm.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef KMM_H
|
||||||
|
#define KMM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint32_t addr;
|
||||||
|
} mem_page_t;
|
||||||
|
|
||||||
|
void init_mm(void* mmap_base, uint32_t mmap_limit);
|
||||||
|
uint32_t total_free_memory();
|
||||||
|
|
||||||
|
void* alloc_page();
|
||||||
|
void free_page(void* addr);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user