mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-03 03:19:16 +00:00
Merge remote-tracking branch 'Kernel/master'
This commit is contained in:
51
Kernel/arch/i386/bootstrap/Multiboot/Paging/mb_pt.s
Normal file
51
Kernel/arch/i386/bootstrap/Multiboot/Paging/mb_pt.s
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.code32
|
||||
KERNEL_VIRTUAL_BASE = 0xC0000000 /* 3GB */
|
||||
KERNEL_PAGE_NUMBER = 768 /* KERNEL_VIRTUAL_BASE >> 22 */
|
||||
|
||||
.section .bootstrap.data, "a"
|
||||
.align 0x1000
|
||||
.global BootPageTable
|
||||
BootPageTable:
|
||||
.long 0x00000083
|
||||
.long 0x00400083
|
||||
.long 0x00800083
|
||||
.long 0x00C00083
|
||||
.long 0x01000083
|
||||
.long 0x01400083
|
||||
.long 0x01800083
|
||||
.long 0x01C00083
|
||||
.long 0x02000083
|
||||
.long 0x02400083
|
||||
.rept (KERNEL_PAGE_NUMBER - 10)
|
||||
.long 0
|
||||
.endr
|
||||
.long 0x00000083
|
||||
.long 0x00400083
|
||||
.long 0x00800083
|
||||
.long 0x00C00083
|
||||
.long 0x01000083
|
||||
.long 0x01400083
|
||||
.long 0x01800083
|
||||
.long 0x01C00083
|
||||
.long 0x02000083
|
||||
.long 0x02400083
|
||||
.rept (1024 - KERNEL_PAGE_NUMBER - 10)
|
||||
.long 0
|
||||
.endr
|
38
Kernel/arch/i386/bootstrap/Multiboot/_start.s
Normal file
38
Kernel/arch/i386/bootstrap/Multiboot/_start.s
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.code32
|
||||
.extern Multiboot_start
|
||||
|
||||
.section .bootstrap.text, "a"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
/* Check for multiboot */
|
||||
cmp $0x2BADB002, %eax
|
||||
je .Multiboot
|
||||
|
||||
/* Unkown bootloader */
|
||||
.Hang:
|
||||
cli
|
||||
hlt
|
||||
jmp .Hang
|
||||
|
||||
/* Multiboot */
|
||||
.Multiboot:
|
||||
call Multiboot_start
|
||||
jmp .Hang
|
27
Kernel/arch/i386/bootstrap/Multiboot/headers/header1.s
Normal file
27
Kernel/arch/i386/bootstrap/Multiboot/headers/header1.s
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
.code32
|
||||
.section .multiboot, "a"
|
||||
.align 4
|
||||
|
||||
MULTIBOOT_HEADER:
|
||||
.long 0x1BADB002
|
||||
.long 1 << 0 | 1 << 1
|
||||
.long -(0x1BADB002 + (1 << 0 | 1 << 1))
|
93
Kernel/arch/i386/bootstrap/Multiboot/headers/header2.s
Normal file
93
Kernel/arch/i386/bootstrap/Multiboot/headers/header2.s
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
.code32
|
||||
.extern Multiboot_start
|
||||
|
||||
/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */
|
||||
.section .multiboot2, "a"
|
||||
.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 0 /* 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 Multiboot_start
|
||||
EntryAddressTag_End:
|
||||
.align 8
|
||||
EndTag_Start:
|
||||
.word 0
|
||||
.word 0
|
||||
.long EndTag_End - EndTag_Start
|
||||
EndTag_End:
|
||||
MULTIBOOT2_HEADER_END:
|
81
Kernel/arch/i386/bootstrap/Multiboot/helper/detect.s
Normal file
81
Kernel/arch/i386/bootstrap/Multiboot/helper/detect.s
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
.code32
|
||||
.section .bootstrap.text, "a"
|
||||
|
||||
.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
|
64
Kernel/arch/i386/bootstrap/Multiboot/helper/gdt32.s
Normal file
64
Kernel/arch/i386/bootstrap/Multiboot/helper/gdt32.s
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.code32
|
||||
.section .bootstrap.text, "a"
|
||||
|
||||
.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:
|
||||
nop
|
||||
|
||||
.global LoadGDT32
|
||||
LoadGDT32:
|
||||
lgdt [gdtr]
|
||||
ljmp $0x8, $ActivateGDT
|
||||
|
||||
ActivateGDT:
|
||||
mov $0x10, %cx
|
||||
mov %cx, %ss
|
||||
mov %cx, %ds
|
||||
mov %cx, %es
|
||||
mov %cx, %fs
|
||||
mov $0x18, %cx
|
||||
mov %cx, %gs
|
||||
ret
|
210
Kernel/arch/i386/bootstrap/Multiboot/mb1_parse.cpp
Normal file
210
Kernel/arch/i386/bootstrap/Multiboot/mb1_parse.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <boot/protocol/multiboot.h>
|
||||
#include <memory.hpp>
|
||||
|
||||
#include "../../../../kernel.h"
|
||||
|
||||
void multiboot_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
|
||||
{
|
||||
multiboot_info *InfoAddress = r_cst(multiboot_info *, Info);
|
||||
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_MEMORY)
|
||||
{
|
||||
fixme("mem_lower: %#x, mem_upper: %#x",
|
||||
InfoAddress->mem_lower, InfoAddress->mem_upper);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_BOOTDEV)
|
||||
{
|
||||
fixme("boot_device: %#x",
|
||||
InfoAddress->boot_device);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_CMDLINE)
|
||||
{
|
||||
strncpy(mb2binfo.Kernel.CommandLine,
|
||||
r_cst(const char *, InfoAddress->cmdline),
|
||||
strlen(r_cst(const char *, InfoAddress->cmdline)));
|
||||
debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_MODS)
|
||||
{
|
||||
multiboot_mod_list *module = r_cst(multiboot_mod_list *, InfoAddress->mods_addr);
|
||||
for (size_t i = 0; i < InfoAddress->mods_count; i++)
|
||||
{
|
||||
if (i > MAX_MODULES)
|
||||
{
|
||||
warn("Too many modules, skipping the rest...");
|
||||
break;
|
||||
}
|
||||
mb2binfo.Modules[i].Address = (void *)(uint32_t)module[i].mod_start;
|
||||
mb2binfo.Modules[i].Size = module[i].mod_end - module[i].mod_start;
|
||||
strncpy(mb2binfo.Modules[i].Path, "(null)", 6);
|
||||
strncpy(mb2binfo.Modules[i].CommandLine, r_cst(const char *, module[i].cmdline),
|
||||
strlen(r_cst(const char *, module[i].cmdline)));
|
||||
debug("Module: %s", mb2binfo.Modules[i].Path);
|
||||
}
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_AOUT_SYMS)
|
||||
{
|
||||
fixme("aout_sym: [tabsize: %#x, strsize: %#x, addr: %#x, reserved: %#x]",
|
||||
InfoAddress->u.aout_sym.tabsize, InfoAddress->u.aout_sym.strsize,
|
||||
InfoAddress->u.aout_sym.addr, InfoAddress->u.aout_sym.reserved);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_ELF_SHDR)
|
||||
{
|
||||
mb2binfo.Kernel.Symbols.Num = InfoAddress->u.elf_sec.num;
|
||||
mb2binfo.Kernel.Symbols.EntSize = InfoAddress->u.elf_sec.size;
|
||||
mb2binfo.Kernel.Symbols.Shndx = InfoAddress->u.elf_sec.shndx;
|
||||
mb2binfo.Kernel.Symbols.Sections = s_cst(uintptr_t, InfoAddress->u.elf_sec.addr);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_MEM_MAP)
|
||||
{
|
||||
mb2binfo.Memory.Entries = InfoAddress->mmap_length / sizeof(multiboot_mmap_entry);
|
||||
for (uint32_t i = 0; i < mb2binfo.Memory.Entries; i++)
|
||||
{
|
||||
if (i > MAX_MEMORY_ENTRIES)
|
||||
{
|
||||
warn("Too many memory entries, skipping the rest...");
|
||||
break;
|
||||
}
|
||||
multiboot_mmap_entry entry = r_cst(multiboot_mmap_entry *, InfoAddress->mmap_addr)[i];
|
||||
mb2binfo.Memory.Size += (__SIZE_TYPE__)entry.len;
|
||||
switch (entry.type)
|
||||
{
|
||||
case MULTIBOOT_MEMORY_AVAILABLE:
|
||||
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
||||
mb2binfo.Memory.Entry[i].Length = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)entry.len;
|
||||
mb2binfo.Memory.Entry[i].Type = BadMemory;
|
||||
break;
|
||||
default:
|
||||
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
||||
mb2binfo.Memory.Entry[i].Length = (__SIZE_TYPE__)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);
|
||||
}
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_DRIVE_INFO)
|
||||
{
|
||||
fixme("drives_length: %d, drives_addr: %#x",
|
||||
InfoAddress->drives_length, InfoAddress->drives_addr);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_CONFIG_TABLE)
|
||||
{
|
||||
fixme("config_table: %#x",
|
||||
InfoAddress->config_table);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_BOOT_LOADER_NAME)
|
||||
{
|
||||
strncpy(mb2binfo.Bootloader.Name,
|
||||
r_cst(const char *, InfoAddress->boot_loader_name),
|
||||
strlen(r_cst(const char *, InfoAddress->boot_loader_name)));
|
||||
debug("Bootloader name: %s", mb2binfo.Bootloader.Name);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_APM_TABLE)
|
||||
{
|
||||
fixme("apm_table: %#x",
|
||||
InfoAddress->apm_table);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_VBE_INFO)
|
||||
{
|
||||
fixme("vbe_control_info: %#x, vbe_mode_info: %#x, vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x",
|
||||
InfoAddress->vbe_control_info, InfoAddress->vbe_mode_info,
|
||||
InfoAddress->vbe_mode, InfoAddress->vbe_interface_seg,
|
||||
InfoAddress->vbe_interface_off, InfoAddress->vbe_interface_len);
|
||||
}
|
||||
if (InfoAddress->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
|
||||
{
|
||||
static int fb_count = 0;
|
||||
mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)InfoAddress->framebuffer_addr;
|
||||
mb2binfo.Framebuffer[fb_count].Width = InfoAddress->framebuffer_width;
|
||||
mb2binfo.Framebuffer[fb_count].Height = InfoAddress->framebuffer_height;
|
||||
mb2binfo.Framebuffer[fb_count].Pitch = InfoAddress->framebuffer_pitch;
|
||||
mb2binfo.Framebuffer[fb_count].BitsPerPixel = InfoAddress->framebuffer_bpp;
|
||||
switch (InfoAddress->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 = InfoAddress->framebuffer_red_mask_size;
|
||||
mb2binfo.Framebuffer[fb_count].RedMaskShift = InfoAddress->framebuffer_red_field_position;
|
||||
mb2binfo.Framebuffer[fb_count].GreenMaskSize = InfoAddress->framebuffer_green_mask_size;
|
||||
mb2binfo.Framebuffer[fb_count].GreenMaskShift = InfoAddress->framebuffer_green_field_position;
|
||||
mb2binfo.Framebuffer[fb_count].BlueMaskSize = InfoAddress->framebuffer_blue_mask_size;
|
||||
mb2binfo.Framebuffer[fb_count].BlueMaskShift = InfoAddress->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, InfoAddress->framebuffer_width,
|
||||
InfoAddress->framebuffer_height,
|
||||
InfoAddress->framebuffer_bpp);
|
||||
debug("More info:\nAddress: %p\nPitch: %d\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d",
|
||||
InfoAddress->framebuffer_addr, InfoAddress->framebuffer_pitch, InfoAddress->framebuffer_type,
|
||||
InfoAddress->framebuffer_red_mask_size, InfoAddress->framebuffer_red_field_position, InfoAddress->framebuffer_green_mask_size,
|
||||
InfoAddress->framebuffer_green_field_position, InfoAddress->framebuffer_blue_mask_size, InfoAddress->framebuffer_blue_field_position);
|
||||
}
|
||||
|
||||
mb2binfo.Kernel.PhysicalBase = (void *)&_bootstrap_start;
|
||||
mb2binfo.Kernel.VirtualBase = (void *)(uint32_t)((uint32_t)&_bootstrap_start + 0xC0000000);
|
||||
mb2binfo.Kernel.Size = ((uint32_t)&_kernel_end - (uint32_t)&_kernel_start) + ((uint32_t)&_bootstrap_end - (uint32_t)&_bootstrap_start);
|
||||
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
|
||||
|
||||
Entry(&mb2binfo);
|
||||
}
|
300
Kernel/arch/i386/bootstrap/Multiboot/mb2_parse.cpp
Normal file
300
Kernel/arch/i386/bootstrap/Multiboot/mb2_parse.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <memory.hpp>
|
||||
|
||||
#include <boot/protocol/multiboot2.h>
|
||||
#include "../../../../kernel.h"
|
||||
|
||||
void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_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();
|
||||
}
|
||||
|
||||
{
|
||||
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 *)(uint32_t)module->mod_start;
|
||||
mb2binfo.Modules[module_count].Size = module->mod_end - module->mod_start;
|
||||
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 (i > MAX_MEMORY_ENTRIES)
|
||||
{
|
||||
warn("Too many memory entries, skipping the rest...");
|
||||
break;
|
||||
}
|
||||
multiboot_mmap_entry entry = mmap->entries[i];
|
||||
mb2binfo.Memory.Size += (size_t)entry.len;
|
||||
switch (entry.type)
|
||||
{
|
||||
case MULTIBOOT_MEMORY_AVAILABLE:
|
||||
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
||||
mb2binfo.Memory.Entry[i].Length = (size_t)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 = (size_t)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 = (size_t)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 = (size_t)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 = (size_t)entry.len;
|
||||
mb2binfo.Memory.Entry[i].Type = BadMemory;
|
||||
break;
|
||||
default:
|
||||
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
||||
mb2binfo.Memory.Entry[i].Length = (size_t)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: %d\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;
|
||||
mb2binfo.Kernel.Symbols.Num = elf->num;
|
||||
mb2binfo.Kernel.Symbols.EntSize = elf->entsize;
|
||||
mb2binfo.Kernel.Symbols.Shndx = elf->shndx;
|
||||
mb2binfo.Kernel.Symbols.Sections = (uintptr_t)&elf->sections;
|
||||
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 *)(uint32_t)load_base_addr->load_base_addr;
|
||||
mb2binfo.Kernel.VirtualBase = (void *)(uint32_t)(load_base_addr->load_base_addr + 0xC0000000);
|
||||
mb2binfo.Kernel.Size = (size_t)(((uint32_t)&_kernel_end - (uint32_t)&_kernel_start) + ((uint32_t)&_bootstrap_end - (uint32_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Entry(&mb2binfo);
|
||||
}
|
53
Kernel/arch/i386/bootstrap/Multiboot/multiboot.cpp
Normal file
53
Kernel/arch/i386/bootstrap/Multiboot/multiboot.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <memory.hpp>
|
||||
|
||||
#include "../../../../kernel.h"
|
||||
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
|
||||
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
|
||||
|
||||
void multiboot_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info);
|
||||
void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info);
|
||||
|
||||
EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info)
|
||||
{
|
||||
BootInfo mb2binfo{};
|
||||
|
||||
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 == MULTIBOOT_BOOTLOADER_MAGIC)
|
||||
multiboot_parse(mb2binfo, Magic, Info);
|
||||
else if (Magic == MULTIBOOT2_BOOTLOADER_MAGIC)
|
||||
multiboot2_parse(mb2binfo, Magic, Info);
|
||||
else
|
||||
{
|
||||
error("Unknown multiboot magic %#x", Magic);
|
||||
CPU::Stop();
|
||||
}
|
||||
}
|
79
Kernel/arch/i386/bootstrap/Multiboot/start.s
Normal file
79
Kernel/arch/i386/bootstrap/Multiboot/start.s
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.code32
|
||||
KERNEL_STACK_SIZE = 0x4000 /* 16KB */
|
||||
|
||||
.extern DetectCPUID
|
||||
.extern DetectPSE
|
||||
.extern multiboot_main
|
||||
.extern LoadGDT32
|
||||
.extern BootPageTable
|
||||
|
||||
.section .bootstrap.data, "a"
|
||||
MB_HeaderMagic:
|
||||
.quad 0
|
||||
|
||||
MB_HeaderInfo:
|
||||
.quad 0
|
||||
|
||||
.section .bootstrap.text, "a"
|
||||
|
||||
.global Multiboot_start
|
||||
Multiboot_start:
|
||||
cli
|
||||
|
||||
mov %eax, [MB_HeaderMagic]
|
||||
mov %ebx, [MB_HeaderInfo]
|
||||
|
||||
call DetectCPUID
|
||||
cmp $0, %eax
|
||||
je .
|
||||
|
||||
call DetectPSE
|
||||
cmp $0, %eax
|
||||
je .
|
||||
|
||||
mov %cr4, %ecx
|
||||
or $0x00000010, %ecx /* PSE */
|
||||
mov %ecx, %cr4
|
||||
|
||||
call LoadGDT32
|
||||
|
||||
mov $BootPageTable, %ecx
|
||||
mov %ecx, %cr3
|
||||
|
||||
mov %cr0, %ecx
|
||||
or $0x80000000, %ecx /* PG */
|
||||
mov %ecx, %cr0
|
||||
|
||||
mov $(KernelStack + KERNEL_STACK_SIZE), %esp
|
||||
mov $0x0, %ebp
|
||||
|
||||
mov [MB_HeaderMagic], %eax
|
||||
mov [MB_HeaderInfo], %ebx
|
||||
push %ebx
|
||||
push %eax
|
||||
call multiboot_main
|
||||
.Hang:
|
||||
hlt
|
||||
jmp .Hang
|
||||
|
||||
.section .bootstrap.bss, "a"
|
||||
.align 16
|
||||
KernelStack:
|
||||
.space KERNEL_STACK_SIZE
|
Reference in New Issue
Block a user