diff options
author | Danny Holman <dholman@gymli.org> | 2023-11-26 18:47:59 -0600 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2023-11-26 18:47:59 -0600 |
commit | 40cbd20b997c2cbcacb2095e7487609bca1c0040 (patch) | |
tree | 9f3adfbdf4c277e8cec29d19aa69a73eff36cc2b /arch | |
parent | 0c34fb36ab9f3df876412382ef62056409e9f98d (diff) |
arch: i386: add multiboot support
Add support for the multiboot specification. These files will allow the
kernel to read the multiboot header information as well as the provided
memory map.
Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/include/kernel/multiboot.h | 104 | ||||
-rw-r--r-- | arch/i386/kernel/multiboot.c | 23 |
2 files changed, 127 insertions, 0 deletions
diff --git a/arch/i386/include/kernel/multiboot.h b/arch/i386/include/kernel/multiboot.h new file mode 100644 index 0000000..5825816 --- /dev/null +++ b/arch/i386/include/kernel/multiboot.h @@ -0,0 +1,104 @@ +#ifndef I386_MULTIBOOT_H +#define I386_MULTIBOOT_H + +#include <stdint.h> + +#define MBOOT_HEADER_MAGIC 0x1BADB002 +#define MBOOT_LOADER_MAGIC 0x2BADB002 + +// Multiboot flags +#define MBOOT_INFO_MMAP 0x00000001 +#define MBOOT_INFO_BOOTDEV 0x00000002 +#define MBOOT_INFO_CMDLINE 0x00000004 +#define MBOOT_INFO_MODS 0x00000008 +#define MBOOT_INFO_AOUT_SYMS 0x00000010 +#define MBOOT_INFO_ELF_HEADER 0x00000020 +#define MBOOT_INFO_MEM_MAP 0x00000040 +#define MBOOT_INFO_DRIVE_INFO 0x00000080 +#define MBOOT_INFO_CONFIG_TBL 0x00000100 +#define MBOOT_INFO_BL_NAME 0x00000200 +#define MBOOT_INFO_APM_TBL 0x00000400 +#define MBOOT_INFO_VBE 0x00000800 +#define MBOOT_INFO_FRAMEBUFFER 0x00001000 + +// Memory types +#define MBOOT_MEM_AVAILABLE 1 +#define MBOOT_MEM_RESERVED 2 +#define MBOOT_MEM_ACPI_REC 3 +#define MBOOT_MEM_NVS 4 +#define MBOOT_MEM_BADRAM 5 + +struct aout_symbol_table { + uint32_t tabsize; + uint32_t strsize; + uint32_t addr; + uint32_t reserved; +}; + +struct elf_section_header { + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; +}; + +struct mboot_header { + uint32_t magic; + uint32_t flags; + uint32_t checksum; + uint32_t header_addr; + uint32_t load_addr; + uint32_t load_end_addr; + uint32_t bss_end_addr; + uint32_t entry_addr; + uint32_t mode_type; + uint32_t width; + uint32_t height; + uint32_t depth; +}; + +struct mboot_info { + uint32_t flags; + uint32_t mem_lower; + uint32_t mem_upper; + uint32_t boot_device; + uint32_t cmdline; + uint32_t mods_count; + uint32_t mods_addr; + union { + struct aout_symbol_table aout_sym; + struct elf_section_header elf_sec; + } u; + uint32_t mmap_length; + uint32_t mmap_addr; + uint32_t drives_length; + uint32_t drives_addr; + uint32_t config_table; + uint32_t boot_loader_name; + uint32_t apm_table; + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; +}; + +struct mboot_mmap_entry { + uint32_t size; + uint32_t addr_low; + uint32_t addr_high; + uint32_t len_low; + uint32_t len_high; + uint32_t type; +} __attribute__((packed)); + +void i386_entry(uint32_t mboot_magic, struct mboot_info *header); + +#endif diff --git a/arch/i386/kernel/multiboot.c b/arch/i386/kernel/multiboot.c new file mode 100644 index 0000000..d7f0a65 --- /dev/null +++ b/arch/i386/kernel/multiboot.c @@ -0,0 +1,23 @@ +#include <kernel/multiboot.h> +#include <kernel/tty.h> +#include <kernel/panic.h> +#include <kernel/io.h> + +void i386_entry(uint32_t mboot_magic, struct mboot_info *header) { + paging_init(); + tty_init(); + + struct mboot_info *vheader = get_vaddr(header); + mark_bitmap(header, 1); + map_page(header, vheader, 0x003); + + if (mboot_magic != MBOOT_LOADER_MAGIC) + panic("NOT BOOTED WITH MULTIBOOT BOOTLOADER"); + if (!(vheader->flags >> 6 & 0x1)) + panic("NO MEMORY MAP FROM BOOTLOADER"); + + gdt_install(); + idt_install(); + alloc_init(vheader); + kernel_main(vheader->cmdline); +} |