diff --git a/src/hos_main.c b/src/hos_main.c index 8249cfe..42f9538 100644 --- a/src/hos_main.c +++ b/src/hos_main.c @@ -1,33 +1,8 @@ #include #include "fb.h" +#include "mbinfo.h" -static uint32_t * process_mbinfo_tag(uint32_t * mbinfo) +void hos_main(uint32_t mbinfo_addr) { - uint32_t type = mbinfo[0]; - uint32_t size = mbinfo[1]; - switch (type) - { - case 0u: - return 0u; - - case 8u: - fb_init((uint32_t *)mbinfo[2], mbinfo[5], mbinfo[6], mbinfo[4]); - break; - } - return (uint32_t *)(((uint32_t)mbinfo + size + 7u) & 0xFFFFFFF8u); -} - -static void process_mbinfo(uint32_t * mbinfo) -{ - /* Skip multiboot2 boot information header. */ - mbinfo += 2u; - do - { - mbinfo = process_mbinfo_tag(mbinfo); - } while (mbinfo != (uint32_t *)0u); -} - -void hos_main(uint32_t * mbinfo) -{ - process_mbinfo(mbinfo); + mbinfo_init(mbinfo_addr); } diff --git a/src/mbinfo.c b/src/mbinfo.c new file mode 100644 index 0000000..8af9d0d --- /dev/null +++ b/src/mbinfo.c @@ -0,0 +1,29 @@ +#include "multiboot2.h" +#include "fb.h" + +static void mbinfo_process_tag(multiboot2_info_tag_t * tag) +{ + switch (tag->type) + { + case MULTIBOOT2_INFO_FRAMEBUFFER_INFO: + { + multiboot2_info_framebuffer_info_t * fbinfo = + (multiboot2_info_framebuffer_info_t *)tag; + fb_init((uint32_t *)(uintptr_t)fbinfo->framebuffer_addr, + fbinfo->framebuffer_width, + fbinfo->framebuffer_height, + fbinfo->framebuffer_pitch); + } + break; + } +} + +void mbinfo_init(uint32_t mbinfo_addr) +{ + multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo_addr + sizeof(multiboot2_info_header_t)); + while (tag->type != 0u) + { + mbinfo_process_tag(tag); + tag = multiboot2_info_next_tag(tag); + } +} diff --git a/src/mbinfo.h b/src/mbinfo.h new file mode 100644 index 0000000..314f675 --- /dev/null +++ b/src/mbinfo.h @@ -0,0 +1,8 @@ +#ifndef MBINFO_H +#define MBINFO_H + +#include + +void mbinfo_init(uint32_t mbinfo_addr); + +#endif diff --git a/src/multiboot2.h b/src/multiboot2.h index e8cd8d9..797deca 100644 --- a/src/multiboot2.h +++ b/src/multiboot2.h @@ -34,4 +34,49 @@ typedef struct { #define multiboot2_framebuffer_tag(width, height, depth) \ {{5u, 0u, 20u}, width, height, depth} +#define MULTIBOOT2_INFO_TAG_ALIGNMENT 8u +#define MULTIBOOT2_INFO_BOOT_COMMAND_LINE 1u +#define MULTIBOOT2_INFO_BOOT_LOADER_NAME 2u +#define MULTIBOOT2_INFO_MODULES 3u +#define MULTIBOOT2_INFO_BASIC_MEMORY_INFO 4u +#define MULTIBOOT2_INFO_BIOS_BOOT_DEVICE 5u +#define MULTIBOOT2_INFO_MEMORY_MAP 6u +#define MULTIBOOT2_INFO_VBE_INFO 7u +#define MULTIBOOT2_INFO_FRAMEBUFFER_INFO 8u +#define MULTIBOOT2_INFO_ELF_SYMBOLS 9u +#define MULTIBOOT2_INFO_APM_TABLE 10u +#define MULTIBOOT2_INFO_EFI_32BIT_SYSTEM_TABLE_POINTER 11u +#define MULTIBOOT2_INFO_EFI_64BIT_SYSTEM_TABLE_POINTER 12u +#define MULTIBOOT2_INFO_SMBIOS_TABLES 13u +#define MULTIBOOT2_INFO_ACPI_OLD_RSDP 14u +#define MULTIBOOT2_INFO_NETWORKING_INFO 16u +#define MULTIBOOT2_INFO_EFI_MEMORY_MAP 17u +#define MULTIBOOT2_INFO_EFI_BOOT_SERVICES_NOT_TERMINATED 18u +#define MULTIBOOT2_INFO_EFI_32BIT_IMAGE_HANDLE_POINTER 19u +#define MULTIBOOT2_INFO_EFI_64BIT_IMAGE_HANDLE_POINTER 20u +#define MULTIBOOT2_INFO_IMAGE_LOAD_BASE_PHYSICAL_ADDRESS 21u + +typedef struct { + uint32_t total_size; + uint32_t _reserved; +} multiboot2_info_header_t; + +typedef struct { + uint32_t type; + uint32_t size; +} multiboot2_info_tag_t; +#define multiboot2_info_next_tag(current_tag) \ + (multiboot2_info_tag_t *)(((uintptr_t)current_tag + current_tag->size + MULTIBOOT2_INFO_TAG_ALIGNMENT - 1u) & ~(MULTIBOOT2_INFO_TAG_ALIGNMENT - 1u)) + +typedef struct { + multiboot2_info_tag_t header; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; + uint8_t _reserved; +} multiboot2_info_framebuffer_info_t; + #endif