feature: a lot of stuff and got to a working command line ish
This commit is contained in:
@@ -7,31 +7,142 @@
|
||||
#include <drivers/ports.h>
|
||||
#include <cpu/isr.h>
|
||||
#include <libc/libc.h>
|
||||
#include <libc/stdbool.h>
|
||||
#include <libc/ringqueue.h>
|
||||
#include <mem/mem.h>
|
||||
|
||||
char scancodes_ascii[] = {
|
||||
0, 0,
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
|
||||
0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
|
||||
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
|
||||
'*',
|
||||
0, ' ',
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F1-F10
|
||||
0, 0,
|
||||
'7', '8', '9', '-',
|
||||
'4', '5', '6', '+',
|
||||
'1', '2', '3',
|
||||
'0', 0,
|
||||
0, // sysrq
|
||||
0, 0, // weird
|
||||
0, 0, // F11 F12
|
||||
// weid
|
||||
|
||||
const char scancode_map_lowercase[] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||
'o', 'p', '[', ']', 0, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c',
|
||||
'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
const char scancode_map_uppercase[] = {
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||
'O', 'P', '{', '}', 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C',
|
||||
'V', 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
//
|
||||
//char scancodes_ascii[] = {
|
||||
// 0, 0,
|
||||
// '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
|
||||
// 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||
// 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
|
||||
// 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
|
||||
// '*',
|
||||
// 0, ' ',
|
||||
// 0,
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F1-F10
|
||||
// 0, 0,
|
||||
// '7', '8', '9', '-',
|
||||
// '4', '5', '6', '+',
|
||||
// '1', '2', '3',
|
||||
// '0', 0,
|
||||
// 0, // sysrq
|
||||
// 0, 0, // weird
|
||||
// 0, 0, // F11 F12
|
||||
// // weid
|
||||
//};
|
||||
|
||||
struct {
|
||||
u8 shift: 1;
|
||||
u8 ctrl: 1;
|
||||
u8 alt: 1;
|
||||
u8 extended: 1;
|
||||
} keyboard_state;
|
||||
|
||||
void *keyboard_event_buffer = NULL;
|
||||
|
||||
char *MSG_KEY = "Clicked on key 'x'\n";
|
||||
|
||||
void print_scancode(unsigned char scancode);
|
||||
char getc() {
|
||||
while (true) {
|
||||
KeyEvent* event = get_next_event();
|
||||
char retval = 0;
|
||||
if (event == NULL) {
|
||||
goto _getc_end;
|
||||
}
|
||||
if (event->is_release) {
|
||||
goto _getc_end;
|
||||
}
|
||||
if (event->scancode == 0x1C) {
|
||||
retval = '\n';
|
||||
goto _getc_end;
|
||||
}
|
||||
if (event->ascii_code != 0) {
|
||||
retval = event->ascii_code;
|
||||
goto _getc_end;
|
||||
}
|
||||
_getc_end:
|
||||
free_event(event);
|
||||
if (retval != 0) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeyEvent *get_next_event() {
|
||||
KeyEvent *target = malloc(sizeof(KeyEvent));
|
||||
if (!ring_buffer_get(keyboard_event_buffer, target)) {
|
||||
free(target);
|
||||
return NULL;
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
void free_event(KeyEvent *event) {
|
||||
free(event);
|
||||
}
|
||||
|
||||
//void print_scancode(unsigned char scancode);
|
||||
|
||||
void handle_modifier_keys(unsigned char scancode, bool is_release) {
|
||||
switch (scancode) {
|
||||
case 42:
|
||||
case 54:
|
||||
keyboard_state.shift = !is_release;
|
||||
break;
|
||||
case 29:
|
||||
keyboard_state.ctrl = !is_release;
|
||||
break;
|
||||
case 56:
|
||||
keyboard_state.alt = !is_release;
|
||||
break;
|
||||
default:
|
||||
// not an modifier key
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void publish_key_event(unsigned char scan_code) {
|
||||
bool is_release = false;
|
||||
if (scan_code > 0x80) {
|
||||
is_release = true;
|
||||
scan_code -= 0x80;
|
||||
}
|
||||
handle_modifier_keys(scan_code, is_release);
|
||||
|
||||
char ascii_char = scancode_map_lowercase[scan_code];
|
||||
if (keyboard_state.shift) {
|
||||
if (scancode_map_uppercase[scan_code] != 0) {
|
||||
ascii_char = scancode_map_uppercase[scan_code];
|
||||
}
|
||||
}
|
||||
|
||||
KeyEvent event = {
|
||||
.scancode = scan_code,
|
||||
.ascii_code = ascii_char,
|
||||
.is_release = !is_release,
|
||||
.shift = keyboard_state.shift,
|
||||
.alt = keyboard_state.alt,
|
||||
.ctrl = keyboard_state.ctrl,
|
||||
};
|
||||
ring_buffer_put(keyboard_event_buffer, &event);
|
||||
}
|
||||
|
||||
static void keyboard_callback(registers_t regs) {
|
||||
unsigned char status = port_byte_in(PORT_PS2_STATUS);
|
||||
@@ -40,31 +151,37 @@ static void keyboard_callback(registers_t regs) {
|
||||
return;
|
||||
}
|
||||
unsigned char scancode = port_byte_in(PORT_PS2_DATA);
|
||||
print_scancode(scancode);
|
||||
publish_key_event(scancode);
|
||||
// print_scancode(scancode);
|
||||
}
|
||||
|
||||
void init_keyboard() {
|
||||
register_interrupt_handler(IRQ1, keyboard_callback);
|
||||
keyboard_state.shift = 0;
|
||||
keyboard_state.ctrl = 0;
|
||||
keyboard_state.alt = 0;
|
||||
keyboard_state.extended = 0;
|
||||
keyboard_event_buffer = create_buffer(256, sizeof(KeyEvent));
|
||||
}
|
||||
|
||||
void print_scancode(unsigned char scancode) {
|
||||
char msg[256];
|
||||
char release = 0;
|
||||
if (scancode > 0x80) {
|
||||
// release
|
||||
release = 1;
|
||||
scancode -= 0x80;
|
||||
}
|
||||
char code = scancodes_ascii[scancode];
|
||||
if (code == 0) {
|
||||
// special
|
||||
} else {
|
||||
if (release && code > 0x60 && code < 0x7B) {
|
||||
code -= 0x20; // to lowercase
|
||||
}
|
||||
|
||||
strcpy(msg, MSG_KEY);
|
||||
msg[strlen(msg) - 3] = code;
|
||||
kprint(msg);
|
||||
}
|
||||
}
|
||||
//void print_scancode(unsigned char scancode) {
|
||||
// char msg[256];
|
||||
// char release = 0;
|
||||
// if (scancode > 0x80) {
|
||||
// // release
|
||||
// release = 1;
|
||||
// scancode -= 0x80;
|
||||
// }
|
||||
// char code = scancodes_ascii[scancode];
|
||||
// if (code == 0) {
|
||||
// // special
|
||||
// } else {
|
||||
// if (release && code > 0x60 && code < 0x7B) {
|
||||
// code -= 0x20; // to lowercase
|
||||
// }
|
||||
//
|
||||
// strcpy(msg, MSG_KEY);
|
||||
// msg[strlen(msg) - 3] = code;
|
||||
// kprint(msg);
|
||||
// }
|
||||
//}
|
||||
@@ -5,6 +5,26 @@
|
||||
#ifndef MY_KERNEL_KEYBOARD_H
|
||||
#define MY_KERNEL_KEYBOARD_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct KeyEvent_t {
|
||||
// KeyCode key;
|
||||
u32 scancode;
|
||||
char ascii_code;
|
||||
u8 is_release: 1;
|
||||
u8 shift: 1;
|
||||
u8 alt: 1;
|
||||
u8 ctrl: 1;
|
||||
} KeyEvent;
|
||||
|
||||
char getc();
|
||||
|
||||
void init_keyboard();
|
||||
|
||||
//const char *key_code_to_string(KeyCode key);
|
||||
|
||||
KeyEvent *get_next_event();
|
||||
|
||||
void free_event(KeyEvent *event);
|
||||
|
||||
#endif //MY_KERNEL_KEYBOARD_H
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <drivers/ports.h>
|
||||
#include <drivers/vgascreen.h>
|
||||
#include <libc/libc.h>
|
||||
#include <libc/stdbool.h>
|
||||
#include <cpu/isr.h>
|
||||
#include <cpu/timer.h>
|
||||
#include <drivers/keyboard.h>
|
||||
@@ -8,9 +9,12 @@
|
||||
#include <multiboot.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <kprint.h>
|
||||
#include <libc/readline.h>
|
||||
#include <libc/string.h>
|
||||
|
||||
char *msg_booted = "Booted Successfully!\n";
|
||||
|
||||
void main_loop();
|
||||
|
||||
void kmain(multiboot_info_t *multiboot_info) {
|
||||
isr_install();
|
||||
@@ -37,9 +41,39 @@ void kmain(multiboot_info_t *multiboot_info) {
|
||||
init_timer(50);
|
||||
init_keyboard();
|
||||
|
||||
print_mmap_info();
|
||||
// print_mmap_info();
|
||||
while (true) {
|
||||
main_loop();
|
||||
}
|
||||
|
||||
// vga_set_raw(pos * 2, 'X');
|
||||
// vga_set_raw(pos * 2 + 1, 0xf);
|
||||
do {} while (1);
|
||||
}
|
||||
|
||||
const char* newline = "\n";
|
||||
const char* msg_unknown_command = "Unknown command: ";
|
||||
|
||||
const char* cmd_echo = "echo";
|
||||
const char* cmd_print_mmap = "print_mmap";
|
||||
|
||||
void main_loop() {
|
||||
char* msg = readline(NULL);
|
||||
char* args = strchr(msg, ' ') + 1;
|
||||
args[-1] = 0;
|
||||
if (strcmp(cmd_echo, msg) == 0) {
|
||||
kprint(args);
|
||||
kprint(newline);
|
||||
goto _main_loop_end;
|
||||
}
|
||||
if (strcmp(cmd_print_mmap, msg) == 0) {
|
||||
print_mmap_info();
|
||||
goto _main_loop_end;
|
||||
}
|
||||
|
||||
kprint(msg_unknown_command);
|
||||
kprint(msg);
|
||||
kprint(newline);
|
||||
_main_loop_end:
|
||||
free(msg);
|
||||
}
|
||||
@@ -27,7 +27,7 @@ void kprint_register(kprint_handler handler) {
|
||||
// todo handle
|
||||
}
|
||||
|
||||
void kprint(char *msg) {
|
||||
void kprint(const char *msg) {
|
||||
for (int i = 0; i < MAX_HANDLERS; ++i) {
|
||||
if (handlers[i] == NULL) {
|
||||
continue;
|
||||
|
||||
@@ -13,4 +13,4 @@ typedef void (*kprint_handler)(const char *);
|
||||
|
||||
void kprint_register(kprint_handler);
|
||||
|
||||
void kprint(char *msg);
|
||||
void kprint(const char *msg);
|
||||
@@ -14,10 +14,6 @@ int memcpy(char *dst, char *src, int amount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strcpy(char *dst, char *src) {
|
||||
return memcpy(dst, src, strlen(src) + 1);
|
||||
}
|
||||
|
||||
int memset(char *dst, char data, int amount) {
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
dst[i] = data;
|
||||
@@ -34,11 +30,9 @@ int itoa(int i, char *target) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strlen(char *str) {
|
||||
int length = 0;
|
||||
while (str[length] != 0) {
|
||||
length++;
|
||||
int maxi(int a, int b) {
|
||||
if (a >= b) {
|
||||
return a;
|
||||
}
|
||||
return length;
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,10 @@
|
||||
|
||||
int memcpy(char *dst, char *src, int amount);
|
||||
|
||||
int strcpy(char *dst, char *src);
|
||||
|
||||
int memset(char *dst, char data, int amount);
|
||||
|
||||
int itoa(int i, char *target);
|
||||
|
||||
int strlen(char *str);
|
||||
int maxi(int a, int b);
|
||||
|
||||
#endif /* KERNEL_LIBC_LIBC_H_ */
|
||||
|
||||
30
kernel/libc/readline.c
Normal file
30
kernel/libc/readline.c
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by rick on 01-02-21.
|
||||
//
|
||||
|
||||
#include "readline.h"
|
||||
#include <libc/libc.h>
|
||||
#include <types.h>
|
||||
#include <kprint.h>
|
||||
#include <mem/mem.h>
|
||||
#include <drivers/keyboard.h>
|
||||
|
||||
#define RESULT_SIZE 256
|
||||
|
||||
const char* default_msg = "> ";
|
||||
|
||||
char* readline(const char *prompt) {
|
||||
kprint(prompt == NULL ? default_msg : prompt);
|
||||
|
||||
char* result = malloc(RESULT_SIZE);
|
||||
memset(result, 0, RESULT_SIZE);
|
||||
for (int i = 0; i < RESULT_SIZE; ++i) {
|
||||
result[i] = getc();
|
||||
kprint(&result[i]);
|
||||
if (result[i] == '\n') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
10
kernel/libc/readline.h
Normal file
10
kernel/libc/readline.h
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by rick on 01-02-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_READLINE_H
|
||||
#define NEW_KERNEL_READLINE_H
|
||||
|
||||
char* readline(const char *prompt);
|
||||
|
||||
#endif //NEW_KERNEL_READLINE_H
|
||||
57
kernel/libc/ringqueue.c
Normal file
57
kernel/libc/ringqueue.c
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Created by rick on 30-01-21.
|
||||
//
|
||||
|
||||
#include "ringqueue.h"
|
||||
#include <libc/libc.h>
|
||||
#include <mem/mem.h>
|
||||
|
||||
#define calc_pos(buffer, index) ((buffer->object_size) * (index))
|
||||
|
||||
typedef struct {
|
||||
int object_size;
|
||||
int count;
|
||||
int read_pos;
|
||||
int write_pos;
|
||||
void *mem;
|
||||
} ring_buffer_t;
|
||||
|
||||
void *create_buffer(int count, int object_size) {
|
||||
ring_buffer_t *buffer = malloc(sizeof(ring_buffer_t));
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
buffer->object_size = object_size;
|
||||
buffer->count = count;
|
||||
buffer->read_pos = 0;
|
||||
buffer->write_pos = 0;
|
||||
buffer->mem = malloc(count * object_size);
|
||||
if (buffer->mem == NULL) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
void free_buffer(void *buffer) {
|
||||
free(((ring_buffer_t *) buffer)->mem);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void ring_buffer_put(void *buffer, void *item) {
|
||||
ring_buffer_t *ring_buffer = (ring_buffer_t *) buffer;
|
||||
// todo check if this write would overwrite the current reading pos
|
||||
// todo handle the above case
|
||||
memcpy(ring_buffer->mem + calc_pos(ring_buffer, ring_buffer->write_pos), item, ring_buffer->object_size);
|
||||
ring_buffer->write_pos++;
|
||||
};
|
||||
|
||||
bool ring_buffer_get(void *buffer, void* target) {
|
||||
ring_buffer_t *ring_buffer = (ring_buffer_t *) buffer;
|
||||
if (ring_buffer->read_pos == ring_buffer->write_pos) {
|
||||
// nothing to read
|
||||
return false;
|
||||
}
|
||||
memcpy(target, ring_buffer->mem + calc_pos(ring_buffer, ring_buffer->read_pos++), ring_buffer->object_size);
|
||||
return true;
|
||||
};
|
||||
19
kernel/libc/ringqueue.h
Normal file
19
kernel/libc/ringqueue.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Created by rick on 30-01-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_RINGQUEUE_H
|
||||
#define NEW_KERNEL_RINGQUEUE_H
|
||||
|
||||
#include <types.h>
|
||||
#include <libc/stdbool.h>
|
||||
|
||||
void *create_buffer(int count, int object_size);
|
||||
|
||||
void free_buffer(void *buffer);
|
||||
|
||||
void ring_buffer_put(void *buffer, void *item);
|
||||
|
||||
bool ring_buffer_get(void *buffer, void* target);
|
||||
|
||||
#endif //NEW_KERNEL_RINGQUEUE_H
|
||||
5
kernel/libc/stdbool.c
Normal file
5
kernel/libc/stdbool.c
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by rick on 31-01-21.
|
||||
//
|
||||
|
||||
#include "stdbool.h"
|
||||
15
kernel/libc/stdbool.h
Normal file
15
kernel/libc/stdbool.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by rick on 31-01-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_STDBOOL_H
|
||||
#define NEW_KERNEL_STDBOOL_H
|
||||
|
||||
#define TRUE 1
|
||||
#define true 1
|
||||
#define FALSE 0
|
||||
#define false 0
|
||||
|
||||
typedef unsigned char bool;
|
||||
|
||||
#endif //NEW_KERNEL_STDBOOL_H
|
||||
60
kernel/libc/string.c
Normal file
60
kernel/libc/string.c
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Created by rick on 01-02-21.
|
||||
//
|
||||
|
||||
#include "string.h"
|
||||
#include "stdbool.h"
|
||||
#include <libc/libc.h>
|
||||
#include <types.h>
|
||||
|
||||
int strcpy(char *dst, char *src) {
|
||||
return memcpy(dst, src, strlen(src) + 1);
|
||||
}
|
||||
|
||||
int strlen(const char *str) {
|
||||
int length = 0;
|
||||
while (str[length] != 0) {
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
int len1 = strlen(s1);
|
||||
int len2 = strlen(s1);
|
||||
return strncmp(s1, s2, maxi(len1, len2));
|
||||
}
|
||||
|
||||
const char *strchr(const char *s, char c) {
|
||||
int index = 0;
|
||||
while (true) {
|
||||
if (s[index] == c) {
|
||||
return &s[index];
|
||||
}
|
||||
if (s[index] == 0) {
|
||||
return NULL;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, int n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (s1[i] == 0 && s2[i] == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (s1[i] == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (s2[i] == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (s1[i] > s2[i]) {
|
||||
return -1;
|
||||
}
|
||||
if (s2[i] < s1[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
18
kernel/libc/string.h
Normal file
18
kernel/libc/string.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by rick on 01-02-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_STRING_H
|
||||
#define NEW_KERNEL_STRING_H
|
||||
|
||||
int strcpy(char *dst, char *src);
|
||||
|
||||
int strlen(const char *str);
|
||||
|
||||
const char *strchr(const char *s, char c);
|
||||
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
|
||||
int strncmp(const char *s1, const char *s2, int n);
|
||||
|
||||
#endif //NEW_KERNEL_STRING_H
|
||||
144
kernel/mem/mem.c
144
kernel/mem/mem.c
@@ -7,6 +7,27 @@
|
||||
#include <mem/mem.h>
|
||||
#include <libc/libc.h>
|
||||
|
||||
#define MEMMAP_ENTRIES 16
|
||||
|
||||
#define MMAP_TYPE_UNDEFINED 0
|
||||
#define MMAP_TYPE_AVAILABLE 1
|
||||
#define MMAP_TYPE_RESERVED 2
|
||||
#define MMAP_TYPE_ACPI_RECLAIMABLE 3
|
||||
#define MMAP_TYPE_NVS 4
|
||||
#define MMAP_TYPE_BADRAM 5
|
||||
#define MMAP_TYPE_KERNEL 6
|
||||
#define MMAP_TYPE_MALLOC 7
|
||||
|
||||
#define MALLOC_TYPE_FREE 0
|
||||
#define MALLOC_TYPE_USED 1
|
||||
|
||||
#define kilobyte (1024)
|
||||
//#define kernel_start (one_meg)
|
||||
#define kernel_size (32 * kilobyte)
|
||||
#define kernel_end (kernel_start + kernel_size)
|
||||
extern void *kernel_start;
|
||||
//extern void *kernel_end;
|
||||
|
||||
char *msg_index = "Idx: ";
|
||||
char *msg_addr = "Address: ";
|
||||
char *msg_len = "Length: ";
|
||||
@@ -14,20 +35,18 @@ char *msg_type = "Type: ";
|
||||
char *msg_nl = "\n";
|
||||
|
||||
typedef struct {
|
||||
u64 address;
|
||||
u64 length;
|
||||
#define MMAP_TYPE_UNDEFINED 0
|
||||
#define MMAP_TYPE_AVAILABLE 1
|
||||
#define MMAP_TYPE_RESERVED 2
|
||||
#define MMAP_TYPE_ACPI_RECLAIMABLE 3
|
||||
#define MMAP_TYPE_NVS 4
|
||||
#define MMAP_TYPE_BADRAM 5
|
||||
void *address;
|
||||
u32 length;
|
||||
u32 type;
|
||||
} __attribute((packed)) mmap_entry;
|
||||
|
||||
char *msg_lu = "0123456789ABCDEF";
|
||||
|
||||
mmap_entry memmap[16] = {
|
||||
int malloc_entries = 0;
|
||||
int malloc_used = 0;
|
||||
|
||||
int last_memmap_entry = 0;
|
||||
mmap_entry memmap[MEMMAP_ENTRIES] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
@@ -46,14 +65,107 @@ mmap_entry memmap[16] = {
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
void init_mmap(struct multiboot_mmap_entry *entries, u32 count) {
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
memmap[i].address = entries[i].addr;
|
||||
memmap[i].length = entries[i].len;
|
||||
memmap[i].type = entries[i].type;
|
||||
typedef struct malloc_map {
|
||||
struct malloc_map *next;
|
||||
struct malloc_map *pref;
|
||||
u32 size;
|
||||
int type;
|
||||
} malloc_map;
|
||||
|
||||
void use_mmap_entry(struct multiboot_mmap_entry *entry) {
|
||||
mmap_entry *mm_entry = &memmap[last_memmap_entry++];
|
||||
mm_entry->address = (void *) entry->addr;
|
||||
mm_entry->length = entry->len;
|
||||
mm_entry->type = entry->type;
|
||||
if (last_memmap_entry == 1) {
|
||||
// not using first map entry for now
|
||||
return;
|
||||
}
|
||||
// check if the entry overlaps with the kernel address space
|
||||
if (kernel_start >= mm_entry->address && kernel_start <= mm_entry->address + mm_entry->length) {
|
||||
// todo make this something proper
|
||||
struct multiboot_mmap_entry extra_entry;
|
||||
extra_entry.size = entry->size;
|
||||
extra_entry.type = entry->type;
|
||||
extra_entry.addr = entry->addr + kernel_size;
|
||||
extra_entry.len = entry->size - kernel_size;
|
||||
use_mmap_entry(&extra_entry);
|
||||
|
||||
mm_entry->length = kernel_size;
|
||||
mm_entry->type = MMAP_TYPE_KERNEL;
|
||||
}
|
||||
if (mm_entry->type == MMAP_TYPE_AVAILABLE && (unsigned int) mm_entry->length > sizeof(malloc_map)) {
|
||||
mm_entry->type = MMAP_TYPE_MALLOC;
|
||||
malloc_map *map = (malloc_map *) mm_entry->address;
|
||||
map->type = MALLOC_TYPE_FREE;
|
||||
map->size = mm_entry->length - sizeof(malloc_map);
|
||||
map->pref = map;
|
||||
map->next = map;
|
||||
malloc_entries++;
|
||||
}
|
||||
}
|
||||
|
||||
void init_mmap(struct multiboot_mmap_entry *entries, u32 count) {
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
use_mmap_entry(&entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void split_malloc_map(malloc_map *entry, unsigned int size) {
|
||||
malloc_entries++;
|
||||
malloc_map *new_entry = entry + sizeof(malloc_map) + size;
|
||||
new_entry->size = entry->size - size - sizeof(malloc_map);
|
||||
new_entry->next = entry->next;
|
||||
new_entry->pref = entry;
|
||||
new_entry->type = MALLOC_TYPE_FREE;
|
||||
entry->next->pref = new_entry;
|
||||
entry->next = new_entry;
|
||||
entry->size = size;
|
||||
}
|
||||
|
||||
void *malloc(unsigned int size) {
|
||||
// todo replace this horrible mess!
|
||||
// this lacks any page alignment and what so ever
|
||||
for (int i = 0; i < MEMMAP_ENTRIES; ++i) {
|
||||
if (memmap[i].type != MMAP_TYPE_MALLOC) {
|
||||
continue;
|
||||
}
|
||||
// get first first_map of address
|
||||
malloc_map *first_map = (malloc_map *) memmap[i].address;
|
||||
malloc_map *current_map = first_map;
|
||||
// iterate through maps
|
||||
do {
|
||||
if (current_map->type == MALLOC_TYPE_USED) {
|
||||
goto malloc_find_next;
|
||||
}
|
||||
if ((unsigned int) current_map->size < size) {
|
||||
goto malloc_find_next;
|
||||
}
|
||||
if ((unsigned int) current_map->size > (size + sizeof(malloc_map))) {
|
||||
// big enough to split
|
||||
split_malloc_map(current_map, size);
|
||||
}
|
||||
malloc_used++;
|
||||
current_map->type = MALLOC_TYPE_USED;
|
||||
return ((void*)current_map) + sizeof(malloc_map);
|
||||
|
||||
malloc_find_next:
|
||||
current_map = current_map->next;
|
||||
} while (current_map != first_map);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free(void *mem) {
|
||||
if (mem == NULL) {
|
||||
return;
|
||||
}
|
||||
malloc_used--;
|
||||
malloc_map *map = (mem - sizeof(malloc_map));
|
||||
map->type = MALLOC_TYPE_FREE;
|
||||
};
|
||||
|
||||
|
||||
void print_hex_u64(u64 input) {
|
||||
char msg[18] = "0x0000000000000000";
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
@@ -74,10 +186,10 @@ void print_mmap_info() {
|
||||
kprint(tmp_str);
|
||||
kprint(msg_nl);
|
||||
kprint(msg_addr);
|
||||
print_hex_u64(memmap[i].address);
|
||||
print_hex_u64((u64) memmap[i].address);
|
||||
kprint(msg_nl);
|
||||
kprint(msg_len);
|
||||
print_hex_u64(memmap[i].length);
|
||||
print_hex_u64((u64) memmap[i].length);
|
||||
kprint(msg_nl);
|
||||
kprint(msg_type);
|
||||
itoa(memmap[i].type, tmp_str);
|
||||
|
||||
@@ -11,4 +11,7 @@ void init_mmap(struct multiboot_mmap_entry *entries, u32 count);
|
||||
|
||||
void print_mmap_info();
|
||||
|
||||
void* malloc(unsigned int size);
|
||||
void free(void* mem);
|
||||
|
||||
#endif //NEW_KERNEL_MEM_H
|
||||
|
||||
Reference in New Issue
Block a user