#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BOOTLOADER_NAME_MAX_LENGTH 64 #define CMDLINE_MAX_LENGTH 256 const char *msg_booted = "Booted Successfully!\n"; const char *newline = "\n"; const char *msg_unknown_command = "Unknown command: "; char bootloader_name[BOOTLOADER_NAME_MAX_LENGTH]; char cmdline[CMDLINE_MAX_LENGTH]; typedef void (*cmd_handler_func)(const char *); typedef struct { char *cmd; cmd_handler_func handler; } cmd_handler; void print(const char *arg); void echo(const char *arg); void help(const char *arg); cmd_handler cmd_handlers[] = { {"help", help}, {"echo", echo}, {"print", print}, {NULL, NULL}, }; void print_bootinfo() { kprint("Bootloader name: "); kprint(bootloader_name[0] == 0 ? "NULL" : bootloader_name); kprint(newline); kprint("cmdline: "); kprint(cmdline[0] == 0 ? "NULL" : cmdline); kprint(newline); } void help(const char* arg) { kprint("Available commands:\n"); int index = 0; while (true) { if (cmd_handlers[index].cmd == NULL) { break; } kprint(cmd_handlers[index].cmd); kprint(newline); index += 1; } } void echo(const char *arg) { kprint(arg); kprint(newline); } void print(const char *arg) { if (strcmp(arg, "mmap") == 0) { print_mmap_info(); } else if (strcmp(arg, "malloc") == 0) { print_malloc_info(); } else if (strcmp(arg, "tick") == 0) { print_current_tick(); } else if (strcmp(arg, "bootinfo") == 0) { print_bootinfo(); } else if (strcmp(arg, "pci") == 0) { pci_print_info(); } else { kprint("Unknown print "); kprint(arg); kprint(newline); } } void main_loop(); void store_bootloader_info(multiboot_info_t *multiboot_info) { // get bootloader and cmdline if (multiboot_info->flags & MULTIBOOT_INFO_CMDLINE) { int cmdline_length = strlen((const char *) multiboot_info->cmdline); if (cmdline_length > CMDLINE_MAX_LENGTH) { kprint("cmdline to long!"); k_panic(); } memcpy(cmdline, (char *) multiboot_info->cmdline, cmdline_length); } if (multiboot_info->flags & MULTIBOOT_INFO_BOOT_LOADER_NAME) { int bootloader_length = strlen((const char *) multiboot_info->boot_loader_name); if (bootloader_length > BOOTLOADER_NAME_MAX_LENGTH) { kprint("bootloader name to long!"); k_panic(); } memcpy(bootloader_name, (char *) multiboot_info->boot_loader_name, bootloader_length); } } void init_mmap(multiboot_info_t *multiboot_info) { if (multiboot_info->flags & (1 << 6)) { init_mmap_multiboot((struct multiboot_mmap_entry *) multiboot_info->mmap_addr, multiboot_info->mmap_length / sizeof(struct multiboot_mmap_entry)); // todo fallback on other mechanisms? } else { kprint("mmap invalid!\n"); k_panic(); } } void register_pci_drivers() { ide_register(); } void init_pci_system() { register_pci_drivers(); pci_sort_drivers(); pci_scan(); pci_init_drivers(); } void kmain(multiboot_info_t *multiboot_info) { isr_install(); vga_clear_screen(); vga_clear_screen(' ', VGA_WHITE | (VGA_GRAY << VGA_SHIFT_BG)); kprint_register(vga_kprint); serial_init(); kprint_register(serial_kprint); store_bootloader_info(multiboot_info); init_mmap(multiboot_info); init_pci_system(); kprint(msg_booted); kprint(newline); // init done, enable interrupts __asm__ __volatile__("sti"); // init timer for future task switching init_timer(1000); // setup PS/2 keyboard init_keyboard(); u8* tmp = malloc(4096); ide_read_access(0, 0, 0, 16, tmp); // enter main loop while (true) { main_loop(); } } void main_loop() { char *msg = readline(NULL); char *args = strchr(msg, ' ') + 1; args[-1] = 0; int test_index = 0; while (true) { if (cmd_handlers[test_index].cmd == 0) { kprint(msg_unknown_command); kprint(msg); kprint(newline); break; } if (strcmp(cmd_handlers[test_index].cmd, msg) == 0) { cmd_handlers[test_index].handler(args); break; } test_index++; } free(msg); }