Files
.github
.vscode
Architecture
aarch64
amd64
i686
Interrupts
cpu
runtime
ArithmeticOperations.c
Multiboot2.cpp
SystemCalls.cpp
linker.ld
Core
Execute
FileSystem
Files
GUI
Library
Network
Profiling
Recovery
SystemCalls
Tasking
Tests
include
.gitignore
DAPI.hpp
Doxyfile
Fex.hpp
KConfig.cpp
KThread.cpp
Kernel.cpp
LICENSE
Makefile
README.md
dump.sh
ipc.h
kernel.h
syscalls.h
Kernel/Architecture/i686/Multiboot2.cpp

344 lines
12 KiB
C++

#include <types.h>
#include <boot/protocols/multiboot2.h>
#include <io.h>
#include "../../kernel.h"
enum VideoType
{
VIDEO_TYPE_NONE = 0x00,
VIDEO_TYPE_COLOUR = 0x20,
VIDEO_TYPE_MONOCHROME = 0x30,
};
uint16_t GetBiosAreaHardware()
{
const uint16_t *BIOSDataAreaDetectedHardware = (const uint16_t *)0x410;
return *BIOSDataAreaDetectedHardware;
}
enum VideoType GetVideoType() { return (enum VideoType)(GetBiosAreaHardware() & 0x30); }
void GetSMBIOS()
{
unsigned char *SMBIOSAddress = (unsigned char *)0xF0000;
while ((unsigned int)(unsigned long)SMBIOSAddress < 0x100000)
{
if (SMBIOSAddress[0] == '_' &&
SMBIOSAddress[1] == 'S' &&
SMBIOSAddress[2] == 'M' &&
SMBIOSAddress[3] == '_')
{
unsigned char Checksum = 0;
int Length = SMBIOSAddress[5];
for (int i = 0; i < Length; i++)
Checksum += SMBIOSAddress[i];
if (Checksum == 0)
break;
}
SMBIOSAddress += 16;
}
if ((unsigned int)(unsigned long)SMBIOSAddress == 0x100000)
{
// No SMBIOS found
}
}
struct multiboot_info
{
multiboot_uint32_t Size;
multiboot_uint32_t Reserved;
struct multiboot_tag *Tag;
};
EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
{
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);
trace("Hello, World!");
CPU::Stop();
}
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);
BootInfo binfo;
uint32_t Itr = 0;
for (uint32_t i = 8; i < Info->Size; i += Itr)
{
multiboot_tag *Tag = (multiboot_tag *)((uint8_t *)Info + i);
if (Tag->type == MULTIBOOT_TAG_TYPE_END)
break;
switch (Tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
{
strncpy(binfo.Kernel.CommandLine,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
break;
}
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
{
strncpy(binfo.Bootloader.Name,
((multiboot_tag_string *)Tag)->string,
strlen(((multiboot_tag_string *)Tag)->string));
break;
}
case MULTIBOOT_TAG_TYPE_MODULE:
{
multiboot_tag_module *module = (multiboot_tag_module *)Tag;
static int module_count = 0;
binfo.Modules[module_count++].Address = (void *)module->mod_start;
binfo.Modules[module_count++].Size = module->size;
strncpy(binfo.Modules[module_count++].Path, "(null)", 6);
strncpy(binfo.Modules[module_count++].CommandLine, module->cmdline,
strlen(module->cmdline));
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;
uint32_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry);
binfo.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];
binfo.Memory.Size += entry.len;
switch (entry.type)
{
case MULTIBOOT_MEMORY_AVAILABLE:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = Usable;
break;
case MULTIBOOT_MEMORY_RESERVED:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = Reserved;
break;
case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = ACPIReclaimable;
break;
case MULTIBOOT_MEMORY_NVS:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = ACPINVS;
break;
case MULTIBOOT_MEMORY_BADRAM:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = BadMemory;
break;
default:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = Unknown;
break;
}
}
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;
binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr;
binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width;
binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height;
binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch;
binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp;
binfo.Framebuffer[fb_count].MemoryModel = fb->common.framebuffer_type;
switch (fb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
fixme("indexed");
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
{
binfo.Framebuffer[fb_count].RedMaskSize = fb->framebuffer_red_mask_size;
binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position;
binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size;
binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position;
binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size;
binfo.Framebuffer[fb_count].BlueMaskShift = fb->framebuffer_blue_field_position;
break;
}
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
{
fixme("ega_text");
break;
}
}
debug("Framebuffer %d: %dx%d %d bpp", i, 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:
{
binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp;
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
{
binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->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;
binfo.Kernel.PhysicalBase = (void *)load_base_addr->load_base_addr;
binfo.Kernel.VirtualBase = (void *)(load_base_addr->load_base_addr + 0xC0000000);
break;
}
}
Itr = Tag->size;
if ((Itr % 8) != 0)
Itr += (8 - Itr % 8);
}
tmp = inb(0x61) & 0xFC;
outb(0x61, tmp);
int *vm = (int *)0xb8000;
// "Not supported yet"
vm[0] = 0x054E;
vm[1] = 0x056F;
vm[2] = 0x0574;
vm[3] = 0x0520;
vm[4] = 0x0573;
vm[5] = 0x0575;
vm[6] = 0x0570;
vm[7] = 0x0570;
vm[8] = 0x0572;
vm[9] = 0x056F;
vm[10] = 0x0574;
vm[11] = 0x0520;
vm[12] = 0x0579;
vm[13] = 0x0565;
vm[14] = 0x0574;
CPU::Stop();
// Entry(&binfo);
}