x32 is now compiling

This commit is contained in:
Alex
2023-03-04 21:17:19 +02:00
parent aa29c8a415
commit 5c91f23527
57 changed files with 1217 additions and 573 deletions

View File

@ -158,7 +158,7 @@ int __ctzdi2(arith64_u64 a)
arith64_u64 __divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
{
if (b > a) //
if (b > a)
{
if (c)
*c = a;
@ -283,3 +283,45 @@ int __gedf2(double a, double b) { return a >= b; }
int __fixdfsi(double a) { return (int)a; }
long __fixdfdi(double a) { return (long)a; }
int __ledf2(double a, double b) { return a <= b; }
/* FIXME: Check if these functions are implemented correctly */
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
typedef struct
{
uint64_t value;
} atomic_uint64_t;
uint64_t __atomic_load_8(const atomic_uint64_t *p)
{
uint64_t value;
__asm__ volatile("lock cmpxchg8b %1"
: "=A"(value)
: "m"(*p)
: "memory");
return value;
}
void __atomic_store_8(atomic_uint64_t *p, uint64_t value)
{
__asm__ volatile("lock cmpxchg8b %0"
: "=m"(p->value)
: "a"((uint32_t)value), "d"((uint32_t)(value >> 32)), "m"(*p)
: "memory");
}
/* FIXME: __fixsfsi is not implemented correctly(?) */
int __fixsfsi(float a) { return (int)a; }
int __ltsf2(float a, float b) { return a < b; }
int __eqsf2(float a, float b) { return a == b; }
float __divsf3(float a, float b) { return a / b; }
double __extendsfdf2(float a) { return (double)a; }
float __truncdfsf2(double a) { return (float)a; }
float __subsf3(float a, float b) { return a - b; }
float __floatsisf(int a) { return (float)a; }
int __fixunssfsi(float a) { return (int)a; }
float __mulsf3(float a, float b) { return a * b; }
float __addsf3(float a, float b) { return a + b; }

View File

@ -1,10 +1,13 @@
#include <types.h>
#include <boot/protocols/multiboot2.h>
#include <memory.hpp>
#include <io.h>
#include "../../kernel.h"
BootInfo mb2binfo;
enum VideoType
{
VIDEO_TYPE_NONE = 0x00,
@ -47,72 +50,52 @@ void GetSMBIOS()
}
}
struct multiboot_info
void ProcessMB2(unsigned long 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)
uint8_t *VideoBuffer = (uint8_t *)0xB8F00 + 0xC0000000;
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 (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();
}
VideoBuffer[pos++] = '.';
VideoBuffer[pos++] = 0x2;
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)
{
debug("End of multiboot2 tags");
break;
}
switch (Tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
{
strncpy(binfo.Kernel.CommandLine,
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(binfo.Bootloader.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;
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,
mb2binfo.Modules[module_count++].Address = (void *)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);
break;
}
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
@ -133,8 +116,7 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
{
multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag;
uint32_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry);
binfo.Memory.Entries = EntryCount;
mb2binfo.Memory.Entries = EntryCount;
for (uint32_t i = 0; i < EntryCount; i++)
{
if (EntryCount > MAX_MEMORY_ENTRIES)
@ -142,42 +124,45 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
warn("Too many memory entries, skipping the rest...");
break;
}
multiboot_mmap_entry entry = mmap->entries[i];
binfo.Memory.Size += entry.len;
mb2binfo.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;
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:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = 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:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = ACPIReclaimable;
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:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = ACPINVS;
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:
binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
binfo.Memory.Entry[i].Length = entry.len;
binfo.Memory.Entry[i].Type = BadMemory;
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
mb2binfo.Memory.Entry[i].Length = entry.len;
mb2binfo.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;
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;
}
@ -192,14 +177,12 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
{
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;
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;
mb2binfo.Framebuffer[fb_count].MemoryModel = fb->common.framebuffer_type;
switch (fb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
@ -209,12 +192,12 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
}
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;
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:
@ -223,12 +206,11 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
break;
}
}
debug("Framebuffer %d: %dx%d %d bpp", i, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp);
debug("Framebuffer %d: %dx%d %d bpp", Tag, 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;
}
@ -266,12 +248,14 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
}
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
{
binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp;
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp;
debug("OLD ACPI RSDP: %p", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
{
binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp;
mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp;
debug("NEW ACPI RSDP: %p", mb2binfo.RSDP);
break;
}
case MULTIBOOT_TAG_TYPE_NETWORK:
@ -307,37 +291,49 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
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);
mb2binfo.Kernel.PhysicalBase = (void *)load_base_addr->load_base_addr;
mb2binfo.Kernel.VirtualBase = (void *)(load_base_addr->load_base_addr + 0xC0000000);
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
break;
}
default:
{
error("Unknown multiboot2 tag type: %d", Tag->type);
break;
}
}
Itr = Tag->size;
if ((Itr % 8) != 0)
Itr += (8 - Itr % 8);
}
}
EXTERNC void x32Multiboot2Entry(unsigned long 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);
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);
ProcessMB2(Info);
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);
Entry(&mb2binfo);
}

View File

@ -324,7 +324,7 @@ namespace APIC
private:
APIC *lapic;
uint64_t Ticks = 0;
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
public:
uint64_t GetTicks() { return Ticks; }

View File

@ -1,4 +1,5 @@
; Inspired From: https://github.com/MQuy/mos/blob/master/src/kernel/boot.asm
; https://wiki.osdev.org/Higher_Half_x86_Bare_Bones
; https://wiki.osdev.org/Higher_Half_x86_Bare_Bones_(Backup)
section .multiboot2
align 4096
HEADER_START:
@ -7,6 +8,33 @@ HEADER_START:
dd (HEADER_END - HEADER_START)
dd 0x100000000 - (HEADER_END - HEADER_START) - 0 - 0xE85250D6
align 8
MB2_INFO_REQUEST_TAG_START:
dw 1
dw 0
dd MB2_INFO_REQUEST_TAG_END - MB2_INFO_REQUEST_TAG_START
dd 1 ; Command Line
dd 2 ; Boot Loader Name
dd 3 ; Module
dd 4 ; Basic Memory Information
dd 5 ; BIOS Boot Device
dd 6 ; Memory Map
dd 7 ; VBE
dd 8 ; Framebuffer
dd 9 ; ELF Sections
dd 10 ; APM Table
dd 11 ; EFI 32-bit System Table Pointer
dd 12 ; EFI 64-bit System Table Pointer
; dd 13 ; SMBIOS
dd 14 ; ACPI Old
dd 15 ; ACPI New
dd 16 ; Network
dd 17 ; EFI Memory Map
dd 18 ; EFI Boot Services Notifier
dd 19 ; EFI 32-bit Image Handle Pointer
dd 20 ; EFI 64-bit Image Handle Pointer
dd 21 ; Load Base Address
MB2_INFO_REQUEST_TAG_END:
align 8
MB2_TAG_START:
dw 0
dw 0
@ -25,34 +53,41 @@ section .data
align 0x1000
BootPageTable:
dd 0x00000083
times ((KERNEL_PAGE_NUMBER) - 1) dd 0
dd 0x00000083
times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0
times (KERNEL_PAGE_NUMBER - 2) dd 0
dd 0x00000083
dd 0x00000083
times (1024 - KERNEL_PAGE_NUMBER - 2) dd 0
section .text
_start:
mov word [0xb8000], 0x074C ; L
mov word [0xb8002], 0x076F ; o
mov word [0xb8004], 0x0761 ; a
mov word [0xb8006], 0x0764 ; d
mov word [0xb8008], 0x0769 ; i
mov word [0xb800a], 0x076E ; n
mov word [0xb800c], 0x0767 ; g
mov word [0xb800e], 0x072E ; .
mov word [0xb8010], 0x072E ; .
mov word [0xb8012], 0x072E ; .
mov word [0xb8F00], 0x072E ; .
mov ecx, (BootPageTable - KERNEL_VIRTUAL_BASE)
mov cr3, ecx
mov word [0xb8F02], 0x072E ; .
mov ecx, cr4
or ecx, 0x00000010 ; Set PSE in CR4
mov cr4, ecx
mov word [0xb8F04], 0x072E ; .
mov ecx, cr0
or ecx, 0x80000000 ; Set PG in CR0
mov cr0, ecx
mov word [0xb8F06], 0x072E ; .
lea ecx, [HigherHalfStart]
jmp ecx
HigherHalfStart:
mov word [0xb8F08], 0x072E ; .
mov dword [BootPageTable], 0
invlpg [0]
mov esp, KernelStack + KERNEL_STACK_SIZE
push eax ; Multiboot2 Magic