feature: a lot of stuff and got to a working command line ish

This commit is contained in:
2021-02-01 22:31:21 +01:00
parent 468d5968a9
commit 9986d95dbb
22 changed files with 1511 additions and 76 deletions

1
.gitignore vendored
View File

@@ -112,3 +112,4 @@ modules.xml
# End of https://www.toptal.com/developers/gitignore/api/cmake,jetbrains+all # End of https://www.toptal.com/developers/gitignore/api/cmake,jetbrains+all
*.old *.old
**/__pycache__

View File

@@ -7,31 +7,142 @@
#include <drivers/ports.h> #include <drivers/ports.h>
#include <cpu/isr.h> #include <cpu/isr.h>
#include <libc/libc.h> #include <libc/libc.h>
#include <libc/stdbool.h>
#include <libc/ringqueue.h>
#include <mem/mem.h>
char scancodes_ascii[] = {
0, 0, const char scancode_map_lowercase[] = {
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, 'o', 'p', '[', ']', 0, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '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, '\\', '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, // 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_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"; 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) { static void keyboard_callback(registers_t regs) {
unsigned char status = port_byte_in(PORT_PS2_STATUS); unsigned char status = port_byte_in(PORT_PS2_STATUS);
@@ -40,31 +151,37 @@ static void keyboard_callback(registers_t regs) {
return; return;
} }
unsigned char scancode = port_byte_in(PORT_PS2_DATA); unsigned char scancode = port_byte_in(PORT_PS2_DATA);
print_scancode(scancode); publish_key_event(scancode);
// print_scancode(scancode);
} }
void init_keyboard() { void init_keyboard() {
register_interrupt_handler(IRQ1, keyboard_callback); 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) { //void print_scancode(unsigned char scancode) {
char msg[256]; // char msg[256];
char release = 0; // char release = 0;
if (scancode > 0x80) { // if (scancode > 0x80) {
// release // // release
release = 1; // release = 1;
scancode -= 0x80; // scancode -= 0x80;
} // }
char code = scancodes_ascii[scancode]; // char code = scancodes_ascii[scancode];
if (code == 0) { // if (code == 0) {
// special // // special
} else { // } else {
if (release && code > 0x60 && code < 0x7B) { // if (release && code > 0x60 && code < 0x7B) {
code -= 0x20; // to lowercase // code -= 0x20; // to lowercase
} // }
//
strcpy(msg, MSG_KEY); // strcpy(msg, MSG_KEY);
msg[strlen(msg) - 3] = code; // msg[strlen(msg) - 3] = code;
kprint(msg); // kprint(msg);
} // }
} //}

View File

@@ -5,6 +5,26 @@
#ifndef MY_KERNEL_KEYBOARD_H #ifndef MY_KERNEL_KEYBOARD_H
#define 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(); 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 #endif //MY_KERNEL_KEYBOARD_H

View File

@@ -1,6 +1,7 @@
#include <drivers/ports.h> #include <drivers/ports.h>
#include <drivers/vgascreen.h> #include <drivers/vgascreen.h>
#include <libc/libc.h> #include <libc/libc.h>
#include <libc/stdbool.h>
#include <cpu/isr.h> #include <cpu/isr.h>
#include <cpu/timer.h> #include <cpu/timer.h>
#include <drivers/keyboard.h> #include <drivers/keyboard.h>
@@ -8,9 +9,12 @@
#include <multiboot.h> #include <multiboot.h>
#include <drivers/serial.h> #include <drivers/serial.h>
#include <kprint.h> #include <kprint.h>
#include <libc/readline.h>
#include <libc/string.h>
char *msg_booted = "Booted Successfully!\n"; char *msg_booted = "Booted Successfully!\n";
void main_loop();
void kmain(multiboot_info_t *multiboot_info) { void kmain(multiboot_info_t *multiboot_info) {
isr_install(); isr_install();
@@ -37,9 +41,39 @@ void kmain(multiboot_info_t *multiboot_info) {
init_timer(50); init_timer(50);
init_keyboard(); init_keyboard();
print_mmap_info(); // print_mmap_info();
while (true) {
main_loop();
}
// vga_set_raw(pos * 2, 'X'); // vga_set_raw(pos * 2, 'X');
// vga_set_raw(pos * 2 + 1, 0xf); // vga_set_raw(pos * 2 + 1, 0xf);
do {} while (1); 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);
}

View File

@@ -27,7 +27,7 @@ void kprint_register(kprint_handler handler) {
// todo handle // todo handle
} }
void kprint(char *msg) { void kprint(const char *msg) {
for (int i = 0; i < MAX_HANDLERS; ++i) { for (int i = 0; i < MAX_HANDLERS; ++i) {
if (handlers[i] == NULL) { if (handlers[i] == NULL) {
continue; continue;

View File

@@ -13,4 +13,4 @@ typedef void (*kprint_handler)(const char *);
void kprint_register(kprint_handler); void kprint_register(kprint_handler);
void kprint(char *msg); void kprint(const char *msg);

View File

@@ -14,10 +14,6 @@ int memcpy(char *dst, char *src, int amount) {
return 0; return 0;
} }
int strcpy(char *dst, char *src) {
return memcpy(dst, src, strlen(src) + 1);
}
int memset(char *dst, char data, int amount) { int memset(char *dst, char data, int amount) {
for (int i = 0; i < amount; ++i) { for (int i = 0; i < amount; ++i) {
dst[i] = data; dst[i] = data;
@@ -34,11 +30,9 @@ int itoa(int i, char *target) {
return 0; return 0;
} }
int strlen(char *str) { int maxi(int a, int b) {
int length = 0; if (a >= b) {
while (str[length] != 0) { return a;
length++;
} }
return length; return b;
} }

View File

@@ -10,12 +10,10 @@
int memcpy(char *dst, char *src, int amount); int memcpy(char *dst, char *src, int amount);
int strcpy(char *dst, char *src);
int memset(char *dst, char data, int amount); int memset(char *dst, char data, int amount);
int itoa(int i, char *target); int itoa(int i, char *target);
int strlen(char *str); int maxi(int a, int b);
#endif /* KERNEL_LIBC_LIBC_H_ */ #endif /* KERNEL_LIBC_LIBC_H_ */

30
kernel/libc/readline.c Normal file
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,5 @@
//
// Created by rick on 31-01-21.
//
#include "stdbool.h"

15
kernel/libc/stdbool.h Normal file
View 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
View 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
View 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

View File

@@ -7,6 +7,27 @@
#include <mem/mem.h> #include <mem/mem.h>
#include <libc/libc.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_index = "Idx: ";
char *msg_addr = "Address: "; char *msg_addr = "Address: ";
char *msg_len = "Length: "; char *msg_len = "Length: ";
@@ -14,20 +35,18 @@ char *msg_type = "Type: ";
char *msg_nl = "\n"; char *msg_nl = "\n";
typedef struct { typedef struct {
u64 address; void *address;
u64 length; u32 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
u32 type; u32 type;
} __attribute((packed)) mmap_entry; } __attribute((packed)) mmap_entry;
char *msg_lu = "0123456789ABCDEF"; 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}, {0, 0, 0},
{0, 0, 0}, {0, 0, 0},
@@ -46,14 +65,107 @@ mmap_entry memmap[16] = {
{0, 0, 0}, {0, 0, 0},
}; };
void init_mmap(struct multiboot_mmap_entry *entries, u32 count) { typedef struct malloc_map {
for (u32 i = 0; i < count; ++i) { struct malloc_map *next;
memmap[i].address = entries[i].addr; struct malloc_map *pref;
memmap[i].length = entries[i].len; u32 size;
memmap[i].type = entries[i].type; 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) { void print_hex_u64(u64 input) {
char msg[18] = "0x0000000000000000"; char msg[18] = "0x0000000000000000";
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
@@ -74,10 +186,10 @@ void print_mmap_info() {
kprint(tmp_str); kprint(tmp_str);
kprint(msg_nl); kprint(msg_nl);
kprint(msg_addr); kprint(msg_addr);
print_hex_u64(memmap[i].address); print_hex_u64((u64) memmap[i].address);
kprint(msg_nl); kprint(msg_nl);
kprint(msg_len); kprint(msg_len);
print_hex_u64(memmap[i].length); print_hex_u64((u64) memmap[i].length);
kprint(msg_nl); kprint(msg_nl);
kprint(msg_type); kprint(msg_type);
itoa(memmap[i].type, tmp_str); itoa(memmap[i].type, tmp_str);

View File

@@ -11,4 +11,7 @@ void init_mmap(struct multiboot_mmap_entry *entries, u32 count);
void print_mmap_info(); void print_mmap_info();
void* malloc(unsigned int size);
void free(void* mem);
#endif //NEW_KERNEL_MEM_H #endif //NEW_KERNEL_MEM_H

View File

@@ -9,6 +9,7 @@ SECTIONS
/* Begin putting sections at 1 MiB, a conventional place for kernels to be /* Begin putting sections at 1 MiB, a conventional place for kernels to be
loaded at by the bootloader. */ loaded at by the bootloader. */
. = 1M; . = 1M;
kernel_start = .;
/* First put the multiboot header, as it is required to be put very early /* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format. early in the image or the bootloader won't recognize the file format.
@@ -38,6 +39,13 @@ SECTIONS
*(.bss) *(.bss)
} }
/DISCARD/ : {
*(.eh_frame);
*(.comment);
*(.gnu.hash);
*(.note.gnu.build-id);
}
/* The compiler may produce other sections, by default it will put them in /* 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. */ a segment with the same name. Simply add stuff here as needed. */
} }

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
nohup qemu-system-i386 -S -s -kernel cmake-build-debug/my-kernel.bin -d guest_errors,int -m 1G & nohup qemu-system-i386 -S -s -kernel cmake-build-debug/my-kernel.bin -d guest_errors,int -m 1G > /dev/null &
disown disown

810
scancodes/set1.json Normal file
View File

@@ -0,0 +1,810 @@
[
[
"1",
"29/A9",
"0E/F0 0E",
"0E/F0 0E",
"`",
"~"
],
[
"2",
"02/82",
"16/F0 16",
"16/F0 16",
"1",
"!"
],
[
"3",
"03/83",
"1E/F0 1E",
"1E/F0 1E",
"2",
"@"
],
[
"4",
"04/84",
"26/F0 26",
"26/F0 26",
"3",
"#"
],
[
"5",
"05/85",
"25/F0 25",
"25/F0 25",
"4",
"$"
],
[
"6",
"06/86",
"2E/F0 2E",
"2E/F0 2E",
"5",
"%"
],
[
"7",
"07/87",
"36/F0 36",
"36/F0 36",
"6",
"^"
],
[
"8",
"08/88",
"3D/F0 3D",
"3D/F0 3D",
"7",
"&"
],
[
"9",
"09/89",
"3E/F0 3E",
"3E/F0 3E",
"8",
"*"
],
[
"10",
"0A/8A",
"46/F0 46",
"46/F0 46",
"9",
"("
],
[
"11",
"0B/8B",
"45/F0 45",
"45/F0 45",
"0",
")"
],
[
"12",
"0C/8C",
"4E/F0 4E",
"4E/F0 4E",
"-",
"_"
],
[
"13",
"0D/8D",
"55/F0 55",
"55/F0 55",
"=",
"+"
],
[
"15",
"0E/8E",
"66/F0 66",
"66/F0 66",
"Backspace",
""
],
[
"16",
"0F/8F",
"0D/F0 0D",
"0D/F0 0D",
"Tab",
""
],
[
"17",
"10/90",
"15/F0 15",
"15/F0 15",
"q",
"Q"
],
[
"18",
"11/91",
"1D/F0 1D",
"1D/F0 1D",
"w",
"W"
],
[
"19",
"12/92",
"24/F0 24",
"24/F0 24",
"e",
"E"
],
[
"20",
"13/93",
"2D/F0 2D",
"2D/F0 2D",
"r",
"R"
],
[
"21",
"14/94",
"2C/F0 2C",
"2C/F0 2C",
"t",
"T"
],
[
"22",
"15/95",
"35/F0 35",
"35/F0 35",
"y",
"Y"
],
[
"23",
"16/96",
"3C/F0 3C",
"3C/F0 3C",
"u",
"U"
],
[
"24",
"17/97",
"43/F0 43",
"43/F0 43",
"i",
"I"
],
[
"25",
"18/98",
"44/F0 44",
"44/F0 44",
"o",
"O"
],
[
"26",
"19/99",
"4D/F0 4D",
"4D/F0 4D",
"p",
"P"
],
[
"27",
"1A/9A",
"54/F0 54",
"54/F0 54",
"[",
"{"
],
[
"28",
"1B/9B",
"5B/F0 5B",
"5B/F0 5B",
"]",
"}"
],
[
"30",
"3A/BA",
"58/F0 58",
"58/F0 58",
"Caps Lock",
""
],
[
"31",
"1E/9E",
"1C/F0 1C",
"1C/F0 1C",
"a",
"A"
],
[
"32",
"1F/9F",
"1B/F0 1B",
"1B/F0 1B",
"s",
"S"
],
[
"33",
"20/A0",
"23/F0 23",
"23/F0 23",
"d",
"D"
],
[
"34",
"21/A1",
"2B/F0 2B",
"2B/F0 2B",
"f",
"F"
],
[
"35",
"22/A2",
"34/F0 34",
"34/F0 34",
"g",
"G"
],
[
"36",
"23/A3",
"33/F0 33",
"33/F0 33",
"h",
"H"
],
[
"37",
"24/A4",
"3B/F0 3B",
"3B/F0 3B",
"j",
"J"
],
[
"38",
"25/A5",
"42/F0 42",
"42/F0 42",
"k",
"K"
],
[
"39",
"26/A6",
"4B/F0 4B",
"4B/F0 4B",
"l",
"L"
],
[
"40",
"27/A7",
"4C/F0 4C",
"4C/F0 4C",
";",
":"
],
[
"41",
"28/A8",
"52/F0 52",
"52/F0 52",
"'",
"\""
],
[
"43",
"1C/9C",
"5A/F0 5A",
"5A/F0 5A",
"Enter",
"Enter"
],
[
"44",
"2A/AA",
"12/F0 12",
"12/F0 12",
"Left Shift",
""
],
[
"46",
"2C/AC",
"1A/F0 1A",
"1A/F0 1A",
"z",
"Z"
],
[
"47",
"2D/AD",
"22/F0 22",
"22/F0 22",
"x",
"X"
],
[
"48",
"2E/AE",
"21/F0 21",
"21/F0 21",
"c",
"C"
],
[
"49",
"2F/AF",
"2A/F0 2A",
"2A/F0 2A",
"v",
"V"
],
[
"50",
"30/B0",
"32/F0 32",
"32/F0 32",
"b",
"B"
],
[
"51",
"31/B1",
"31/F0 31",
"31/F0 31",
"n",
"N"
],
[
"52",
"32/B2",
"3A/F0 3A",
"3A/F0 3A",
"m",
"M"
],
[
"53",
"33/B3",
"41/F0 41",
"41/F0 41",
",",
"<"
],
[
"54",
"34/B4",
"49/F0 49",
"49/F0 49",
".",
">"
],
[
"55",
"35/B5",
"4A/F0 4A",
"4A/F0 4A",
"/",
"?"
],
[
"57",
"36/B6",
"59/F0 59",
"59/F0 59",
"Right Shift",
""
],
[
"58",
"1D/9D",
"14/F0 14",
"11/F0 11",
"Left Ctrl",
""
],
[
"60",
"38/B8",
"11/F0 11",
"19/F0 19",
"Left Alt",
""
],
[
"61",
"39/B9",
"29/F0 29",
"29/F0 29",
"Spacebar",
""
],
[
"62",
"E0 38/E0 B8",
"E0 11/E0 F0 11",
"39/F0 39",
"Right Alt",
""
],
[
"64",
"E0 1D/E0 9D",
"E0 14/E0 F0 14",
"58/F0 58",
"Right Ctrl",
""
],
[
"75",
"E0 52/E0 D2 (base)",
"E0 70/E0 F0 70 (base)",
"67/F0 67",
"Insert",
""
],
[
"76",
"E0 4B/E0 CB (base)",
"E0 71/E0 F0 71 (base)",
"64/F0 64",
"Delete",
""
],
[
"79",
"E0 4B/E0 CB (base)",
"E0 6B/E0 F0 6B (base)",
"61/F0 61",
"Left Arrow",
""
],
[
"80",
"E0 47/E0 C7 (base)",
"E0 6C/E0 F0 6C (base)",
"6E/F0 6E",
"Home",
""
],
[
"81",
"E0 4F/E0 CF (base)",
"E0 69/E0 F0 69 (base)",
"65/F0 65",
"End",
""
],
[
"83",
"E0 48/E0 C8 (base)",
"E0 75/E0 F0 75 (base)",
"63/F0 63",
"Up Arrow",
""
],
[
"84",
"E0 50/E0 D0 (base)",
"E0 72/E0 F0 72 (base)",
"60/F0 60",
"Down Arrow",
""
],
[
"85",
"E0 49/E0 C9 (base)",
"E0 7D/E0 F0 7D (base)",
"6F/F0 6F",
"Page Up",
""
],
[
"86",
"E0 51/E0 D1 (base)",
"E0 7A/E0 F0 7A (base)",
"6D/F0 6D",
"Page Down",
""
],
[
"89",
"E0 4D/E0 CD (base)",
"E0 74/E0 F0 74 (base)",
"6A/F0 6A",
"Right Arrow",
""
],
[
"90",
"45/C5",
"77/F0 77",
"76/F0 76",
"Num Lock",
""
],
[
"91",
"47/C7",
"6C/F0 6C",
"6C/F0 6C",
"Keypad 7",
""
],
[
"92",
"4B/CB",
"6B/F0 6B",
"6B/F0 6B",
"Keypad 4",
""
],
[
"93",
"4F/CF",
"69/F0 69",
"69/F0 69",
"Keypad 1",
""
],
[
"95",
"E0 35/E0 B5 (base)",
"E0 4A/E0 F0 4A (base)",
"77/F0 77",
"Keypad /",
""
],
[
"96",
"48/C8",
"75/F0 75",
"75/F0 75",
"Keypad 8",
""
],
[
"97",
"4C/CC",
"73/F0 73",
"73/F0 73",
"Keypad 5",
""
],
[
"98",
"50/D0",
"72/F0 72",
"72/F0 72",
"Keypad 2",
""
],
[
"99",
"52/D2",
"70/F0 70",
"70/F0 70",
"Keypad 0",
""
],
[
"100",
"37/B7",
"7C/F0 7C",
"7E/F0 7E",
"Keypad *",
""
],
[
"101",
"49/C9",
"7D/F0 7D",
"7D/F0 7D",
"Keypad 9",
""
],
[
"102",
"4D/CD",
"74/F0 74",
"74/F0 74",
"Keypad 6",
""
],
[
"103",
"51/D1",
"7A/F0 7A",
"7A/F0 7A",
"Keypad 3",
""
],
[
"104",
"53/D3",
"71/F0 71",
"71/F0 71",
"Keypad .",
""
],
[
"105",
"4A/CA",
"7B/F0 7B",
"84/F0 84",
"Keypad -",
""
],
[
"106",
"4E/CE",
"79/F0 79",
"7C/F0 7C",
"Keypad +",
""
],
[
"108",
"E0 1C/E0 9C",
"E0 5A/E0 F0 5A",
"79/F0 79",
"Keypad Enter",
""
],
[
"110",
"01/81",
"76/F0 76",
"08/F0 08",
"Esc",
""
],
[
"112",
"3B/BB",
"05/F0 05",
"07/F0 07",
"F1",
""
],
[
"113",
"3C/BC",
"06/F0 06",
"0F/F0 0F",
"F2",
""
],
[
"114",
"3D/BD",
"04/F0 04",
"17/F0 17",
"F3",
""
],
[
"115",
"3E/BE",
"0C/F0 0C",
"1F/F0 1F",
"F4",
""
],
[
"116",
"3F/BF",
"03/F0 03",
"27/F0 27",
"F5",
""
],
[
"117",
"40/C0",
"0B/F0 0B",
"2F/F0 2F",
"F6",
""
],
[
"118",
"41/C1",
"83/F0 83",
"37/F0 37",
"F7",
""
],
[
"119",
"42/C2",
"0A/F0 0A",
"3F/F0 3F",
"F8",
""
],
[
"120",
"43/C3",
"01/F0 01",
"47/F0 47",
"F9",
""
],
[
"121",
"44/C4",
"09/F0 09",
"4F/F0 4F",
"F10",
""
],
[
"122",
"57/D7",
"78/F0 78",
"56/F0 56",
"F11",
""
],
[
"123",
"58/D8",
"07/F0 07",
"5E/F0 5E",
"F12",
""
],
[
"124",
"E0 2A E0 37/E0 B7 E0 AA",
"E0 12 E0 7C/E0 F0 7C E0 F0 12",
"57/F0 57",
"Print Screen",
""
],
[
"125",
"46/C6",
"7E/F0 7E",
"5F/F0 5F",
"Scroll Lock",
""
],
[
"126",
"E1 1D 45/E1 9D C5",
"E1 14 77 E1/F0 14 F0 77",
"62/F0 62",
"Pause Break",
""
],
[
"29 or 42*",
"2B/AB",
"5D/F0 5D",
"5C/F0 5C or 53/F0 53",
"\\",
"|"
]
]

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
import functools
import itertools
import json
import unicodedata
from typing import NamedTuple, List, Optional
import pyperclip
class KeyCode(NamedTuple):
scan_code: int
name_lower: str
name_upper: str
ascii_lower: Optional[str]
ascii_upper: Optional[str]
# scancodes retrieved from https://wiki.osdev.org/PS/2_Keyboard
# scancodes transformed with https://www.convertjson.com/html-table-to-json.htm
blacklist_names = {'(zero)'}
special_map = {
'\\': 'forwardSlash',
'/': 'backSlash',
'[': 'bracketLeft',
']': 'bracketRight',
';': 'colonPressed',
"'": None,
'`': None,
',': 'comma',
'.': 'dot',
# todo keypad *
'-': 'dash',
'=': 'equals',
}
def get_unknown(i):
return KeyCode(i, f"Unknown{i:02x}Lower", f"Unknown{i:02x}Upper", None, None)
def not_in_blacklist(name: str) -> bool:
return name not in blacklist_names
def remove_braces(name: str) -> str:
name = name.lstrip('(').rstrip(')')
if name in special_map:
return special_map[name]
return name
def key_name_to_name(names: List[str]) -> str:
_names: List[str] = list(filter(lambda i: i is not None, map(remove_braces, filter(not_in_blacklist, names))))
_names_cap = itertools.chain([_names[0][0].lower() + _names[0][1:]],
map(lambda i: i[0].upper() + i[1:], _names[1:]))
return ''.join(_names_cap)
def get_name(item: str):
item = item.replace(' ', ' ')
if len(item) == 1:
item = unicodedata.name(item).title()
if item.startswith('Latin'):
return 'Letter' + item.split()[-1]
return item.replace(' ', '_') if item else None
def transform_set1(path):
codes = []
with open(path) as f:
data = json.load(f)
for ibm_number, make_break_1, _, _, lower, upper in data:
make_code, break_code = make_break_1.split('/')
if make_code.startswith('E0') or make_code.startswith('E1'):
# skipping multi codes for now
continue
make_code_i = int(make_code, base=16)
break_code_i = int(break_code, base=16)
if make_code_i != break_code_i ^ 0x80:
raise ValueError("Make/Break not equal" + ibm_number)
codes.append(KeyCode(
make_code_i,
get_name(lower),
get_name(upper),
lower,
upper,
))
codes_map = {}
for code in codes:
if code.scan_code in codes_map:
raise ValueError(f"Duplicate code {code!r}")
codes_map[code.scan_code] = code
# max_val = functools.reduce(lambda a, b: max(a, b), map(lambda x: x.scan_code, codes), 0)
return codes_map
# txts = []
# for i in range(max_val):
# code = codes_map.get(i) or get_unknown(i)
# txts.append(f'{code.scan_code}\t{code.name_lower}\t{code.name_upper}\t{code.ascii_lower or None}\t{code.ascii_upper or None}')
# pyperclip.copy('\n'.join(txts))
def get_ascii_val(val: str):
if not val:
return 'NULL'
if len(val) > 1:
return 'NULL'
if val == "'":
return "'\\''"
return repr(val)
def main():
transform_set1()
if __name__ == '__main__':
main()