memory #7
2
Makefile
2
Makefile
@@ -1,4 +1,4 @@
|
|||||||
SOURCES = src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
SOURCES = src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||||
|
|
||||||
build:
|
build:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
// Terminal output
|
// Terminal output
|
||||||
|
/*
|
||||||
|
There are a couple of bugs here and there but for now I don't care too much
|
||||||
|
because this shitty implementation will be replaced one day by Flanterm
|
||||||
|
(once memory management is okay: paging & kernel malloc)
|
||||||
|
*/
|
||||||
|
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ enum ErrorCodes
|
|||||||
#include "io/serial/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "io/term/printf.h"
|
#include "io/term/printf.h"
|
||||||
|
|
||||||
// Still lacks print formatting...
|
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__)
|
||||||
#define DEBUG(log, ...) \
|
|
||||||
printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__); \
|
|
||||||
fctprintf((void*)&skputc, 0, "debug: [%s]: %s\n", __FILE__, log)
|
|
||||||
|
|
||||||
|
// printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
14
src/kmain.c
14
src/kmain.c
@@ -22,6 +22,13 @@ static volatile struct limine_framebuffer_request framebuffer_request = {
|
|||||||
.revision = 0
|
.revision = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Memory map request
|
||||||
|
__attribute__((used, section(".limine_requests")))
|
||||||
|
static volatile struct limine_memmap_request memmap_request = {
|
||||||
|
.id = LIMINE_MEMMAP_REQUEST,
|
||||||
|
.revision = 0
|
||||||
|
};
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests_start")))
|
__attribute__((used, section(".limine_requests_start")))
|
||||||
static volatile LIMINE_REQUESTS_START_MARKER;
|
static volatile LIMINE_REQUESTS_START_MARKER;
|
||||||
|
|
||||||
@@ -51,17 +58,20 @@ void kmain()
|
|||||||
term_init();
|
term_init();
|
||||||
serial_init();
|
serial_init();
|
||||||
|
|
||||||
|
if (memmap_request.response == NULL) hcf();
|
||||||
|
memmap_display(memmap_request.response);
|
||||||
|
|
||||||
CLEAR_INTERRUPTS;
|
CLEAR_INTERRUPTS;
|
||||||
gdt_init();
|
gdt_init();
|
||||||
idt_init();
|
idt_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
SET_INTERRUPTS;
|
SET_INTERRUPTS;
|
||||||
|
|
||||||
keyboard_init(FR);
|
//keyboard_init(FR);
|
||||||
|
|
||||||
// Draw something
|
// Draw something
|
||||||
printf("%s, %s!\n", "Hello", "world");
|
printf("%s, %s!\n", "Hello", "world");
|
||||||
// Yoohoooooo!
|
// Yoohoooooo!
|
||||||
DEBUG("kernel initialized successfully! hanging... wow=%d", 42);
|
//DEBUG("kernel initialized successfully! hanging... wow=%d", 42);
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <limine.h>
|
||||||
|
#include "../../kernel.h"
|
||||||
|
#include "../../string/string.h"
|
||||||
|
|
||||||
// We won't be linked to standard library, but still need the basic mem* functions
|
// We won't be linked to standard library, but still need the basic mem* functions
|
||||||
// so everything goes allright with the compiler
|
// so everything goes allright with the compiler
|
||||||
@@ -68,3 +71,46 @@ int memcmp(const void* s1, const void* s2, size_t n)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display the memmap so we see how the memory is laid out at handoff
|
||||||
|
void memmap_display(struct limine_memmap_response* response)
|
||||||
|
{
|
||||||
|
DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count);
|
||||||
|
|
||||||
|
for (size_t i=0; i<response->entry_count; i++)
|
||||||
|
{
|
||||||
|
struct limine_memmap_entry* entry = response->entries[i];
|
||||||
|
char type[32] = {0};
|
||||||
|
switch(entry->type)
|
||||||
|
{
|
||||||
|
case LIMINE_MEMMAP_USABLE:
|
||||||
|
strcpy(type, "USABLE");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_RESERVED:
|
||||||
|
strcpy(type, "RESERVED");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
|
||||||
|
strcpy(type, "ACPI_RECLAIMABLE");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_ACPI_NVS:
|
||||||
|
strcpy(type, "ACPI_NVS");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_BAD_MEMORY:
|
||||||
|
strcpy(type, "BAD_MEMORY");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
|
||||||
|
strcpy(type, "BOOTLOADER_RECLAIMABLE");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
|
||||||
|
strcpy(type, "KERNEL_AND_MODULES");
|
||||||
|
break;
|
||||||
|
case LIMINE_MEMMAP_FRAMEBUFFER:
|
||||||
|
strcpy(type, "FRAMEBUFFER");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(type, "UNKNOWN");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DEBUG("entry %u: [%016x | %u bytes] - %s", i, entry->base, entry->length, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,4 +8,6 @@ void* memset(void* s, int c, size_t n);
|
|||||||
void* memmove(void *dest, const void* src, size_t n);
|
void* memmove(void *dest, const void* src, size_t n);
|
||||||
int memcmp(const void* s1, const void* s2, size_t n);
|
int memcmp(const void* s1, const void* s2, size_t n);
|
||||||
|
|
||||||
|
void memmap_display(struct limine_memmap_response* response);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
16
src/mem/paging/paging.h
Normal file
16
src/mem/paging/paging.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef PAGING_PMM_H
|
||||||
|
#define PAGING_PMM_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
We are going to use a bitmap, consisting of an array of uint64_t
|
||||||
|
to represent pages for the PMM (physical memory manager).
|
||||||
|
|
||||||
|
Bit set (1) = page used
|
||||||
|
Bit clear (0) = page free
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define BITS_PER_ROW 64
|
||||||
|
|
||||||
|
#endif
|
||||||
17
src/mem/paging/pmm.c
Normal file
17
src/mem/paging/pmm.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// OMG here we are. I'm cooked.
|
||||||
|
|
||||||
|
/*
|
||||||
|
pmm - Physical Memory Manager
|
||||||
|
will manage 4kb pages physically
|
||||||
|
it will probably need to get some info from Limine,
|
||||||
|
to see which pages are used by kernel/bootloader/mmio/fb etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "paging.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
First we'll have to discover the physical memory layout,
|
||||||
|
and for that we can use a Limine request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint64_t pages_bitmap[];
|
||||||
6
src/string/string.c
Normal file
6
src/string/string.c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
char* strcpy(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
char *temp = dest;
|
||||||
|
while((*dest++ = *src++));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
6
src/string/string.h
Normal file
6
src/string/string.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef STRING_H
|
||||||
|
#define STRING_H
|
||||||
|
|
||||||
|
char *strcpy(char *dest, const char *src);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user