added ide block device added mbr block device driver started fat block device driver reordered boot start timer before pci/ide/etc. enable interrupts earlier fixed exception from ide controller cleanup code more printfs
202 lines
5.1 KiB
C
202 lines
5.1 KiB
C
#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>
|
|
#include <mem/mem.h>
|
|
#include <multiboot.h>
|
|
#include <drivers/serial.h>
|
|
#include <kprint.h>
|
|
#include <libc/readline.h>
|
|
#include <libc/string.h>
|
|
#include <libk.h>
|
|
#include <drivers/pci.h>
|
|
#include <drivers/ide.h>
|
|
#include <libc/kprintf.h>
|
|
#include <fs/mbr.h>
|
|
#include <fs/blockdev.h>
|
|
|
|
#define BOOTLOADER_NAME_MAX_LENGTH 64
|
|
#define CMDLINE_MAX_LENGTH 256
|
|
|
|
const char *msg_booted = "Booted Successfully!\n";
|
|
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();
|
|
|
|
// 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("%s v%d.%d.%d\n", msg_booted, version_major, version_minor, version_patch);
|
|
// print_gdt();
|
|
|
|
// u8* tmp = malloc(4096);
|
|
// ide_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) {
|
|
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);
|
|
} |