summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/include/libc.h2
-rw-r--r--src/kernel/include/paging.h27
-rw-r--r--src/kernel/include/video.h2
-rw-r--r--src/kernel/kernel.c22
-rw-r--r--src/kernel/libs/acpi.c5
-rw-r--r--src/kernel/libs/drivers/serial.c20
-rw-r--r--src/kernel/libs/drivers/video.c3
-rw-r--r--src/kernel/libs/libc.c19
-rw-r--r--src/kernel/libs/page.c108
9 files changed, 137 insertions, 71 deletions
diff --git a/src/kernel/include/libc.h b/src/kernel/include/libc.h
index 7e837ae..cdf6dbc 100644
--- a/src/kernel/include/libc.h
+++ b/src/kernel/include/libc.h
@@ -7,4 +7,6 @@ int strncmp(const char *str1, const char *str2, size_t n);
void strcpy(char *dest, char *src);
void memcpy(void *dest, void *src, size_t n); //TODO
int memcmp(const void *s1, const void *s2, size_t n);
+void bzero(const void *dest, size_t size);
+int ceil(float n1);
#endif
diff --git a/src/kernel/include/paging.h b/src/kernel/include/paging.h
index 3b89af9..267da43 100644
--- a/src/kernel/include/paging.h
+++ b/src/kernel/include/paging.h
@@ -24,7 +24,7 @@ typedef struct __attribute__((packed)) {
unsigned int software_marks : 3; // available for our own use, I doubt we'll use it in such a simple thing
uintptr_t base_ptr : 40;
- unsigned int available:11;
+ unsigned int sign:11;
} page_entry;
@@ -35,11 +35,11 @@ typedef struct __attribute__((packed)) {
page_entry pte[512];
} page_table;
-#define MEM_AVAILABLE 0
-#define MEM_RESERVED 1
-#define MEM_APCI_RECLAIMABLE 2
-#define MEM_APCI_NVS 3
-#define MEM_BAD 4
+#define MEM_AVAILABLE 1
+#define MEM_RESERVED 2
+#define MEM_APCI_RECLAIMABLE 3
+#define MEM_APCI_NVS 4
+#define MEM_BAD 5
#define PAGE_SIZE_4K 12
#define PAGE_SIZE_2M 21
@@ -49,12 +49,23 @@ struct memory_table {
uint64_t base;
uint64_t length;
uint32_t type;
- uint32_t ACPI; //we'll never use this
+ uint32_t ACPI;
+} __attribute__((packed));
+
+struct phys_map {
+ uint64_t map_size; //this way we won't have to calculate it every time
+ void *chunk_start;
+ uint64_t chunk_size;
+ uint64_t *buddies;
} __attribute__((packed));
extern void* _meminfo_loc;
+extern void* _stage2_pagetable;
-bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t PAGE_SIZE);
+bool map_page(void *virtual_addr, void *physical_addr, uint8_t PAGE_SIZE);
void debug_print_memory();
+void create_pagetable_stage2(uint64_t free_mem);
+void init_memory();
#endif
+
diff --git a/src/kernel/include/video.h b/src/kernel/include/video.h
index 6f702b1..82d3423 100644
--- a/src/kernel/include/video.h
+++ b/src/kernel/include/video.h
@@ -47,3 +47,5 @@ struct vbe_infoblock {
uint32_t videomodeptr;
uint16_t total_memory;
} __attribute__((packed));
+
+extern void *_vbe_infoblock;
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 8db2e50..d7fc3e0 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -15,28 +15,20 @@ void main() {
if(!(init_serial(COM1))) {
printf("\nKernal started on CPU 1!\n"); // will detect cpu later
}
-
+
rsdp_t *rsdp;
- struct memory_table *table = (struct memory_table *)&_meminfo_loc;
- struct vbe_infoblock *vbe_info = (struct vbe_infoblock *)0x500;
- debug_print_memory();
-
rsdp = find_RSDP();
if(!(rsdp)) {
- printf("Couldn't find the RSDP... uhh, not sure what to do now.\n");
+ printf("Couldn't find the RSDP... not sure what to do now.\n");
panic();
}
+
+
dump_video();
-
- if(rsdp->v1.version) {
- map_page(0x200000, (rsdp->v2.xsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K);
- }
- else {
- map_page(0x200000, (rsdp->v1.rsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K);
- struct acpi_header *acpi = (struct acpi_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000));
- }
+ debug_print_memory();
+
+ init_memory();
- printf("kernel is done, you can ignore this panic\n");
panic();
}
diff --git a/src/kernel/libs/acpi.c b/src/kernel/libs/acpi.c
index 8bc6a56..0c22fe4 100644
--- a/src/kernel/libs/acpi.c
+++ b/src/kernel/libs/acpi.c
@@ -31,16 +31,13 @@ static int RSDP_verify(void *rsdp_pointer) {
return 1;
}
-// TODO: move these when you gain your sanity
-rsdp_t *find_RSDP() { // finds root descriptor
+rsdp_t *find_RSDP() {
const char sig[9] = "RSD PTR ";
uintptr_t *p = (void *)0x040e;
uintptr_t *ebda_unshifted = (void *)p;
- // TODO you REALLY need to verify this.
void *ebda = (void *)((uintptr_t)ebda_unshifted << (uintptr_t)4 & (uintptr_t)0xfffff);
-
for(void *i = ebda; i <= ebda + 64000; i += 16) {
if(!(memcmp(sig, i, 8))) {
if(RSDP_verify(i)) {
diff --git a/src/kernel/libs/drivers/serial.c b/src/kernel/libs/drivers/serial.c
index 665f06c..25f89ad 100644
--- a/src/kernel/libs/drivers/serial.c
+++ b/src/kernel/libs/drivers/serial.c
@@ -1,10 +1,6 @@
#include <stdint.h>
#include <serial.h>
-//you can add more options if you need to later
-// PORT + 3: values are from bit zero (right) to left
-// dlab(1) | misteryyy bone(1) | paraty(3) | stop bits (1) | character length (2)
static inline void outb(uint16_t port, uint8_t value) {
- //here "a" is the a register, and "Nd" is inteter (I think?) in the d register
asm volatile(
"outb %0, %1" :: "a"(value), "Nd"(port)
);
@@ -19,14 +15,14 @@ static inline uint8_t inb(uint16_t port) {
}
int init_serial(uint16_t port) {
- outb(port + 1, 0x00); // disable them fuckin interupts
- outb(port + 3, 0x80); // sets dlab, allowing custom serial speeds
- outb(port + 0, 0x06); // speed is 115200/6
+ outb(port + 1, 0x00);
+ outb(port + 3, 0x80);
+ outb(port + 0, 0x06);
outb(port + 1, 0x00);
- outb(port + 3, 0x03); // disables dlab, as well as 8 bit char len, 1 stop bit, no paraty, no mystery
- outb(port + 2, 0xc7); // I have no fucking clue what this means
- outb(port + 4, 0x0b); // don't know what this means eather... delete if you can
- outb(port + 4, 0x1e); // loopback mode (where the hell is this documented????)
+ outb(port + 3, 0x03);
+ outb(port + 2, 0xc7);
+ outb(port + 4, 0x0b);
+ outb(port + 4, 0x1e);
outb(port + 0, 0xae); // test char
@@ -38,6 +34,6 @@ int init_serial(uint16_t port) {
}
void _putchar_serial(uint16_t port, char msg) {
- while(!(inb(port + 5) & 0x20)); //wait for transmit to be doneroni
+ while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
outb(port, msg);
}
diff --git a/src/kernel/libs/drivers/video.c b/src/kernel/libs/drivers/video.c
index 9bb4187..ab73bb0 100644
--- a/src/kernel/libs/drivers/video.c
+++ b/src/kernel/libs/drivers/video.c
@@ -1,5 +1,8 @@
#include <printf.h>
#include <video.h>
+
+//to be implimented when paging is set up
+
void dump_video() {
struct mode_info *video = (struct mode_info *)0x600;
printf("Video info:\nx:\t%u\ny:\t%u\nbbp:\t%u\nloc:\t0x%p\n", video->width, video->height, video->bpp, video->framebuffer);
diff --git a/src/kernel/libs/libc.c b/src/kernel/libs/libc.c
index 31580ff..dc5c0ac 100644
--- a/src/kernel/libs/libc.c
+++ b/src/kernel/libs/libc.c
@@ -1,7 +1,6 @@
#include <stddef.h>
#include <stdint.h>
-//#include <printf.h>
-// you need to sort all these into diffrent files! TODO
+// TODO clean up variable names
int strncmp(const char *s1, const char *s2, unsigned int n) {
int i;
for(i = 0; ((i <= n) && (s1[i] != '\0') && (s2[i] != '\0')); i++) {
@@ -23,7 +22,7 @@ int strcmp(const char *s1, const char *s2) {
}
int memcmp(const void *s1, const void *s2, size_t n) {
- const unsigned char *p1 = s1; // Why is c such a bitch?
+ const unsigned char *p1 = s1;
const unsigned char *p2 = s2;
int i;
for(i = 0; i < n; i++) {
@@ -45,3 +44,17 @@ void memcpy(char *dest, char *src, size_t n) {
dest[i] = src[i];
}
}
+
+void bzero(void *dest, size_t size) {
+ unsigned char *p1 = dest;
+ for(uint64_t i = 0; i < size; i++) {
+ p1[i] = 0;
+ }
+}
+
+//TODO move this function to a seperate math library
+int ceil(float n) {
+ int low_n = (int)n;
+ if(n == (float)low_n) return(low_n);
+ return(low_n + 1);
+}
diff --git a/src/kernel/libs/page.c b/src/kernel/libs/page.c
index 88d0c2f..6f1dd7c 100644
--- a/src/kernel/libs/page.c
+++ b/src/kernel/libs/page.c
@@ -1,14 +1,7 @@
#include <printf.h>
#include <paging.h>
#include <stdint.h>
-
-// for now, this will always remain the same.
-// If this ever isn't the case, we'll add paramaters to the paging functions.
-// We will also never need to mess with many bits,
-// as we are not implimenting security for a bare metal fractal generator.
-// Also, is this really the cleanest way to do things?
-
-//after we get paging working, we can probably remove these structs and replace them with plain old uint_16ts.
+#include <libc.h>
void debug_print_memory() {
struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;
@@ -22,33 +15,89 @@ void debug_print_memory() {
}
+//uses buddy system allocation
+void init_memory() {
+ struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;
+ struct phys_map *map = (struct phys_map*)0x200000;
+ uintptr_t onpage = 0x200000;
+ unsigned int i, x, buddy_size, buddy_bitsize, prev_buddy_bsize;
+ uint64_t *buddy_ptr;
+
+ map_page((void*)0x200000, (void*)0x200000, PAGE_SIZE_2M);
+ void *next_page = (void *)onpage + 0x200000;
+ // at this point, we are declaring our header and kernel itself as free (so don't forget to fix that!)
+
+ for(i = 0; memtable[i].length > 0; i++) {
+ if((memtable[i].type == MEM_AVAILABLE) && (memtable[i].ACPI & 1)) {
+
+ map->chunk_start = (void*)memtable[i].base;
+ map->chunk_size = memtable[i].length;
+ buddy_ptr = (void*)&map->buddies;
+
+
+ for(x = 0; x < 8; x++) {
+
+ buddy_bitsize = memtable[i].length / (0x1000 * (1 << x));
+ buddy_size = ceil(buddy_bitsize / (float)8);
+
+ if((void *)buddy_ptr + buddy_size >= next_page) {
+ map_page(next_page, next_page, PAGE_SIZE_2M);
+ next_page += 0x200000;
+ }
+
+ bzero(buddy_ptr, buddy_size); //meant to be /8?
+
+ if((buddy_bitsize * 2) != prev_buddy_bsize) {
+ buddy_ptr[-1] |= (1 << ((prev_buddy_bsize % 8) - 1));
+ }
+
+ buddy_ptr += buddy_size;
+
+ prev_buddy_bsize = buddy_bitsize;
+
+ }
+ map->map_size = buddy_ptr - (uint64_t*)map;
+ map = (struct phys_map *)map + map->map_size;
+
+ if((void *)map + 24 >= next_page) {
+ map_page(next_page, next_page, PAGE_SIZE_2M);
+ next_page += 0x200000;
+ }
+ }
+ }
+}
+
+//TODO this function was deleted due to it being wrong.
+//I'll create it once I have the physical paging prerequisite set up.
+void create_pagetable_stage2(uint64_t free_mem) {
+}
+
+
/**
- * You can critisise the quality of this function all you want, it's messy due to planning mistakes
- * and I'm planning on sanatising it.
- * BUT, don't critisise it _just_ for using goto, that's bullshit. See the following links.
- *
- * https://www.kernel.org/doc/html/v4.17/process/coding-style.html "goto" section
- * https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
+ * BIG TODO:
+ * Paging turned out to be simpler then I thought. I've temporarily fixed the code, but needs to be rewritten/simplified.
+ * Let's get rid of those nasty GOTOs if we can.
+ * Also, once we get physical memory allocator up and running, impliment that in this function.
**/
-bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
- printf("map page called\n");
- if((virtual_addr % (1 << size)) || (physical_addr % (1 << size))) {
+bool map_page(void *virtual_addr, void *physical_addr, uint8_t size) {
+ //printf("map page called\n");
+ uintptr_t va_ptr = (uintptr_t)virtual_addr;
+ uintptr_t pa_ptr = (uintptr_t)physical_addr;
+ if((va_ptr % (1 << size)) || (pa_ptr % (1 << size))) {
return 0;
}
page_table *table = (page_table *)PAGEMAP_LOCATION;
- int pte_i = (virtual_addr >> 12) & 0x1ff;
- int pde_i = (virtual_addr >> 21) & 0x1ff;
- int pdpe_i = (virtual_addr >> 30) & 0x1ff;
- int pml4e_i = (virtual_addr >> 39) & 0x1ff;
- //TODO remove this debugging info
- printf("Virtual offsets:\npte:\t\t%i\npde:\t\t%i\npdpe:\t\t%i\npml4e\t\t%i\n", pte_i, pde_i, pdpe_i, pml4e_i);
+ int pte_i = (va_ptr >> 12) & 0x1ff;
+ int pde_i = (va_ptr >> 21) & 0x1ff;
+ int pdpe_i = (va_ptr >> 30) & 0x1ff;
+ int pml4e_i = (va_ptr >> 39) & 0x1ff;
if(table->pml4e[pml4e_i].present) {
if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error;
if(table->pdpe[pdpe_i].present) {
if(size == PAGE_SIZE_1G) {
- if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)physical_addr >> 30 & 0x1ff)
+ if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)pa_ptr >> 30 & 0x1ff)
return true;
goto error;
}
@@ -56,13 +105,13 @@ bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
if(table->pde[pde_i].present) {
if(size == PAGE_SIZE_2M) {
- if(table->pde[pde_i].base_ptr == (uintptr_t)physical_addr >> 21 & 0x1ff)
+ if(table->pde[pde_i].base_ptr == (uintptr_t)pa_ptr >> 21 & 0x1ff)
return true;
goto error;
}
if(table->pde[pde_i].base_ptr != (uintptr_t)&table->pte[pte_i] >> 12) goto error;
if(table->pte[pte_i].present) {
- if(table->pte[pte_i].base_ptr != ((physical_addr >> 12) & 0x1ff)) goto error;
+ if(table->pte[pte_i].base_ptr != ((pa_ptr >> 12) & 0x1ff)) goto error;
return true;
}
else goto mod_page_pte;
@@ -77,9 +126,10 @@ bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
table->pml4e[pml4e_i].present = 1;
mod_page_pdpe:
table->pdpe[pdpe_i].read_write = 1;
+ //TODO you just found out things are a lot more simple then you thought!
if(size == PAGE_SIZE_1G) {
table->pdpe[pdpe_i].size = 1;
- table->pdpe[pdpe_i].base_ptr = physical_addr >> 30;
+ table->pdpe[pdpe_i].base_ptr = pa_ptr >> 12;
table->pdpe[pdpe_i].present = 1;
return true;
}
@@ -89,14 +139,14 @@ mod_page_pde:
table->pde[pde_i].read_write = 1;
if(size == PAGE_SIZE_2M) {
table->pde[pde_i].size = 1;
- table->pde[pde_i].base_ptr = physical_addr >> 21;
+ table->pde[pde_i].base_ptr = pa_ptr >> 12;
table->pde[pde_i].present = 1;
return true;
}
table->pde[pde_i].base_ptr = (uintptr_t)&table->pte[pte_i] >> 12;
table->pde[pde_i].present = 1;
mod_page_pte:
- table->pte[pte_i].base_ptr = (physical_addr >> 12);
+ table->pte[pte_i].base_ptr = pa_ptr >> 12;
table->pte[pte_i].read_write = 1;
table->pte[pte_i].present = 1;
return true;