#include #include #include #include #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 int version_major = 0, version_minor = 0, version_patch = 1; 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 ide(const char *arg); void echo(const char *arg); void help(const char *arg); cmd_handler cmd_handlers[] = { {"help", help}, {"echo", echo}, {"print", print}, {"ide", ide}, {NULL, NULL}, }; void print_bootinfo() { printf("Bootloader name: %s\n" "cmdline: %s\n", (bootloader_name[0] == 0 ? "NULL" : bootloader_name), (cmdline[0] == 0 ? "NULL" : cmdline)); } void help(const char *arg) { kprint("Available commands:\n"); int index = 0; while (true) { if (cmd_handlers[index].cmd == NULL) { break; } printf("%s\n", cmd_handlers[index].cmd); index += 1; } } void echo(const char *arg) { printf("%s\n", arg); } 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 if (strcmp(arg, "ide") == 0) { ide_print_devices(); } else { printf("Unknown print %s\n", arg); } } void ide(const char *arg) { if (strcmp(arg, "block_devices") == 0) { block_dev_print_info(); } else if (strcmp(arg, "ide_devices") == 0) { ide_print_devices(); } else if (strcmp(arg, "mbr") == 0) { mbr_read_from_ide(0); } else { printf("Unknown print %s\n", arg); } } 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) { k_panics("cmdline to long!\n"); } 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) { k_panics("bootloader name to long!\n"); } 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 { k_panics("mmap invalid!\n"); } } void register_pci_drivers() { ide_register(); } void init_pci_system() { register_pci_drivers(); pci_sort_drivers(); pci_scan(); pci_init_drivers(); } void init_block_devices() { // register drivers mbr_register_block_driver(); fat_register_block_driver(); // scan block_dev_scan_repeat(); } 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 done, enable interrupts __asm__ __volatile__("sti"); init_timer(1000); init_keyboard(); init_pci_system(); init_block_devices(); printf("Booted successfully v%d.%d.%d\n", version_major, version_minor, version_patch); // 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) { printf("Unknown command: %s\n", msg); break; } if (strcmp(cmd_handlers[test_index].cmd, msg) == 0) { cmd_handlers[test_index].handler(args); break; } test_index++; } free(msg); }