diff --git a/Makefile b/Makefile index d98c3d5f..f617aaf5 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ endif GRUB_DIR := grub/boot GRUB_FILE := grub-file GRUB_MKRESCUE := grub-mkrescue -GRUB_MODULES := multiboot iso9660 serial normal +GRUB_MODULES := multiboot2 iso9660 serial normal ifneq ($(UNITTEST),) GRUB_CONFIG := $(GRUB_DIR)/grub/grub-test.cfg else @@ -254,7 +254,7 @@ $(ISO_FILE): dockerboot.iso else $(ISO_FILE): $(TARGET) @echo "GEN ISO" $(ISO_FILE) - $(VERBOSE) $(GRUB_FILE) --is-x86-multiboot $(TARGET) || { echo "Multiboot not supported"; exit 1; } + $(VERBOSE) $(GRUB_FILE) --is-x86-multiboot2 $(TARGET) || { echo "Multiboot not supported"; exit 1; } $(VERBOSE) cp $(TARGET) $(GRUB_DIR)/ $(VERBOSE) $(XZ) -q -f $(GRUB_DIR)/$(TARGET) $(VERBOSE) $(GRUB_MKRESCUE) --install-modules="$(GRUB_MODULES)" --fonts=no --compress=xz -o $(ISO_FILE) grub &> /dev/null diff --git a/arch/x86/boot/boot.S b/arch/x86/boot/boot.S index 404c0885..2e4cce34 100644 --- a/arch/x86/boot/boot.S +++ b/arch/x86/boot/boot.S @@ -24,38 +24,30 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -#include +#include -SECTION(.multiboot, "a", 4) -#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE) -#define MULTIBOOT_CHECKSUM -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) +SECTION(.multiboot, "a", 8) +#define MULTIBOOT2_HEADER_FLAGS (MULTIBOOT2_ARCHITECTURE_I386) +#define MULTIBOOT2_HEADER_SIZE (multiboot_header_end - multiboot_header) +#define MULTIBOOT2_CHECKSUM -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_FLAGS + MULTIBOOT2_HEADER_SIZE) -#define MULTIBOOT_VIDEO_MODE_GFX 0 -#define MULTIBOOT_VIDEO_MODE_TEXT 1 - -#define MULTIBOOT_MODE_TYPE MULTIBOOT_VIDEO_MODE_GFX - -#define MULTIBOOT_HEADER_ADDR 0 -#define MULTIBOOT_LOAD_ADDRESS 0 -#define MULTIBOOT_LOAD_END_ADDRESS 0 -#define MULTIBOOT_BSS_END_ADDRESS 0 -#define MULTIBOOT_ENTRY_ADDRESS 0 - -#define MULTIBOOT_FB_WIDTH 1024 -#define MULTIBOOT_FB_HEIGHT 768 -#define MULTIBOOT_FB_BPP 32 +#define MULTIBOOT2_FB_WIDTH 1024 +#define MULTIBOOT2_FB_HEIGHT 768 +#define MULTIBOOT2_FB_BPP 32 .code32 multiboot_header: - .long MULTIBOOT_HEADER_MAGIC - .long MULTIBOOT_HEADER_FLAGS - .long MULTIBOOT_CHECKSUM - .long MULTIBOOT_HEADER_ADDR - .long MULTIBOOT_LOAD_ADDRESS - .long MULTIBOOT_LOAD_END_ADDRESS - .long MULTIBOOT_BSS_END_ADDRESS - .long MULTIBOOT_ENTRY_ADDRESS - .long MULTIBOOT_MODE_TYPE - .long MULTIBOOT_FB_WIDTH - .long MULTIBOOT_FB_HEIGHT - .long MULTIBOOT_FB_BPP + .long MULTIBOOT2_HEADER_MAGIC + .long MULTIBOOT2_HEADER_FLAGS + .long MULTIBOOT2_HEADER_SIZE + .long MULTIBOOT2_CHECKSUM +framebuffer_tag_start: + .short MULTIBOOT2_HEADER_TAG_FRAMEBUFFER + .short MULTIBOOT2_HEADER_TAG_OPTIONAL + .long framebuffer_tag_end - framebuffer_tag_start + .long MULTIBOOT2_FB_WIDTH + .long MULTIBOOT2_FB_HEIGHT + .long MULTIBOOT2_FB_BPP +framebuffer_tag_end: + .quad MULTIBOOT2_HEADER_TAG_END +multiboot_header_end: diff --git a/arch/x86/boot/multiboot.c b/arch/x86/boot/multiboot.c index 97e9bfb0..ab1b750b 100644 --- a/arch/x86/boot/multiboot.c +++ b/arch/x86/boot/multiboot.c @@ -1,5 +1,6 @@ /* * Copyright © 2020 Amazon.com, Inc. or its affiliates. + * Copyright © 2022 Open Source Security, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,103 +23,189 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include -#include +#include +#include +#include -static multiboot_info_t *multiboot_info; +#define TAG_ADDR(tag) \ + ((multiboot2_tag_t *) ((multiboot2_uint8_t *) (tag) + (((tag)->size + 7) & ~7))) +#define TAG_STRING(tag) (((struct multiboot2_tag_string *) (tag))->string) -static multiboot_memory_map_t *multiboot_mmap; +static void *multiboot2_hdr; +static size_t multiboot2_hdr_size; + +static multiboot2_memory_map_t *multiboot_mmap; static unsigned multiboot_mmap_num; +static unsigned multiboot_mem_lower; +static unsigned multiboot_mem_upper; + static const char *multiboot_region_type_name[] = { - [MULTIBOOT_MEMORY_UNDEFINED] = "Undefined", - [MULTIBOOT_MEMORY_AVAILABLE] = "Available", - [MULTIBOOT_MEMORY_RESERVED] = "Reserved", - [MULTIBOOT_MEMORY_ACPI_RECLAIMABLE] = "ACPI Reclaimable", - [MULTIBOOT_MEMORY_NVS] = "NVS", - [MULTIBOOT_MEMORY_BADRAM] = "Bad RAM", + [MULTIBOOT2_MEMORY_AVAILABLE] = "Available", + [MULTIBOOT2_MEMORY_RESERVED] = "Reserved", + [MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE] = "ACPI Reclaimable", + [MULTIBOOT2_MEMORY_NVS] = "NVS", }; -static inline bool has_mbi_flag(unsigned flag) { - return multiboot_info && !!(multiboot_info->flags & flag); -} +static void handle_multiboot_mmap(struct multiboot2_tag_mmap *tag) { + multiboot2_uint8_t *tag_end = (multiboot2_uint8_t *) tag + tag->size; -void display_multiboot_mmap(void) { - if (!has_mbi_flag(MULTIBOOT_INFO_MEMORY)) - return; + BUG_ON(sizeof(multiboot2_memory_map_t) != tag->entry_size); - printk("\nPhysical Memory Map\n"); + multiboot_mmap = tag->entries; - if (!has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - printk("REGION: [0x%016lx - 0x%016lx] Lower memory\n", 0UL, - multiboot_info->mem_lower * KB(1)); - printk("REGION: [0x%016lx - 0x%016lx] Upper memory\n", MB(1), - MB(1) + (multiboot_info->mem_upper * KB(1))); - return; - } + for (multiboot2_memory_map_t *mmap = tag->entries; _ptr(mmap) < _ptr(tag_end); mmap++) + multiboot_mmap_num++; +} + +void display_multiboot_mmap(void) { + printk("Physical Memory Map\n"); for (unsigned int i = 0; i < multiboot_mmap_num; i++) { - multiboot_memory_map_t *entry = &multiboot_mmap[i]; + multiboot2_memory_map_t *mmap = &multiboot_mmap[i]; - if (entry->type != MULTIBOOT_MEMORY_UNDEFINED) { - printk("REGION: [0x%016lx - 0x%016lx] %s\n", entry->addr, - entry->addr + entry->len, multiboot_region_type_name[entry->type]); - } + printk("REGION: [0x%016lx - 0x%016lx] %s\n", mmap->addr, mmap->addr + mmap->len, + multiboot_region_type_name[mmap->type]); } } -void init_multiboot(multiboot_info_t *mbi, const char **cmdline) { - multiboot_info = mbi; +void init_multiboot(unsigned long *addr, const char **cmdline) { + dprintk("Initialize multiboot2\n"); + + multiboot2_hdr = addr; + multiboot2_hdr_size = *addr++; + + dprintk("[multiboot2] header at %p of size: %lx\n", multiboot2_hdr, + multiboot2_hdr_size); + + for (multiboot2_tag_t *tag = (multiboot2_tag_t *) addr; + tag->type != MULTIBOOT2_TAG_TYPE_END; tag = TAG_ADDR(tag)) { + switch (tag->type) { + case MULTIBOOT2_TAG_TYPE_CMDLINE: + *cmdline = TAG_STRING(tag); + break; + + case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME: + printk("[multiboot2] Boot loader name: %s\n", TAG_STRING(tag)); + break; + + case MULTIBOOT2_TAG_TYPE_MODULE: { + struct multiboot2_tag_module *mod = (struct multiboot2_tag_module *) tag; + + printk("[multiboot2] Module: [0x%08x - 0x%08x], Command line %s\n", + mod->mod_start, mod->mod_end, mod->cmdline); + } break; + + case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO: { + struct multiboot2_tag_basic_meminfo *meminfo = + (struct multiboot2_tag_basic_meminfo *) tag; + + multiboot_mem_lower = meminfo->mem_lower; + multiboot_mem_upper = meminfo->mem_upper; + + printk("[multiboot2] Lower memory: %u KB, Upper memory: %u KB\n", + multiboot_mem_lower, multiboot_mem_upper); + } break; + + case MULTIBOOT2_TAG_TYPE_BOOTDEV: { + struct multiboot2_tag_bootdev *bootdev = + (struct multiboot2_tag_bootdev *) tag; + + printk("[multiboot2] Boot device 0x%x,%x,%x\n", bootdev->biosdev, + bootdev->slice, bootdev->part); + } break; + + case MULTIBOOT2_TAG_TYPE_MMAP: + handle_multiboot_mmap((struct multiboot2_tag_mmap *) tag); + break; + + case MULTIBOOT2_TAG_TYPE_FRAMEBUFFER: { + struct multiboot2_tag_framebuffer *fb = + (struct multiboot2_tag_framebuffer *) tag; + + switch (fb->common.framebuffer_type) { + case MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED: + case MULTIBOOT2_FRAMEBUFFER_TYPE_RGB: + init_framebuffer(fb); + break; + case MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT: + default: + printk("[multiboot2] Unsupported framebuffer type: %u\n", + fb->common.framebuffer_type); + break; + } + } break; - if (has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - multiboot_mmap = (multiboot_memory_map_t *) _ptr(mbi->mmap_addr); - multiboot_mmap_num = mbi->mmap_length / sizeof(*multiboot_mmap); - } + case MULTIBOOT2_TAG_TYPE_EFI32: { + struct multiboot2_tag_efi32 *efi32 = (struct multiboot2_tag_efi32 *) tag; - if (has_mbi_flag(MULTIBOOT_INFO_CMDLINE) && cmdline) - *cmdline = (const char *) _ptr(mbi->cmdline); -} + printk("[multiboot2] EFI32 Pointer: 0x%p\n", efi32->pointer); + } break; -void map_multiboot_areas(void) { - paddr_t mbi = _paddr(multiboot_info); + case MULTIBOOT2_TAG_TYPE_EFI64: { + struct multiboot2_tag_efi64 *efi64 = (struct multiboot2_tag_efi64 *) tag; + + printk("[multiboot2] EFI64 Pointer: 0x%p\n", efi64->pointer); + } break; + + case MULTIBOOT2_TAG_TYPE_ACPI_OLD: { + struct multiboot2_tag_old_acpi *acpi = (struct multiboot2_tag_old_acpi *) tag; + + acpi_rsdp = _paddr(&acpi->rsdp); - vmap_4k(paddr_to_virt(mbi), paddr_to_mfn(mbi), L1_PROT_RO); - kmap_4k(paddr_to_mfn(mbi), L1_PROT_RO); + printk("[multiboot2] ACPI RSDPv1: 0x%016lx\n", acpi_rsdp); + } break; - if (has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - paddr_t mmap_start = _paddr(multiboot_info->mmap_addr); - paddr_t mmap_stop = mmap_start + _paddr(multiboot_info->mmap_length); + case MULTIBOOT2_TAG_TYPE_ACPI_NEW: { + struct multiboot2_tag_new_acpi *acpi = (struct multiboot2_tag_new_acpi *) tag; - for (mfn_t mmap_mfn = paddr_to_mfn(mmap_start); - mmap_mfn < paddr_to_mfn(mmap_stop); mmap_mfn++) { - vmap_4k(mfn_to_virt(mmap_mfn), mmap_mfn, L1_PROT_RO); - kmap_4k(mmap_mfn, L1_PROT_RO); + acpi_rsdp = _paddr(&acpi->rsdp); + + printk("[multiboot2] ACPI RSDPv2: 0x%016lx\n", acpi_rsdp); + } break; + + case MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR: { + struct multiboot2_tag_load_base_addr *addr = + (struct multiboot2_tag_load_base_addr *) tag; + + printk("[multiboot2] Load base address: 0x%p\n", addr->load_base_addr); + } break; + + default: + printk("Tag 0x%02x, Size 0x%04x\n", tag->type, tag->size); + break; } } +} - if (has_mbi_flag(MULTIBOOT_INFO_CMDLINE)) { - paddr_t cmdline_start = _paddr(multiboot_info->cmdline); - paddr_t cmdline_stop = cmdline_start + strlen((const char *) _ptr(cmdline_start)); +void map_multiboot_areas(void) { + paddr_t mbi_start = _paddr(multiboot2_hdr); + paddr_t mbi_stop = mbi_start + multiboot2_hdr_size; - for (mfn_t cmdline_mfn = paddr_to_mfn(cmdline_start); - cmdline_mfn < paddr_to_mfn(cmdline_stop); cmdline_mfn++) - kmap_4k(cmdline_mfn, L1_PROT_RO); + for (mfn_t mfn = paddr_to_mfn(mbi_start); mfn <= paddr_to_mfn(mbi_stop); mfn++) { + vmap_4k(mfn_to_virt(mfn), mfn, L1_PROT_RO); + kmap_4k(mfn, L1_PROT_RO); } } unsigned mbi_get_avail_memory_ranges_num(void) { unsigned num = 0; - if (has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - for (unsigned int i = 0; i < multiboot_mmap_num; i++) { - multiboot_memory_map_t *entry = &multiboot_mmap[i]; + for (unsigned i = 0; i < multiboot_mmap_num; i++) { + multiboot2_memory_map_t *entry = &multiboot_mmap[i]; - if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) - num++; - } + if (entry->type == MULTIBOOT2_MEMORY_AVAILABLE) + num++; + } + + if (multiboot_mmap_num == 0) { + if (multiboot_mem_lower > 0) + num++; + if (multiboot_mem_upper > 0) + num++; } - else if (has_mbi_flag(MULTIBOOT_INFO_MEMORY)) - num = 2; return num; } @@ -126,29 +213,32 @@ unsigned mbi_get_avail_memory_ranges_num(void) { int mbi_get_avail_memory_range(unsigned index, addr_range_t *r) { unsigned avail = 0; - if (has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - for (unsigned int i = 0; i < multiboot_mmap_num; i++) { - multiboot_memory_map_t *entry = &multiboot_mmap[i]; + for (unsigned int i = 0; i < multiboot_mmap_num; i++) { + multiboot2_memory_map_t *entry = &multiboot_mmap[i]; - if (entry->type != MULTIBOOT_MEMORY_AVAILABLE) - continue; + if (entry->type != MULTIBOOT2_MEMORY_AVAILABLE) + continue; - if (avail++ == index) { - r->start = _ptr(_paddr(entry->addr)); - r->end = _ptr(_paddr(r->start + entry->len)); - return 0; - } + if (avail++ == index) { + r->start = _ptr(_paddr(entry->addr)); + r->end = _ptr(_paddr(r->start + entry->len)); + return 0; } } - else if (has_mbi_flag(MULTIBOOT_INFO_MEMORY)) { + + if (multiboot_mmap_num == 0) { if (index == 0) { + BUG_ON(multiboot_mem_lower == 0); + r->start = 0x0; - r->end = _ptr(multiboot_info->mem_lower * KB(1)); + r->end = _ptr(multiboot_mem_lower); return 0; } else if (index == 1) { + BUG_ON(multiboot_mem_upper == 0); + r->start = _ptr(MB(1)); - r->end = r->start + (multiboot_info->mem_upper * KB(1)); + r->end = r->start + (multiboot_mem_upper); return 0; } } @@ -159,26 +249,29 @@ int mbi_get_avail_memory_range(unsigned index, addr_range_t *r) { int mbi_get_memory_range(paddr_t pa, addr_range_t *r) { paddr_t _start, _end; - if (has_mbi_flag(MULTIBOOT_INFO_MEM_MAP)) { - for (unsigned int i = 0; i < multiboot_mmap_num; i++) { - multiboot_memory_map_t *entry = &multiboot_mmap[i]; + for (unsigned int i = 0; i < multiboot_mmap_num; i++) { + multiboot2_memory_map_t *entry = &multiboot_mmap[i]; - _start = _paddr(entry->addr); - _end = _paddr(_start + entry->len); + _start = _paddr(entry->addr); + _end = _paddr(_start + entry->len); - if (pa >= _start && pa < _end) - goto found; - } + if (pa >= _start && pa < _end) + goto found; } - else if (has_mbi_flag(MULTIBOOT_INFO_MEMORY)) { + + if (multiboot_mmap_num == 0) { + BUG_ON(multiboot_mem_lower == 0); + _start = 0x0; - _end = multiboot_info->mem_lower * KB(1); + _end = multiboot_mem_lower; if (pa < _end) goto found; + BUG_ON(multiboot_mem_upper == 0); + _start = MB(1); - _end = _start + multiboot_info->mem_upper * KB(1); + _end = _start + multiboot_mem_upper; if (pa >= _start && pa < _end) goto found; @@ -194,19 +287,3 @@ int mbi_get_memory_range(paddr_t pa, addr_range_t *r) { return 0; } - -bool mbi_has_framebuffer(void) { - if (!has_mbi_flag(MULTIBOOT_INFO_FRAMEBUFFER_INFO)) - return false; - - switch (multiboot_info->framebuffer_type) { - case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: - case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: - return true; - case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: - default: - return false; - } - - return false; -} diff --git a/common/acpi.c b/common/acpi.c index 5f426366..958da5a6 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -28,6 +28,8 @@ #include #include +paddr_t acpi_rsdp = 0; + static const char *madt_int_bus_names[] = { [ACPI_MADT_INT_BUS_ISA] = "ISA", }; @@ -115,6 +117,9 @@ static rsdp_rev1_t *acpi_find_rsdp(void) { uint32_t ebda_addr; rsdp_rev1_t *rsdp; + if (acpi_rsdp) + return (rsdp_rev1_t *) acpi_rsdp; + ebda_addr = get_bios_ebda_addr(); rsdp = find_rsdp(paddr_to_virt_kern(ebda_addr), paddr_to_virt_kern(ebda_addr + KB(1))); diff --git a/common/kernel.c b/common/kernel.c index 500096b1..1542a990 100644 --- a/common/kernel.c +++ b/common/kernel.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/common/setup.c b/common/setup.c index 58039c45..ae5d7af2 100644 --- a/common/setup.c +++ b/common/setup.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -148,15 +148,14 @@ static void __text_init init_vga_console(void) { register_console_callback(vga_console_write, paddr_to_virt_kern(VGA_START_ADDR)); } -void __noreturn __text_init kernel_start(uint32_t multiboot_magic, - multiboot_info_t *mbi) { +void __noreturn __text_init kernel_start(uint32_t multiboot_magic, unsigned long *mbi) { /* Zero-out BSS sections */ zero_bss(); /* Initialize console early */ init_console(); - if (multiboot_magic == MULTIBOOT_BOOTLOADER_MAGIC) { + if (multiboot_magic == MULTIBOOT2_BOOTLOADER_MAGIC) { /* Indentity mapping is still on, so fill in multiboot structures */ init_multiboot(mbi, &kernel_cmdline); } @@ -196,7 +195,7 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic, if (opt_debug) dump_pagetables(); - if (init_framebuffer(mbi)) + if (setup_framebuffer()) display_banner(); else init_vga_console(); diff --git a/drivers/acpi/acpica/osl.c b/drivers/acpi/acpica/osl.c index a823135e..73dae607 100644 --- a/drivers/acpi/acpica/osl.c +++ b/drivers/acpi/acpica/osl.c @@ -23,6 +23,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef KTF_ACPICA +#include #include #include #include @@ -186,7 +187,11 @@ ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width) ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void) { ACPI_PHYSICAL_ADDRESS pa = 0; - AcpiFindRootPointer(&pa); + if (acpi_rsdp) + pa = (ACPI_PHYSICAL_ADDRESS) acpi_rsdp; + else + AcpiFindRootPointer(&pa); + return pa; } diff --git a/drivers/fb/fb.c b/drivers/fb/fb.c index 0f743a7a..03623e04 100644 --- a/drivers/fb/fb.c +++ b/drivers/fb/fb.c @@ -26,12 +26,14 @@ #include #include #include -#include +#include #include #include extern uint64_t fonts[]; +static bool has_fb = false; + static uint32_t width; static uint32_t height; static uint32_t pitch; @@ -69,18 +71,15 @@ static void put_pixel32(uint32_t x, uint32_t y, uint32_t color) { *(uint32_t *) (video_memory + (y * pitch) + (x * 4)) = color; } -bool init_framebuffer(const multiboot_info_t *mbi) { - if (!mbi_has_framebuffer()) - return false; - - video_memory = (void *) mbi->framebuffer_addr; +void init_framebuffer(const struct multiboot2_tag_framebuffer *fb) { + video_memory = (void *) fb->common.framebuffer_addr; if (!video_memory) - return false; + return; - width = mbi->framebuffer_width; - height = mbi->framebuffer_height; - pitch = mbi->framebuffer_pitch; - bpp = mbi->framebuffer_bpp; + width = fb->common.framebuffer_width; + height = fb->common.framebuffer_height; + pitch = fb->common.framebuffer_pitch; + bpp = fb->common.framebuffer_bpp; buffer_size = (size_t) width * height; banner_size = (size_t) width * LOGO_HEIGHT; @@ -88,7 +87,8 @@ bool init_framebuffer(const multiboot_info_t *mbi) { switch (bpp) { case 0 ... 7: printk("FB: Unsupported framebuffer BPP: %u\n", bpp); - return false; + has_fb = false; + return; case 8: put_pixel = put_pixel8; break; @@ -112,7 +112,14 @@ bool init_framebuffer(const multiboot_info_t *mbi) { BUG(); } - map_fb_area(mbi->framebuffer_addr, buffer_size); + has_fb = true; +} + +bool setup_framebuffer(void) { + if (!has_fb) + return false; + + map_fb_area(_paddr(video_memory), buffer_size); memset(video_memory, 0, buffer_size); register_console_callback(fb_console_write, video_memory); diff --git a/grub/boot/grub/grub.cfg b/grub/boot/grub/grub.cfg index 5430eb5b..e99ae016 100644 --- a/grub/boot/grub/grub.cfg +++ b/grub/boot/grub/grub.cfg @@ -2,6 +2,7 @@ set timeout=0 set default=0 insmod serial +insmod multiboot2 insmod all_video serial --speed=115200 --word=8 --parity=no --stop=1 @@ -9,6 +10,6 @@ terminal_input --append serial terminal_output --append serial menuentry "kernel64" { - multiboot /boot/kernel64.bin.xz poweroff=1 com1=0x3f8,115200,8,n,1 + multiboot2 /boot/kernel64.bin.xz poweroff=1 com1=0x3f8,115200,8,n,1 boot } diff --git a/include/acpi_ktf.h b/include/acpi_ktf.h index 72a6ada4..6fd14869 100644 --- a/include/acpi_ktf.h +++ b/include/acpi_ktf.h @@ -47,6 +47,8 @@ extern unsigned acpi_get_nr_cpus(void); +extern paddr_t acpi_rsdp; + #ifndef KTF_ACPICA #define RSDP_SIGNATURE (('R') | ('S' << 8) | ('D' << 16) | ('P' << 24)) #define RSDT_SIGNATURE (('R') | ('S' << 8) | ('D' << 16) | ('T' << 24)) diff --git a/include/drivers/fb.h b/include/drivers/fb.h index e0920f8c..9803c654 100644 --- a/include/drivers/fb.h +++ b/include/drivers/fb.h @@ -26,14 +26,15 @@ #define KTF_DRV_FB_H #include -#include +#include #define FB_WHITE 0xFFFFFFFF -extern bool init_framebuffer(const multiboot_info_t *mbi); +extern void init_framebuffer(const struct multiboot2_tag_framebuffer *fb); extern void put_char(char c, uint32_t x, uint32_t y, uint32_t color); extern void draw_line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t color); extern void draw_logo(void); extern void fb_write(void *fb_addr, const char *buf, size_t len, uint32_t color); +extern bool setup_framebuffer(void); #endif /* KTF_DRV_FB_H */ diff --git a/include/multiboot2.h b/include/multiboot2.h new file mode 100644 index 00000000..fef0ff87 --- /dev/null +++ b/include/multiboot2.h @@ -0,0 +1,439 @@ +#ifndef KTF_MULTIBOOT2_H +#define KTF_MULTIBOOT2_H + +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT2_HEADER +#define MULTIBOOT2_HEADER 1 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax on x86 architecture. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT2_SEARCH 32768 + +/* Multiboot 2 header alignment. */ +#define MULTIBOOT2_HEADER_ALIGN 8 + +/* Alignment of multiboot 2 modules. */ +#define MULTIBOOT2_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot 2 info structure. */ +#define MULTIBOOT2_INFO_ALIGN 0x00000008 + +/* Multiboot 2 architectures. */ +#define MULTIBOOT2_ARCHITECTURE_I386 0 +#define MULTIBOOT2_ARCHITECTURE_MIPS32 4 + +/* Header tag types. */ +#define MULTIBOOT2_HEADER_TAG_END 0 +#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT2_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT2_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT2_HEADER_TAG_RELOCATABLE 10 + +/* Header tag flags. */ +#define MULTIBOOT2_HEADER_TAG_REQUIRED 0 +#define MULTIBOOT2_HEADER_TAG_OPTIONAL 1 + +/* Where image should be loaded (suggestion not requirement). */ +#define MULTIBOOT2_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT2_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT2_LOAD_PREFERENCE_HIGH 2 + +/* Header console tag console_flags. */ +#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +/* Flags set in the 'flags' member of the multiboot header. */ +#define MULTIBOOT2_TAG_TYPE_END 0 +#define MULTIBOOT2_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT2_TAG_TYPE_MODULE 3 +#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT2_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT2_TAG_TYPE_MMAP 6 +#define MULTIBOOT2_TAG_TYPE_VBE 7 +#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT2_TAG_TYPE_APM 10 +#define MULTIBOOT2_TAG_TYPE_EFI32 11 +#define MULTIBOOT2_TAG_TYPE_EFI64 12 +#define MULTIBOOT2_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT2_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT2_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT2_TAG_TYPE_NETWORK 16 +#define MULTIBOOT2_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT2_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT2_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT2_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR 21 + +/* Multiboot 2 tag alignment. */ +#define MULTIBOOT2_TAG_ALIGN 8 + +/* Memory types. */ +#define MULTIBOOT2_MEMORY_AVAILABLE 1 +#define MULTIBOOT2_MEMORY_RESERVED 2 +#define MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT2_MEMORY_NVS 4 +#define MULTIBOOT2_MEMORY_BADRAM 5 + +/* Framebuffer types. */ +#define MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot2_uint8_t; +typedef unsigned short multiboot2_uint16_t; +typedef unsigned int multiboot2_uint32_t; +typedef unsigned long long multiboot2_uint64_t; + +struct multiboot2_header { + /* Must be MULTIBOOT2_MAGIC - see above. */ + multiboot2_uint32_t magic; + + /* ISA */ + multiboot2_uint32_t architecture; + + /* Total header length. */ + multiboot2_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot2_uint32_t checksum; +}; + +struct multiboot2_header_tag { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; +}; + +struct multiboot2_header_tag_information_request { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t requests[0]; +}; + +struct multiboot2_header_tag_address { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t header_addr; + multiboot2_uint32_t load_addr; + multiboot2_uint32_t load_end_addr; + multiboot2_uint32_t bss_end_addr; +}; + +struct multiboot2_header_tag_entry_address { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t entry_addr; +}; + +struct multiboot2_header_tag_console_flags { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t console_flags; +}; + +struct multiboot2_header_tag_framebuffer { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t width; + multiboot2_uint32_t height; + multiboot2_uint32_t depth; +}; + +struct multiboot2_header_tag_module_align { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; +}; + +struct multiboot2_header_tag_relocatable { + multiboot2_uint16_t type; + multiboot2_uint16_t flags; + multiboot2_uint32_t size; + multiboot2_uint32_t min_addr; + multiboot2_uint32_t max_addr; + multiboot2_uint32_t align; + multiboot2_uint32_t preference; +}; + +struct multiboot2_color { + multiboot2_uint8_t red; + multiboot2_uint8_t green; + multiboot2_uint8_t blue; +}; + +struct multiboot2_mmap_entry { + multiboot2_uint64_t addr; + multiboot2_uint64_t len; + multiboot2_uint32_t type; + multiboot2_uint32_t zero; +}; +typedef struct multiboot2_mmap_entry multiboot2_memory_map_t; + +struct multiboot2_tag { + multiboot2_uint32_t type; + multiboot2_uint32_t size; +}; + +struct multiboot2_tag_string { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + char string[0]; +}; + +struct multiboot2_tag_module { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t mod_start; + multiboot2_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot2_tag_basic_meminfo { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t mem_lower; + multiboot2_uint32_t mem_upper; +}; + +struct multiboot2_tag_bootdev { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t biosdev; + multiboot2_uint32_t slice; + multiboot2_uint32_t part; +}; + +struct multiboot2_tag_mmap { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t entry_size; + multiboot2_uint32_t entry_version; + struct multiboot2_mmap_entry entries[0]; +}; + +struct multiboot2_vbe_info_block { + multiboot2_uint8_t external_specification[512]; +}; + +struct multiboot2_vbe_mode_info_block { + multiboot2_uint8_t external_specification[256]; +}; + +struct multiboot2_tag_vbe { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + + multiboot2_uint16_t vbe_mode; + multiboot2_uint16_t vbe_interface_seg; + multiboot2_uint16_t vbe_interface_off; + multiboot2_uint16_t vbe_interface_len; + + struct multiboot2_vbe_info_block vbe_control_info; + struct multiboot2_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot2_tag_framebuffer_common { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + + multiboot2_uint64_t framebuffer_addr; + multiboot2_uint32_t framebuffer_pitch; + multiboot2_uint32_t framebuffer_width; + multiboot2_uint32_t framebuffer_height; + multiboot2_uint8_t framebuffer_bpp; + multiboot2_uint8_t framebuffer_type; + multiboot2_uint16_t reserved; +}; + +struct multiboot2_tag_framebuffer { + struct multiboot2_tag_framebuffer_common common; + + union { + struct { + multiboot2_uint16_t framebuffer_palette_num_colors; + struct multiboot2_color framebuffer_palette[0]; + }; + struct { + multiboot2_uint8_t framebuffer_red_field_position; + multiboot2_uint8_t framebuffer_red_mask_size; + multiboot2_uint8_t framebuffer_green_field_position; + multiboot2_uint8_t framebuffer_green_mask_size; + multiboot2_uint8_t framebuffer_blue_field_position; + multiboot2_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot2_tag_elf_sections { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t num; + multiboot2_uint32_t entsize; + multiboot2_uint32_t shndx; + char sections[0]; +}; + +struct multiboot2_tag_apm { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint16_t version; + multiboot2_uint16_t cseg; + multiboot2_uint32_t offset; + multiboot2_uint16_t cseg_16; + multiboot2_uint16_t dseg; + multiboot2_uint16_t flags; + multiboot2_uint16_t cseg_len; + multiboot2_uint16_t cseg_16_len; + multiboot2_uint16_t dseg_len; +}; + +struct multiboot2_tag_efi32 { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t pointer; +}; + +struct multiboot2_tag_efi64 { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint64_t pointer; +}; + +struct multiboot2_tag_smbios { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint8_t major; + multiboot2_uint8_t minor; + multiboot2_uint8_t reserved[6]; + multiboot2_uint8_t tables[0]; +}; + +struct multiboot2_tag_old_acpi { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint8_t rsdp[0]; +}; + +struct multiboot2_tag_new_acpi { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint8_t rsdp[0]; +}; + +struct multiboot2_tag_network { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint8_t dhcpack[0]; +}; + +struct multiboot2_tag_efi_mmap { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t descr_size; + multiboot2_uint32_t descr_vers; + multiboot2_uint8_t efi_mmap[0]; +}; + +struct multiboot2_tag_efi32_ih { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t pointer; +}; + +struct multiboot2_tag_efi64_ih { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint64_t pointer; +}; + +struct multiboot2_tag_load_base_addr { + multiboot2_uint32_t type; + multiboot2_uint32_t size; + multiboot2_uint32_t load_base_addr; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT2_HEADER */ + +/* + * Copyright © 2022 Open Source Security, Inc. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ASSEMBLY__ + +typedef struct multiboot2_tag multiboot2_tag_t; + +extern void display_multiboot_mmap(void); +extern void init_multiboot(unsigned long *addr, const char **cmdline); + +#include +extern void map_multiboot_areas(void); +extern unsigned mbi_get_avail_memory_ranges_num(void); +extern int mbi_get_avail_memory_range(unsigned index, addr_range_t *r); +extern int mbi_get_memory_range(paddr_t pa, addr_range_t *r); + +#endif /* __ASSEMBLY__ */ + +#endif /* KTF_MULTIBOOT2_H */