diff --git a/defaults.mk b/defaults.mk index 9aba905..86110d7 100644 --- a/defaults.mk +++ b/defaults.mk @@ -16,3 +16,6 @@ LDFLAGS = -melf_i386 ASFLAGS = ARFLAGS = +# Qemu +AUDIODEV = pipewire + diff --git a/kernel/include/bootloader.h b/kernel/include/bootloader.h index ccf5cde..2383072 100644 --- a/kernel/include/bootloader.h +++ b/kernel/include/bootloader.h @@ -9,25 +9,41 @@ #define BOOT_MB2 2 // MultiBoot 2 #define BOOT_LIMINE 3 // Limine -struct boot_memmapEntry { - uint64_t base; - uint64_t size; - uint32_t type; - uint32_t attr; -}; +// Memmap region types +#define BOOT_MMAP_AVAILABLE 1 +#define BOOT_MMAP_RESERVED 2 +#define BOOT_MMAP_ACPI_RECLAIM 3 +#define BOOT_MMAP_NVS 4 +#define BOOT_MMAP_BADRAM 5 + +// A memory map entry +struct boot_memmap { + uint32_t skip; // Used for skipping (may be padded for alignment) + uint64_t base; // Memory region address + uint64_t size; // Memory region length + uint32_t type; // Memory region type +} __packed; /* * Some values may not be provided by the bootloader, in this case * pointers will be NULL and integer values will be 0 if applicable. * Some unprovided values may also be implied. Eg.: * If 'memmap = NULL' then 'memmapLen' doesn't matter. + */ struct boot_info { uint32_t memLower; uint32_t memUpper; - struct boot_memmapEntry* memmap; + uint8_t bootDrive; + uint8_t bootPart1; + uint8_t bootPart2; + uint8_t bootPart3; + char* cmdline; + uint32_t memmap; size_t memmapLen; -}; + char* bootname; +} __packed; +extern struct boot_info bootloader; /* * This functions arguments depend on the boot protocol provided. @@ -36,9 +52,9 @@ struct boot_info { */ int boot_init(int type, ...); -int boot_init_mb1(void* ptr, uint32_t magic); +int boot_initMB1(void* ptr, uint32_t magic); // TODO: -// int boot_init_mb2(...); -// int boot_init_limine(...); +// int boot_initMB2(...); +// int boot_initLimine(...); #endif diff --git a/kernel/include/kernel.h b/kernel/include/kernel.h index 021e802..703b0f3 100644 --- a/kernel/include/kernel.h +++ b/kernel/include/kernel.h @@ -7,11 +7,12 @@ /* * Variable arguments */ -typedef void* va_list; -#define __va_align(size) ((size + sizeof(int) - 1) & ~(sizeof(int) - 1)) -#define va_start(ap, param) (void)((ap) = (char*)(&(param) + 1)) -#define va_end(ap) (void)((ap) = 0) -#define va_arg(ap, type) (*(type*)(((ap) += __va_align(sizeof(type))) - sizeof(type))) +typedef char* va_list; +#define __VA_ALIGN 4 +#define __va_align(_t) (((sizeof(_t) + __VA_ALIGN - 1) / __VA_ALIGN) * __VA_ALIGN) +#define va_start(_ap, _arg) ((_ap) = (char*)(&(_arg) + 1)) +#define va_arg(_ap, _type) (*(_type*)((_ap += __va_align(_type)) - __va_align(_type))) +#define va_end(_ap) (void)((_ap) = 0) /* * Utility macros diff --git a/kernel/src/bootloader.c b/kernel/src/bootloader.c index ad998d1..ba08013 100644 --- a/kernel/src/bootloader.c +++ b/kernel/src/bootloader.c @@ -2,46 +2,59 @@ #include #include -struct boot_info bootloader = { 0 }; +struct boot_info bootloader; +// TODO: int boot_init(int type, ...) { - va_list args; - va_start(args, type); - - switch (type) { - case BOOT_UNKNOWN: return 1; - case BOOT_MB1: return boot_init_mb1(va_arg(args, void*), va_arg(args, uint32_t)); - case BOOT_MB2: return 1; - case BOOT_LIMINE: return 1; - } - - // We got an invalid boot protocol return 1; } -int boot_init_mb1(void* ptr, uint32_t magic) { +int boot_initMB1(void* ptr, uint32_t magic) { multiboot_info_t* mbi = ptr; - if (magic != 0xBADB002) return 1; + if (magic != MULTIBOOT_BOOTLOADER_MAGIC) return 1; - // Memory info + // mem_* fields are valid if (mbi->flags & MULTIBOOT_INFO_MEMORY) { bootloader.memLower = mbi->mem_lower; bootloader.memUpper = mbi->mem_upper; } - // Memory map - if (mbi->flags & MULTIBOOT_INFO_MEM_MAP) { - uint32_t memmap = mbi->mmap_addr; - uint32_t offset = 0; - while (offset < mbi->mmap_length) { - multiboot_memory_map_t* entry = (multiboot_memory_map_t*)(memmap + offset); - offset += entry->size; - - - } + // boot_device is valid + if (mbi->flags & MULTIBOOT_INFO_BOOTDEV) { + bootloader.bootDrive = (mbi->boot_device & 0xff000000) >> 24; + bootloader.bootPart1 = (mbi->boot_device & 0x00ff0000) >> 16; + bootloader.bootPart2 = (mbi->boot_device & 0x0000ff00) >> 8; + bootloader.bootPart3 = (mbi->boot_device & 0x000000ff); } + // cmdline is valid + if (mbi->flags & MULTIBOOT_INFO_CMDLINE) { + bootloader.cmdline = (char*)mbi->cmdline; + } + + // TODO: mods + // TODO: a.out symbol table + // TODO: ELF symbol table + + // mmap_* fields are valid + if (mbi->flags & MULTIBOOT_INFO_MEM_MAP) { + bootloader.memmap = mbi->mmap_addr; + bootloader.memmapLen = mbi->mmap_length; + } + + // TODO: drives_* + // TODO: config_table + + // boot_loader_name is valid + if (mbi->flags & MULTIBOOT_INFO_BOOT_LOADER_NAME) { + bootloader.bootname = (char*)mbi->boot_loader_name; + } + + // TODO: APM table + // TODO: VBE table + // TODO: Framebuffer + return 0; } diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index 045e7b2..7d7953f 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -7,11 +7,13 @@ __noreturn void kmain(void* ptr, uint32_t magic) { - if (boot_init(BOOT_MB1, ptr, magic) != 0) panic("Unsupporred bootloader."); + if (boot_initMB1(ptr, magic) != 0) panic("Unsupporred bootloader."); // Serial console for debugging serial_init(COM1); - debugf("\x1b[H\x1b[J\x1b[0mkern. \x1b[35m(serial console)\x1b[0m\n\n"); + // ESC[H moves cursor to (0,0), ESC[J clears from cursor to end of screen + // ESC[m sets graphics mode, 0 - reset, 36 - cyan + debugf("\x1b[H\x1b[J\x1b[0mkern. \x1b[36m(serial console)\x1b[0m\n\n"); // VGA tty thingy tty_init(); @@ -26,6 +28,24 @@ void kmain(void* ptr, uint32_t magic) { // pag_init(); debugf("Basic initialization complete!\n"); + + struct boot_memmap* entry; + for ( + entry = (struct boot_memmap*)bootloader.memmap; + (uint64_t)entry < bootloader.memmap + bootloader.memmapLen; + entry = (struct boot_memmap*)((uint64_t)entry + entry->skip + sizeof(entry)) + ) { + + debugf("[Region] base: %x size: %x b type: ", entry->base, entry->size); + switch (entry->type) { + case BOOT_MMAP_AVAILABLE: debugf("Available\n"); break; + case BOOT_MMAP_RESERVED: debugf("Reserved\n"); break; + case BOOT_MMAP_ACPI_RECLAIM: debugf("ACPI Reclaim\n"); break; + case BOOT_MMAP_NVS: debugf("NVS\n"); break; + case BOOT_MMAP_BADRAM: debugf("Bad RAM\n"); break; + default: debugf("Invalid type\n"); break; + } + } panic("kmain() reached end."); diff --git a/makefile b/makefile index ed4d98b..f2df9be 100644 --- a/makefile +++ b/makefile @@ -1,3 +1,5 @@ +include defaults.mk + KERNEL = ./kernel MODULES = $(KERNEL) @@ -17,5 +19,5 @@ qemu: -kernel ./kernel/kernel.elf\ -m 256M -accel tcg -monitor stdio -net none\ -rtc base=localtime,clock=host,driftfix=slew\ - -audiodev pipewire,id=audio0 -machine pcspk-audiodev=audio0 + -audiodev $(AUDIODEV),id=audio0 -machine pcspk-audiodev=audio0