From 4673a23db7d9ca9824d21a0f79881898514e88f2 Mon Sep 17 00:00:00 2001 From: Rick Rongen Date: Mon, 1 Feb 2021 23:28:24 +0100 Subject: [PATCH] stuff --- kernel/cpu/isr.c | 2 +- kernel/cpu/timer.c | 18 ++++++++--- kernel/cpu/timer.h | 1 + kernel/drivers/keyboard.c | 1 + kernel/kernel.c | 46 ++++++++++++++++++++-------- kernel/libc/libc.c | 64 +++++++++++++++++++++++++++++++++++---- kernel/libc/libc.h | 4 ++- kernel/libc/readline.c | 2 +- kernel/mem/mem.c | 36 +++++++++++++--------- kernel/mem/mem.h | 7 +++-- linker.ld | 1 - 11 files changed, 140 insertions(+), 42 deletions(-) diff --git a/kernel/cpu/isr.c b/kernel/cpu/isr.c index dd9c2e7..16bd8c7 100644 --- a/kernel/cpu/isr.c +++ b/kernel/cpu/isr.c @@ -121,7 +121,7 @@ char *exception_messages[] = { void isr_handler(registers_t r) { kprint("received interrupt: "); char s[3]; - itoa(r.int_no, s); + itoa(r.int_no, s, 10); kprint(s); kprint("\n"); kprint(exception_messages[r.int_no]); diff --git a/kernel/cpu/timer.c b/kernel/cpu/timer.c index b20571b..407cde3 100644 --- a/kernel/cpu/timer.c +++ b/kernel/cpu/timer.c @@ -6,16 +6,18 @@ #include #include +#include +#include // https://wiki.osdev.org/PIT #define PIT_MODE_BIN_BCD (1 << 0) #define PIT_MODE_BIN (0 << 0) #define PIT_MODE_BCD (1 << 0) #define PIT_GENERATOR_MODE (0b111 << 1) -#define PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT (0b000 < 1) -#define PIT_MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT (0b001 < 1) -#define PIT_MODE_HARDWARE_RATE_GENERATOR (0b010 < 1) -#define PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR (0b011 < 1) +#define PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT (0b000 << 1) +#define PIT_MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT (0b001 << 1) +#define PIT_MODE_HARDWARE_RATE_GENERATOR (0b010 << 1) +#define PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR (0b011 << 1) #define PIT_MODE_SOFTWARE_TRIGGERED_STROBE (0b100 << 1) #define PIT_MODE_HARDWARE_TRIGGERED_STROBE (0b101 << 1) #define PIT_ACCESS_MODE (0b11 << 4) @@ -35,6 +37,14 @@ static void timer_callback(registers_t regs) { tick++; } +void print_current_tick() { + char msg[32]; + memset(msg, 0, 32); + itoa(tick, msg, 10); + kprint(msg); + kprint("\n"); +} + int init_timer(u32 freq) { register_interrupt_handler(IRQ0, timer_callback); diff --git a/kernel/cpu/timer.h b/kernel/cpu/timer.h index a91e2c3..5bdc92a 100644 --- a/kernel/cpu/timer.h +++ b/kernel/cpu/timer.h @@ -8,5 +8,6 @@ #include int init_timer(u32 freq); +void print_current_tick(); #endif //MY_KERNEL_TIMER_H diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index e059ea0..add0829 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -88,6 +88,7 @@ char getc() { KeyEvent *get_next_event() { KeyEvent *target = malloc(sizeof(KeyEvent)); if (!ring_buffer_get(keyboard_event_buffer, target)) { + asm("hlt"); free(target); return NULL; } diff --git a/kernel/kernel.c b/kernel/kernel.c index c8e00ff..e097349 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -12,23 +12,43 @@ #include #include -char *msg_booted = "Booted Successfully!\n"; +const char *msg_booted = "Booted Successfully!\n"; +const char *newline = "\n"; +const char *msg_unknown_command = "Unknown command: "; + +const char *cmd_echo = "echo"; +const char *cmd_print_mmap = "print_mmap"; +const char *cmd_print_malloc = "print_malloc"; +const char *cmd_print_tick = "print_tick"; void main_loop(); +void panic() { + kprint("PANIC!"); + asm("cli;" + "hlt;"); +} + void kmain(multiboot_info_t *multiboot_info) { isr_install(); - init_mmap((struct multiboot_mmap_entry *) multiboot_info->mmap_addr, - multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry)); vga_clear_screen(); vga_clear_screen(' ', VGA_WHITE | (VGA_GRAY << VGA_SHIFT_BG)); kprint_register(vga_kprint); serial_init(); kprint_register(serial_kprint); + if (multiboot_info->flags & (1 << 6)) { + kprint("mmap valid\n"); + init_mmap((struct multiboot_mmap_entry *) multiboot_info->mmap_addr, + multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry)); + } else { + kprint("mmap invalid!\n"); + panic(); + } // vga_print_string(msg_booted, VGA_WHITE | (VGA_DARK_GRAY << VGA_SHIFT_BG)); kprint(msg_booted); kprint((char *) multiboot_info->boot_loader_name); + kprint(newline); // multiboot_memory_map_t *fe = multiboot_info->mmap_addr; // port_byte_out(0x3d4, 14); // int pos = port_byte_in(0x3d5); @@ -51,15 +71,9 @@ void kmain(multiboot_info_t *multiboot_info) { 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; + char *msg = readline(NULL); + char *args = strchr(msg, ' ') + 1; args[-1] = 0; if (strcmp(cmd_echo, msg) == 0) { kprint(args); @@ -70,10 +84,18 @@ void main_loop() { print_mmap_info(); goto _main_loop_end; } + if (strcmp(cmd_print_malloc, msg) == 0) { + print_malloc_info(); + goto _main_loop_end; + } + if (strcmp(cmd_print_tick, msg) == 0) { + print_current_tick(); + goto _main_loop_end; + } kprint(msg_unknown_command); kprint(msg); kprint(newline); -_main_loop_end: + _main_loop_end: free(msg); } \ No newline at end of file diff --git a/kernel/libc/libc.c b/kernel/libc/libc.c index a3a2aa2..44f3bb8 100644 --- a/kernel/libc/libc.c +++ b/kernel/libc/libc.c @@ -21,13 +21,65 @@ int memset(char *dst, char data, int amount) { return 0; } -int itoa(int i, char *target) { - target[0] = (char) (i % 10 + '0'); - target[1] = '\0'; - if (i > 9) { - itoa(i / 10, target + 1); +int abs(int val) { + if (val >= 0) { + return val; } - return 0; + return val * -1; +} + +// next stolen form https://www.techiedelight.com/implement-itoa-function-in-c/ +// inline function to swap two numbers +void swap(char *x, char *y) { + char t = *x; *x = *y; *y = t; +} + +// function to reverse buffer[i..j] +char* reverse(char *buffer, int i, int j) +{ + while (i < j) + swap(&buffer[i++], &buffer[j--]); + + return buffer; +} + +// Iterative function to implement itoa() function in C +char* itoa(int value, char* buffer, int base) +{ + // invalid input + if (base < 2 || base > 32) + return buffer; + + // consider absolute value of number + int n = abs(value); + + int i = 0; + while (n) + { + int r = n % base; + + if (r >= 10) + buffer[i++] = 65 + (r - 10); + else + buffer[i++] = 48 + r; + + n = n / base; + } + + // if number is 0 + if (i == 0) + buffer[i++] = '0'; + + // If base is 10 and value is negative, the resulting string + // is preceded with a minus sign (-) + // With any other base, value is always considered unsigned + if (value < 0 && base == 10) + buffer[i++] = '-'; + + buffer[i] = '\0'; // null terminate string + + // reverse the string and return it + return reverse(buffer, 0, i - 1); } int maxi(int a, int b) { diff --git a/kernel/libc/libc.h b/kernel/libc/libc.h index 04f5582..d5a3e7c 100644 --- a/kernel/libc/libc.h +++ b/kernel/libc/libc.h @@ -12,7 +12,9 @@ int memcpy(char *dst, char *src, int amount); int memset(char *dst, char data, int amount); -int itoa(int i, char *target); +char *itoa(int value, char *buffer, int base); + +int abs(int val); int maxi(int a, int b); diff --git a/kernel/libc/readline.c b/kernel/libc/readline.c index 52ca847..c71e607 100644 --- a/kernel/libc/readline.c +++ b/kernel/libc/readline.c @@ -18,7 +18,7 @@ char* readline(const char *prompt) { char* result = malloc(RESULT_SIZE); memset(result, 0, RESULT_SIZE); - for (int i = 0; i < RESULT_SIZE; ++i) { + for (int i = 0; i < RESULT_SIZE - 1; ++i) { result[i] = getc(); kprint(&result[i]); if (result[i] == '\n') { diff --git a/kernel/mem/mem.c b/kernel/mem/mem.c index 26a4706..d21f37d 100644 --- a/kernel/mem/mem.c +++ b/kernel/mem/mem.c @@ -33,6 +33,8 @@ char *msg_addr = "Address: "; char *msg_len = "Length: "; char *msg_type = "Type: "; char *msg_nl = "\n"; +char *msg_malloc_num_entries_avail = "Malloc avail entries: "; +char *msg_malloc_num_entries_used = "Malloc used entries: "; typedef struct { void *address; @@ -166,34 +168,40 @@ void free(void *mem) { }; -void print_hex_u64(u64 input) { - char msg[18] = "0x0000000000000000"; - for (int i = 0; i < 16; ++i) { - int val = input >> (4 * i) & 0xF; - msg[17 - i] = msg_lu[val]; - } - kprint(msg); +void print_int(int val, int base) { + char tmp_str[32]; + memset(tmp_str, 0, 32); + itoa(val, tmp_str, base); + kprint(tmp_str); } +void print_malloc_info() { + kprint(msg_malloc_num_entries_avail); + print_int(malloc_entries, 10); + kprint(msg_nl); + + kprint(msg_malloc_num_entries_used); + print_int(malloc_used, 10); + kprint(msg_nl); +} + + void print_mmap_info() { for (int i = 0; i < 16; ++i) { if (memmap[i].type == 0) { break; } - char *tmp_str = " "; kprint(msg_index); - itoa(i, tmp_str); - kprint(tmp_str); + print_int(i, 10); kprint(msg_nl); kprint(msg_addr); - print_hex_u64((u64) memmap[i].address); + print_int((int) memmap[i].address, 16); kprint(msg_nl); kprint(msg_len); - print_hex_u64((u64) memmap[i].length); + print_int(memmap[i].length, 16); kprint(msg_nl); kprint(msg_type); - itoa(memmap[i].type, tmp_str); - kprint(tmp_str); + print_int(memmap[i].type, 10); kprint(msg_nl); kprint(msg_nl); } diff --git a/kernel/mem/mem.h b/kernel/mem/mem.h index f017b81..8ff0825 100644 --- a/kernel/mem/mem.h +++ b/kernel/mem/mem.h @@ -9,9 +9,12 @@ void init_mmap(struct multiboot_mmap_entry *entries, u32 count); +void print_malloc_info(); + void print_mmap_info(); -void* malloc(unsigned int size); -void free(void* mem); +void *malloc(unsigned int size); + +void free(void *mem); #endif //NEW_KERNEL_MEM_H diff --git a/linker.ld b/linker.ld index 7591e42..01adc88 100644 --- a/linker.ld +++ b/linker.ld @@ -42,7 +42,6 @@ SECTIONS /DISCARD/ : { *(.eh_frame); *(.comment); - *(.gnu.hash); *(.note.gnu.build-id); }