diff --git a/Architecture/i386/Bootstrap/Multiboot/1/Header.s b/Architecture/i386/Bootstrap/Multiboot/1/Header.s new file mode 100644 index 0000000..81fce85 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/1/Header.s @@ -0,0 +1,27 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.section .multiboot +.align 4 + +MULTIBOOT_HEADER: + .long 0x1BADB002 + .long 1 << 0 | 1 << 1 + .long -(0x1BADB002 + (1 << 0 | 1 << 1)) diff --git a/Architecture/i386/Bootstrap/Multiboot/1/Start.asm b/Architecture/i386/Bootstrap/Multiboot/1/Start.asm new file mode 100644 index 0000000..49bc2c2 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/1/Start.asm @@ -0,0 +1,22 @@ +; This file is part of Fennix Kernel. +; +; Fennix Kernel is free software: you can redistribute it and/or +; modify it under the terms of the GNU General Public License as +; published by the Free Software Foundation, either version 3 of +; the License, or (at your option) any later version. +; +; Fennix Kernel is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with Fennix Kernel. If not, see . + +[bits 32] + +section .bootstrap.text + +global Multiboot1_start +Multiboot1_start: + int3 diff --git a/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h b/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h new file mode 100644 index 0000000..42dd7d3 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h @@ -0,0 +1,274 @@ +/* multiboot.h - Multiboot 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 MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info +{ + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Detect.s b/Architecture/i386/Bootstrap/Multiboot/2/Detect.s new file mode 100644 index 0000000..319d180 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Detect.s @@ -0,0 +1,81 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.section .bootstrap.text + +.global DetectCPUID +DetectCPUID: + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + xor eax, ecx + jz .NoCPUID + mov eax, 1 + ret +.NoCPUID: + xor eax, eax + ret + +.global Detect64Bit +Detect64Bit: + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000001 + jb .NoLongMode + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 + jz .NoLongMode + mov eax, 1 + ret +.NoLongMode: + xor eax, eax + ret + +.global DetectPSE +DetectPSE: + mov eax, 0x00000001 + cpuid + test edx, 0x00000008 + jz .NoPSE + mov eax, 1 + ret +.NoPSE: + xor eax, eax + ret + +.global DetectPAE +DetectPAE: + mov eax, 0x00000001 + cpuid + test edx, 0x00000040 + jz .NoPAE + mov eax, 1 + ret +.NoPAE: + xor eax, eax + ret diff --git a/Architecture/i386/Bootstrap/Multiboot/2/GDT32.s b/Architecture/i386/Bootstrap/Multiboot/2/GDT32.s new file mode 100644 index 0000000..30974ac --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/GDT32.s @@ -0,0 +1,66 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.section .bootstrap.text + +.align 32 +.global gdtr +gdtr: + .word GDT32_END - GDT32 - 1 + .long GDT32 + +.align 32 +GDT32: + .quad 0x0 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF9A + .byte 0x00 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF92 + .byte 0x00 + + .word 0x0100 + .word 0x1000 + .byte 0x00 + .word 0x4092 + .byte 0x00 +GDT32_END: + +.global LoadGDT32 +LoadGDT32: + lgdt [gdtr] + + jmp 0x8:ActivateGDT + ActivateGDT: + mov cx, 0x10 + mov ss, cx + mov ds, cx + mov es, cx + mov fs, cx + mov cx, 0x18 + mov gs, cx + + ret diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Header.s b/Architecture/i386/Bootstrap/Multiboot/2/Header.s new file mode 100644 index 0000000..4c55a22 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Header.s @@ -0,0 +1,93 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.extern Multiboot2_start + +/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */ +.section .multiboot2 +.align 0x1000 +MULTIBOOT2_HEADER_START: + .long 0xE85250D6 + .long 0 + .long (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) + .long 0x100000000 - (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) - 0 - 0xE85250D6 +.align 8 +InfoRequestTag_Start: + .word 1 + .word 0 + .long InfoRequestTag_End - InfoRequestTag_Start + .long 1 /* Command Line */ + .long 2 /* Boot Loader Name */ + .long 3 /* Module */ + .long 4 /* Basic Memory Information */ + .long 5 /* BIOS Boot Device */ + .long 6 /* Memory Map */ + .long 7 /* VBE */ + .long 8 /* Framebuffer */ + .long 9 /* ELF Sections */ + .long 10 /* APM Table */ + .long 11 /* EFI 32-bit System Table Pointer */ + .long 12 /* EFI 64-bit System Table Pointer */ + /* .long 13 */ /* SMBIOS */ + .long 14 /* ACPI Old */ + .long 15 /* ACPI New */ + .long 16 /* Network */ + .long 17 /* EFI Memory Map */ + .long 18 /* EFI Boot Services Notifier */ + .long 19 /* EFI 32-bit Image Handle Pointer */ + .long 20 /* EFI 64-bit Image Handle Pointer */ + .long 21 /* Load Base Address */ +InfoRequestTag_End: +/*.align 8 +FramebufferTag_Start: + .word 5 + .word 1 + .long FramebufferTag_End - FramebufferTag_Start + .long 0 + .long 0 + .long 32 +FramebufferTag_End:*/ +.align 8 +EGATextSupportTag_Start: + .word 4 + .word 0 + .long EGATextSupportTag_End - EGATextSupportTag_Start + .long 1 /* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Console-header-tags.html */ +EGATextSupportTag_End: +.align 8 +AlignedModulesTag_Start: + .word 6 + .word 0 + .long AlignedModulesTag_End - AlignedModulesTag_Start +AlignedModulesTag_End: +.align 8 +EntryAddressTag_Start: + .word 3 + .word 0 + .long EntryAddressTag_End - EntryAddressTag_Start + .long Multiboot2_start +EntryAddressTag_End: +.align 8 +EndTag_Start: + .word 0 + .word 0 + .long EndTag_End - EndTag_Start +EndTag_End: +MULTIBOOT2_HEADER_END: diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp new file mode 100644 index 0000000..2f82a1c --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp @@ -0,0 +1,313 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include + +#include +#include + +#include "multiboot2.h" +#include "../../../../../kernel.h" + +EXTERNC void multiboot_main(uint32_t Magic, uint32_t Info) +{ + if (Info == NULL || Magic == NULL) + { + if (Magic == NULL) + error("Multiboot magic is NULL"); + if (Info == NULL) + error("Multiboot info is NULL"); + CPU::Stop(); + } + else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) + { + error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC); + CPU::Stop(); + } + + BootInfo mb2binfo{}; + + { + uint64_t div = 1193180 / 1000; + outb(0x43, 0xB6); + outb(0x42, (uint8_t)div); + outb(0x42, (uint8_t)(div >> 8)); + uint8_t tmp = inb(0x61); + if (tmp != (tmp | 3)) + outb(0x61, tmp | 3); + + int pos = 0; + auto InfoAddress = Info; + for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8); + ; + Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7))) + { + if (Tag->type == MULTIBOOT_TAG_TYPE_END) + { + debug("End of multiboot2 tags"); + break; + } + + switch (Tag->type) + { + case MULTIBOOT_TAG_TYPE_CMDLINE: + { + strncpy(mb2binfo.Kernel.CommandLine, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); + debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine); + break; + } + case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: + { + strncpy(mb2binfo.Bootloader.Name, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); + debug("Bootloader name: %s", mb2binfo.Bootloader.Name); + break; + } + case MULTIBOOT_TAG_TYPE_MODULE: + { + multiboot_tag_module *module = (multiboot_tag_module *)Tag; + static int module_count = 0; + mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start; + mb2binfo.Modules[module_count].Size = module->size; + strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6); + strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, + strlen(module->cmdline)); + debug("Module: %s", mb2binfo.Modules[module_count].Path); + module_count++; + break; + } + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + { + multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag; + fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]", + meminfo->mem_lower, meminfo->mem_upper); + break; + } + case MULTIBOOT_TAG_TYPE_BOOTDEV: + { + multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag; + fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]", + bootdev->biosdev, bootdev->slice, bootdev->part); + break; + } + case MULTIBOOT_TAG_TYPE_MMAP: + { + multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag; + size_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry); + mb2binfo.Memory.Entries = EntryCount; + for (uint32_t i = 0; i < EntryCount; i++) + { + if (EntryCount > MAX_MEMORY_ENTRIES) + { + warn("Too many memory entries, skipping the rest..."); + break; + } + multiboot_mmap_entry entry = mmap->entries[i]; + mb2binfo.Memory.Size += entry.len; + switch (entry.type) + { + case MULTIBOOT_MEMORY_AVAILABLE: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = Usable; + break; + case MULTIBOOT_MEMORY_RESERVED: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = Reserved; + break; + case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = ACPIReclaimable; + break; + case MULTIBOOT_MEMORY_NVS: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = ACPINVS; + break; + case MULTIBOOT_MEMORY_BADRAM: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = BadMemory; + break; + default: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = entry.len; + mb2binfo.Memory.Entry[i].Type = Unknown; + break; + } + debug("Memory entry: [BaseAddress: %#x, Length: %#x, Type: %d]", + mb2binfo.Memory.Entry[i].BaseAddress, + mb2binfo.Memory.Entry[i].Length, + mb2binfo.Memory.Entry[i].Type); + } + break; + } + case MULTIBOOT_TAG_TYPE_VBE: + { + multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag; + fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]", + vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len); + break; + } + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag; + static int fb_count = 0; + mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr; + mb2binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width; + mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; + mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; + mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; + switch (fb->common.framebuffer_type) + { + case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: + { + mb2binfo.Framebuffer[fb_count].Type = Indexed; + break; + } + case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: + { + mb2binfo.Framebuffer[fb_count].Type = RGB; + mb2binfo.Framebuffer[fb_count].RedMaskSize = fb->framebuffer_red_mask_size; + mb2binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position; + mb2binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size; + mb2binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position; + mb2binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size; + mb2binfo.Framebuffer[fb_count].BlueMaskShift = fb->framebuffer_blue_field_position; + break; + } + case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: + { + mb2binfo.Framebuffer[fb_count].Type = EGA; + break; + } + default: + { + mb2binfo.Framebuffer[fb_count].Type = Unknown_Framebuffer_Type; + break; + } + } + debug("Framebuffer %d: %dx%d %d bpp", fb_count, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp); + debug("More info:\nAddress: %p\nPitch: %lld\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d", + fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type, + fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size, + fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position); + fb_count++; + break; + } + case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + { + multiboot_tag_elf_sections *elf = (multiboot_tag_elf_sections *)Tag; + fixme("elf_sections->[num=%d, size=%d, entsize=%d, shndx=%d]", + elf->num, elf->size, elf->entsize, elf->shndx); + break; + } + case MULTIBOOT_TAG_TYPE_APM: + { + multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag; + fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]", + apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32: + { + multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag; + fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64: + { + multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag; + fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size); + break; + } + case MULTIBOOT_TAG_TYPE_SMBIOS: + { + multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag; + fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor); + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_OLD: + { + mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp; + debug("OLD ACPI RSDP: %p", mb2binfo.RSDP); + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_NEW: + { + mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp; + debug("NEW ACPI RSDP: %p", mb2binfo.RSDP); + break; + } + case MULTIBOOT_TAG_TYPE_NETWORK: + { + multiboot_tag_network *net = (multiboot_tag_network *)Tag; + fixme("network->[dhcpack: %p]", net->dhcpack); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_MMAP: + { + multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag; + fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]", + efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_BS: + { + fixme("efi_bs->[%p] (unknown structure)", Tag); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32_IH: + { + multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag; + fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64_IH: + { + multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag; + fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: + { + multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; + mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr; + mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000); + mb2binfo.Kernel.Size = ((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start); + debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase); + break; + } + default: + { + error("Unknown multiboot2 tag type: %d", Tag->type); + break; + } + } + } + + tmp = inb(0x61) & 0xFC; + outb(0x61, tmp); + } + + Entry(&mb2binfo); +} diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.asm b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.asm new file mode 100644 index 0000000..46b0e89 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.asm @@ -0,0 +1,30 @@ +; This file is part of Fennix Kernel. +; +; Fennix Kernel is free software: you can redistribute it and/or +; modify it under the terms of the GNU General Public License as +; published by the Free Software Foundation, either version 3 of +; the License, or (at your option) any later version. +; +; Fennix Kernel is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with Fennix Kernel. If not, see . + +[bits 32] + +KERNEL_VIRTUAL_BASE equ 0xC0000000 ; 3GB or 0xC0000000 +KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; 768 + +section .bootstrap.data +align 0x1000 +global BootPageTable +BootPageTable: + dd 0x00000083 + dd 0x00000083 + times (KERNEL_PAGE_NUMBER - 2) dd 0 + dd 0x00000083 + dd 0x00000083 + times (1024 - KERNEL_PAGE_NUMBER - 2) dd 0 diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme new file mode 100644 index 0000000..6922f1b --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme @@ -0,0 +1,67 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 + +.equ PAGE_TABLE_SIZE, 0x4 + +.section .bootstrap.data +.align 0x1000 +.global BootPageTable +BootPageTable: + .rept 0x10000 /* 0x4000 bytes will be used in UpdatePageTable */ + .long 0 + .endr + +.section .bootstrap.text +.global UpdatePageTable +UpdatePageTable: + mov edi, (BootPageTable + 0x0000) /* First PML4E */ + mov eax, (BootPageTable + 0x1000) /* First PDPTE */ + or eax, 0b11 /* Bitwise OR on rax (PDPTE) with 11b (Present, Write) */ + mov dword [edi], eax /* Write 11b to PML4E */ + + mov edi, (BootPageTable + 0x1000) /* First PDPTE */ + mov eax, (BootPageTable + 0x2000) /* First PDE */ + or eax, 0b11 /* Bitwise OR on rax (PDE) with 11b (Present, Write) */ + + mov ecx, PAGE_TABLE_SIZE /* For loop instruction */ + mov ebx, 0x0 /* Value to store in the next 4 bytes */ + .FillPageTableLevel3: + mov dword [edi], eax /* Store modified PDE in PDPTE */ + mov dword [edi + 4], ebx /* Store the rbx value in the next 4 bytes */ + add eax, 0x1000 /* Increment (page size) */ + adc ebx, 0 /* Add 0 to carry flag */ + add edi, 8 /* Add 8 to rdi (next PDE) */ + loop .FillPageTableLevel3 /* Loop until rcx is 0 */ + + mov edi, (BootPageTable + 0x2000) /* First PDE */ + mov eax, 0b10000011 /* Present, Write, Large Page */ + + mov ecx, (512 * PAGE_TABLE_SIZE) /* For loop instruction */ + mov ebx, 0x0 /* Value to store in the next 4 bytes */ + .FillPageTableLevel2: + mov dword [edi], eax /* Store modified PDE in PDPTE */ + mov dword [edi + 4], ebx /* Store the rbx value in the next 4 bytes */ + add eax, 1 << 21 /* Increment (page size) */ + adc ebx, 0 /* Add 0 (carry flag) to rbx to increment if there was a carry */ + add edi, 8 /* Add 8 to rdi (next PDE) */ + loop .FillPageTableLevel2 /* Loop until rcx is 0 */ + + ret diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Start.asm b/Architecture/i386/Bootstrap/Multiboot/2/Start.asm new file mode 100644 index 0000000..ae571ac --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Start.asm @@ -0,0 +1,86 @@ +; This file is part of Fennix Kernel. +; +; Fennix Kernel is free software: you can redistribute it and/or +; modify it under the terms of the GNU General Public License as +; published by the Free Software Foundation, either version 3 of +; the License, or (at your option) any later version. +; +; Fennix Kernel is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with Fennix Kernel. If not, see . + +[bits 32] +KERNEL_STACK_SIZE equ 0x4000 ; 16KB + +extern DetectCPUID +extern Detect64Bit +extern DetectPSE +extern DetectPAE +extern multiboot_main +extern LoadGDT32 +extern BootPageTable + +section .bootstrap.data +MB_HeaderMagic: + dq 0 + +MB_HeaderInfo: + dq 0 + +section .bootstrap.text + +global Multiboot2_start +Multiboot2_start: + cli + + mov [MB_HeaderMagic], eax + mov [MB_HeaderInfo], ebx + + call DetectCPUID + cmp eax, 0 + je $ + + ; call Detect64Bit + ; cmp eax, 0 + ; je $ + + call DetectPSE + cmp eax, 0 + je $ + + ; call DetectPAE + ; cmp eax, 0 + ; je $ + + mov ecx, cr4 + or ecx, 0x00000010 ; Set PSE in CR4 + ; or ecx, 0x00000020 ; Set PAE in CR4 + mov cr4, ecx + + call LoadGDT32 + + mov ecx, BootPageTable + mov cr3, ecx + + mov ecx, cr0 + or ecx, 0x80000001 ; Set PG and PE in CR0 + mov cr0, ecx + + mov esp, KernelStack + KERNEL_STACK_SIZE + mov eax, [MB_HeaderMagic] + mov ebx, [MB_HeaderInfo] + push ebx + push eax + call multiboot_main +.Hang: + hlt + jmp .Hang + +section .bootstrap.bss +align 16 +KernelStack: + resb KERNEL_STACK_SIZE diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Start.s_fixme b/Architecture/i386/Bootstrap/Multiboot/2/Start.s_fixme new file mode 100644 index 0000000..8076319 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/Start.s_fixme @@ -0,0 +1,117 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.code32 +.equ KERNEL_STACK_SIZE, 0x4000 /* 16KB */ + +.extern DetectCPUID +.extern Detect64Bit +.extern DetectPSE +.extern DetectPAE +.extern multiboot_main +.extern LoadGDT32 +.extern BootPageTable +.extern UpdatePageTable +.extern GDT64.Ptr +.extern GDT64.Code +.extern GDT64.Data + +.section .bootstrap.data +MB_HeaderMagic: + .quad 0 + +MB_HeaderInfo: + .quad 0 + +.section .bootstrap.text + +.global Multiboot2_start +Multiboot2_start: + cli + + mov [MB_HeaderMagic], eax + mov [MB_HeaderInfo], ebx + + call DetectCPUID + cmp eax, 0 + je $ + + call Detect64Bit + cmp eax, 0 + je $ + + call DetectPSE + cmp eax, 0 + je $ + + call DetectPAE + cmp eax, 0 + je $ + + mov ecx, cr4 + or ecx, 0x00000010 /* Set PSE in CR4 */ + or ecx, 0x00000020 /* Set PAE in CR4 */ + mov cr4, ecx + + call LoadGDT32 + call UpdatePageTable + + mov ecx, BootPageTable + mov cr3, ecx + + mov ecx, 0xC0000080 /* EFER */ + rdmsr + or eax, 0x800 | 0x100 | 0x1 /* Set LME, LMA, SCE */ + wrmsr + + mov ecx, cr0 + or ecx, 0x80000001 /* Set PG and PE in CR0 */ + mov cr0, ecx + + lgdt [GDT64.Ptr] + jmp GDT64.Code:HigherHalfStart + +.extern UpdatePageTable64 + +.code64 +HigherHalfStart: + mov ax, GDT64.Data + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + call UpdatePageTable64 + + mov rsp, KernelStack + KERNEL_STACK_SIZE + mov rbp, 0 + mov rdi, [MB_HeaderMagic] + mov rsi, [MB_HeaderInfo] + push rsi + push rdi + call multiboot_main +.Hang: + hlt + jmp .Hang + +.section .bootstrap.bss +.align 16 +KernelStack: + .space KERNEL_STACK_SIZE diff --git a/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h b/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h new file mode 100644 index 0000000..32f8d99 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h @@ -0,0 +1,417 @@ +/* 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 MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the 'flags' member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_relocatable +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; + multiboot_uint32_t zero; +}; +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +struct multiboot_tag_efi32_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_load_base_addr +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/Architecture/i386/Bootstrap/Multiboot/_start.s b/Architecture/i386/Bootstrap/Multiboot/_start.s new file mode 100644 index 0000000..eac169c --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/_start.s @@ -0,0 +1,40 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +.intel_syntax noprefix + +.extern Multiboot1_start +.extern Multiboot2_start + +.code32 +.section .bootstrap.text + +.global _start +_start: + cmp eax, 0x36D76289 + je .Multiboot2 + cmp eax, 0x1BADB002 + je .Multiboot1 + int3 + +.Multiboot1: + call Multiboot1_start + jmp . + +.Multiboot2: + call Multiboot2_start + jmp . diff --git a/Architecture/i386/runtime/crt0.c b/Architecture/i386/runtime/crt0.c deleted file mode 100644 index 35cf1ab..0000000 --- a/Architecture/i386/runtime/crt0.c +++ /dev/null @@ -1,15 +0,0 @@ -// #include - -// #include - -// int Entry(void *Info); - -// void _start(void *Raw) -// { -// error("Todo"); -// while (1) -// asmv("hlt"); -// Entry(NULL); -// return; -// } -// C stuff \ No newline at end of file diff --git a/Architecture/i386/runtime/crt1.c b/Architecture/i386/runtime/crt1.c deleted file mode 100644 index bcc936a..0000000 --- a/Architecture/i386/runtime/crt1.c +++ /dev/null @@ -1,15 +0,0 @@ -#include - -#include - -int Entry(void *Info); - -void _start(void *Raw) -{ - UNUSED(Raw); - error("ERROR! INVALID BOOT PROTOCOL!"); - while (1) - asmv("hlt"); - Entry(NULL); - return; -} diff --git a/Architecture/i386/runtime/crtbegin.c b/Architecture/i386/runtime/crtbegin.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/i386/runtime/crtbegin.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/i386/runtime/crtend.c b/Architecture/i386/runtime/crtend.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/i386/runtime/crtend.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/i386/runtime/crti.S b/Architecture/i386/runtime/crti.S deleted file mode 100644 index 7f9924a..0000000 --- a/Architecture/i386/runtime/crti.S +++ /dev/null @@ -1,13 +0,0 @@ -.section .init -.global _init -.type _init, @function -_init: - push %ebp - mov %esp, %ebp - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %ebp - mov %esp, %ebp diff --git a/Architecture/i386/runtime/crtn.S b/Architecture/i386/runtime/crtn.S deleted file mode 100644 index aa67ce1..0000000 --- a/Architecture/i386/runtime/crtn.S +++ /dev/null @@ -1,7 +0,0 @@ -.section .init - pop %ebp - ret - -.section .fini - pop %ebp - ret