aboutsummaryrefslogtreecommitdiffstats
path: root/bootloader
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bootloader/.gitignore1
-rw-r--r--bootloader/ELF.c78
-rw-r--r--bootloader/ELF.h56
-rw-r--r--bootloader/Makefile49
-rw-r--r--bootloader/README.md27
-rw-r--r--bootloader/bootloader.pro30
-rw-r--r--bootloader/bootloader.pro.user274
-rw-r--r--bootloader/deployment.pri191
-rw-r--r--bootloader/disk.c98
-rw-r--r--bootloader/disk.h9
-rw-r--r--bootloader/main.c396
-rw-r--r--bootloader/memory.c29
-rw-r--r--bootloader/memory.h14
-rw-r--r--bootloader/memorytypes.h12
-rw-r--r--bootloader/misc.s10
-rw-r--r--bootloader/other.c42
-rw-r--r--bootloader/other.h12
-rw-r--r--bootloader/paging.c295
-rw-r--r--bootloader/paging.h17
-rw-r--r--bootloader/paging_struct.h189
-rw-r--r--bootloader/vga.c108
-rw-r--r--bootloader/vga.h16
-rw-r--r--bootloader/vmmem.c25
-rw-r--r--bootloader/vmmem.h9
24 files changed, 1987 insertions, 0 deletions
diff --git a/bootloader/.gitignore b/bootloader/.gitignore
new file mode 100644
index 0000000..335ec95
--- /dev/null
+++ b/bootloader/.gitignore
@@ -0,0 +1 @@
+*.tar.gz
diff --git a/bootloader/ELF.c b/bootloader/ELF.c
new file mode 100644
index 0000000..dd2bc62
--- /dev/null
+++ b/bootloader/ELF.c
@@ -0,0 +1,78 @@
+#include "ELF.h"
+#include "memorytypes.h"
+
+#include <efi.h>
+#include <efilib.h>
+#include <efidef.h>
+
+UINTN EFIAPI elf_ceil2(float x)
+{
+ UINTN ret = x;
+ if (x - (int)x > 0) {
+ x += 1;
+ ret = (int)x;
+ }
+
+ return ret;
+}
+
+void EFIAPI PrintELFInfo(ELF * file)
+{
+ Print(L"LoadAddress: 0x%x\n", file);
+
+ Print(L"Kernel Entry Point: 0x%llx\n", file->e_entry);
+
+ Print(L"program Header offset: %d\n", file->e_phoff);
+ Print(L"Program Header Size: %d\n", file->e_phentsize);
+ Print(L"Program Header number: %d\n", file->e_phnum);
+ Print(L"== FILE PH START: 0x%llx ==\n", (uint64_t)file + file->e_phoff);
+
+ for(uint64_t i = 0; i < file->e_phnum; i++)
+ {
+ Print(L"====== PH %d\n", (uint64_t)(i+1));
+ PH* ph = (PH*)(((uint64_t)file) + file->e_phoff+i*file->e_phentsize);
+ Print(L"TOTAL LOAD offset: 0x%llx\n", (uint64_t)(file) + ph->p_offset);
+ Print(L"UNCAST LOAD offset: 0x%llx\n", (uint64_t)(file + ph->p_offset));
+ Print(L"LOAD offset: 0x%llx\n", ph->p_offset);
+ Print(L"LOAD vaddr: 0x%llx\n", ph->p_vaddr);
+ Print(L"LOAD paddr: 0x%llx\n", ph->p_paddr);
+ Print(L"LOAD size in file: 0x%llx\n", ph->p_filesz);
+ Print(L"LOAD size in memory: 0x%llx\n", ph->p_memsz);
+ }
+}
+
+Loaded_ELF* EFIAPI LoadELF(ELF* file)
+{
+ Print(L"Loading ELF file into memory\n");
+ Loaded_ELF* loaded_elf;
+
+ uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, sizeof(Loaded_ELF), (void**)&loaded_elf);
+
+ loaded_elf->ph_num = file->e_phnum;
+ loaded_elf->entry = file->e_entry;
+ uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, file->e_phnum*sizeof(Loaded_PH), (void**)&(loaded_elf->ph));
+
+ Print(L"Loading Program Segments...\n");
+ for(uint32_t i = 0; i < file->e_phnum; i++)
+ {
+ PH* ph = (PH*)(((uint64_t)file) + file->e_phoff+i*file->e_phentsize);
+ loaded_elf->ph[i].mem_size = ph->p_memsz;
+ loaded_elf->ph[i].vaddr = ph->p_vaddr;
+
+ uint64_t pages = (ph->p_memsz/1024)/4;
+
+ // uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, ph->p_memsz, (void**)&(loaded_elf->ph[i].data)); // <- wrong, need to allocate aligned pages
+ UINTN ipages = elf_ceil2(pages);
+ EFI_PHYSICAL_ADDRESS tmp;
+
+ /*EFI_STATUS allocstatus = */uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, MEM_KERNEL, ipages, &tmp);
+ loaded_elf->ph[i].data = (void*)tmp;
+
+ // Print(L"PH: %d Addr: 0x%llX\n", i, file + ph->p_offset);
+ Print(L"LOADED PH: %d Addr: 0x%llX\n", i, loaded_elf->ph[i].data);
+ uefi_call_wrapper(BS->CopyMem, 3, loaded_elf->ph[i].data, (void*)((uint64_t)(file) + ph->p_offset), ph->p_filesz);
+ }
+ Print(L"\nFinished Loading ELF file into memory\n\n");
+
+ return loaded_elf;
+}
diff --git a/bootloader/ELF.h b/bootloader/ELF.h
new file mode 100644
index 0000000..c379a91
--- /dev/null
+++ b/bootloader/ELF.h
@@ -0,0 +1,56 @@
+#ifndef ELF_H
+#define ELF_H
+
+#include <efi.h>
+
+#define ELFMAGIC 0x464C457F
+
+// Elf header struct
+typedef struct ELF
+{
+ UINT8 e_ident[16];
+ UINT16 e_type;
+ UINT16 e_machine;
+ UINT32 e_version;
+ UINT64 e_entry;
+ UINT64 e_phoff;
+ UINT64 e_shoff;
+ UINT32 e_flags;
+ UINT16 e_ehsize;
+ UINT16 e_phentsize;
+ UINT16 e_phnum;
+ UINT16 e_shentsize;
+ UINT16 e_shnum;
+ UINT16 e_shstrndx;
+} ELF;
+
+typedef struct PH
+{
+ UINT32 p_type;
+ UINT32 p_flags;
+ UINT64 p_offset;
+ UINT64 p_vaddr;
+ UINT64 p_paddr;
+ UINT64 p_filesz;
+ UINT64 p_memsz;
+ UINT64 p_align;
+} PH;
+
+typedef struct Loaded_PH
+{
+ UINT64 mem_size;
+ UINT64 vaddr;
+ void* data;
+} Loaded_PH;
+
+typedef struct Loaded_ELF
+{
+ UINT64 ph_num;
+ UINT64 entry;
+ Loaded_PH* ph;
+} Loaded_ELF;
+
+void EFIAPI PrintELFInfo(ELF * file);
+Loaded_ELF* EFIAPI LoadELF(ELF* file);
+
+#endif
diff --git a/bootloader/Makefile b/bootloader/Makefile
new file mode 100644
index 0000000..cd7cbba
--- /dev/null
+++ b/bootloader/Makefile
@@ -0,0 +1,49 @@
+#CC = gcc-4.8.3
+
+#ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
+EFI_ARCH = x86_64
+ARCH = x86-64
+
+OBJS = main.o misc.o ELF.o disk.o vga.o vmmem.o paging.o memory.o other.o
+TARGET = hello.efi
+
+EFIINC = /usr/include/efi
+EFIINCS = -I$(EFIINC) -I$(EFIINC)/$(EFI_ARCH) -I$(EFIINC)/protocol
+LIB = /usr/lib
+EFILIB = /usr/lib
+EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(EFI_ARCH).o
+EFI_LDS = $(EFILIB)/elf_$(EFI_ARCH)_efi.lds
+
+CFLAGS = $(EFIINCS) -fno-stack-protector -fpic \
+ -fshort-wchar -mno-red-zone -Wall -ggdb3 -O0 -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -mno-avx -mno-sse
+ifeq ($(ARCH),x86-64)
+ CFLAGS += -DEFI_FUNCTION_WRAPPER
+endif
+
+LDFLAGS = -T $(EFI_LDS) -shared \
+ -Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
+# -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
+
+.PHONY: all debug clean
+
+all: $(TARGET)
+
+hello.so: $(OBJS)
+ ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
+
+%.efi: %.so
+ objcopy -v -j .text -j .sdata -j .data -j .rodata -j .dynamic \
+ -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc \
+ --output-target=efi-app-x86_64 --subsystem=10 $^ $@
+# --target=efi-app-$(ARCH) $^ $@
+
+debug: all
+ objcopy -j .text -j .sdata -j .data -j .dynamic \
+ -j .dynsym -j .rel -j .rela -j .reloc \
+ -j .debug_info -j .debug_abbrev -j .debug_loc \
+ -j .debug_aranges -j .debug_line -j .debug_macinfo -j .debug_str\
+ --target=pei-$(ARCH) hello.so hello-debug.so
+# --target=efi-app-$(ARCH) hello.so hello-debug.so
+
+clean:
+ rm *.so *.efi *.o
diff --git a/bootloader/README.md b/bootloader/README.md
new file mode 100644
index 0000000..4251b2f
--- /dev/null
+++ b/bootloader/README.md
@@ -0,0 +1,27 @@
+
+UEFI Bootloader
+---------------
+
+UEFI is a replacement to the BIOS, not only as the system firmware but also changes how the computer boots.
+previously the computer would start in 16 bits mode, then jump to 32 and then to 64, all that process being the responsibility of the bootloader.
+If the system is of 64 bits and the uefi firmware is also of 64 bits the system boot directly into 64 bits, meaning the bootloader binary
+must be a 64 bits executable.
+
+It also removes old interfaces like VGA and VESA when dealing with the gpu, but in turn provides alternate ways of talking with the hardware
+all those new interfaces are defined as protocols, which you need to ask for to the firmware, as such to load a file instead of parsing the disk and
+reading the filesystem directly, you ask for the appropiate protocol that is able of understandding the disk and the filesystem, and then you use the API
+of that protocol to load the file.
+
+
+Steps
+-----
+
+* firmware load the bootloader and starts executin the entry point, at this stage the bootloader is a regular program.
+* clean up the screen and setup a more appropiate video mode
+* allocate memory for the arguments that will be passed to the kernel
+* load the kernel file form disk
+* parse the ELF header of the kernel
+* obtain the system memory map(is needed to exit the boot services)
+* exit boot services, this destroys the uefi environment and we can no longer use anything that requires the boot services(and we can no longer return to the firmware)
+* fill the the struct that will be passed to the kernel
+* jump into the kernel with the information extracted from the ELF header
diff --git a/bootloader/bootloader.pro b/bootloader/bootloader.pro
new file mode 100644
index 0000000..0a3c1f6
--- /dev/null
+++ b/bootloader/bootloader.pro
@@ -0,0 +1,30 @@
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+CONFIG -= qt
+
+INCLUDEPATH += /usr/include/efi
+
+SOURCES += main.c misc.s \
+ disk.c \
+ ELF.c \
+ vga.c \
+ vmmem.c \
+ memory.c \
+ paging.c \
+ other.c
+
+include(deployment.pri)
+qtcAddDeployment()
+
+HEADERS += \
+ ELF.h \
+ disk.h \
+ vga.h \
+ vmmem.h \
+ memory.h \
+ memorytypes.h \
+ paging_struct.h \
+ paging.h \
+ other.h
+
diff --git a/bootloader/bootloader.pro.user b/bootloader/bootloader.pro.user
new file mode 100644
index 0000000..082affd
--- /dev/null
+++ b/bootloader/bootloader.pro.user
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.6.0, 2016-02-15T01:15:17. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{2c3e9189-5d42-4938-9849-c0bb2ac935ae}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">GCC</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">GCC</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{d432c706-8e6f-4f4f-92f1-4099cda2d690}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ornitorrincos/os/build-bootloader-GCC-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ornitorrincos/os/build-bootloader-GCC-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+ <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">0</value>
+ <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+ <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">bootloader</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">bootloader2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/ornitorrincos/OS-github/bootloader/bootloader.pro</value>
+ <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">bootloader.pro</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
diff --git a/bootloader/deployment.pri b/bootloader/deployment.pri
new file mode 100644
index 0000000..5f1749f
--- /dev/null
+++ b/bootloader/deployment.pri
@@ -0,0 +1,191 @@
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Android and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ greaterThan(QT_MAJOR_VERSION, 4) {
+ itemsources = $${item}.files
+ } else {
+ itemsources = $${item}.sources
+ }
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+android-no-sdk {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ target.path = /data/user/qt
+
+ export(target.path)
+ INSTALLS += target
+} else:android {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /assets/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
+ INSTALLS += target
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:ios {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ target = $CODESIGNING_FOLDER_PATH/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += mkdir -p \"$$target\"
+ copyCommand += && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = echo Copying application data... && $$copyCommand
+ !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";"
+ QMAKE_POST_LINK += "$$copyCommand"
+ export(QMAKE_POST_LINK)
+ }
+} else:unix {
+ maemo5 {
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ !isEmpty(target.path) {
+ installPrefix = $${target.path}
+ } else {
+ installPrefix = /opt/$${TARGET}
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ isEmpty(target.path) {
+ target.path = $${installPrefix}/bin
+ export(target.path)
+ }
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
+
diff --git a/bootloader/disk.c b/bootloader/disk.c
new file mode 100644
index 0000000..646448e
--- /dev/null
+++ b/bootloader/disk.c
@@ -0,0 +1,98 @@
+#include <efi.h>
+#include <efilib.h>
+
+#include "disk.h"
+#include "memory.h"
+
+UINTN EFIAPI ceil2(float x)
+{
+ UINTN ret = x;
+ if (x - (int)x > 0) {
+ x += 1;
+ ret = (int)x;
+ }
+
+ return ret;
+}
+
+void * EFIAPI LoadFile(CHAR16 * name, UINTN memtype, int32_t* filesize)
+{
+ // ask for the protocol to handle the filesystem
+ EFI_GUID EfiSimpleFileSystemGuid = SIMPLE_FILE_SYSTEM_PROTOCOL;
+ EFI_FILE_IO_INTERFACE * FSInterface = NULL;
+ struct _EFI_FILE_HANDLE * fsroot = NULL;
+
+ EFI_STATUS localteprotocolstat = uefi_call_wrapper(BS->LocateProtocol, 3, &EfiSimpleFileSystemGuid, NULL, &FSInterface);
+
+ if(localteprotocolstat != EFI_SUCCESS)
+ {
+ Print(L"Failed to locate protocol\n");
+ }
+
+ EFI_STATUS openvolumestat = uefi_call_wrapper(FSInterface->OpenVolume, 2, FSInterface, &fsroot);
+
+ if(openvolumestat != EFI_SUCCESS)
+ {
+ Print(L"FAiled to open the volume\n");
+ }
+
+ struct _EFI_FILE_HANDLE * fp = NULL;
+
+ EFI_STATUS openstat = uefi_call_wrapper(fsroot->Open, 5, fsroot, &fp, name, (UINT64)1, (UINT64)1);
+
+
+
+ if(openstat != EFI_SUCCESS)
+ {
+ Print(L"Failed opening the file\n");
+ }
+
+
+ // even if the specification says that asking to open the file with insuficient memory
+ // reports the full file size, qemu and virtualbox implementations don't do that
+ // as such we need to get manually the file info
+ UINTN infosize = 1024;
+ EFI_FILE_INFO * info = AllocatePool(infosize);
+ EFI_GUID infoguid = EFI_FILE_INFO_ID;
+
+ EFI_STATUS infostatus = uefi_call_wrapper(fp->GetInfo, 4, fp, &infoguid, &infosize, info);
+
+ if(infostatus != EFI_SUCCESS)
+ {
+ Print(L"Failed to get FileInfo\n");
+ }
+
+ *filesize = info->FileSize;
+
+ UINTN size = info->FileSize;
+ void * data = NULL;
+
+ //data = AllocatePool(size);
+ //EFI_STATUS allocstatus = uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, size, (void**)&data);
+ float pages = (size/1024)/4;
+
+ UINTN ipages = ceil2(pages);
+ EFI_PHYSICAL_ADDRESS tmp;
+
+ EFI_STATUS allocstatus = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, memtype, ipages, &tmp);
+
+ data = (void*)tmp;
+
+ //data = AllocatePages2(size);
+
+ //if(data == NULL)
+ if(allocstatus != EFI_SUCCESS)
+ {
+ Print(L"Failed to get Kernel memory\n");
+ }
+
+ // phoenix lies, must specify the size myself
+ uefi_call_wrapper(fp->Read, 3, fp, &size, data);
+
+ // Print(L"Read Size: %d\n", size);
+
+ uefi_call_wrapper(fp->Close, 1, fp);
+
+ return data;
+}
+
diff --git a/bootloader/disk.h b/bootloader/disk.h
new file mode 100644
index 0000000..e291861
--- /dev/null
+++ b/bootloader/disk.h
@@ -0,0 +1,9 @@
+#ifndef DISK_H
+#define DISK_H
+
+#include <efidef.h>
+#include <stdint.h>
+
+void * EFIAPI LoadFile(CHAR16 * name, UINTN memtype, int32_t* filesize);
+
+#endif // DISK_H
diff --git a/bootloader/main.c b/bootloader/main.c
new file mode 100644
index 0000000..e196777
--- /dev/null
+++ b/bootloader/main.c
@@ -0,0 +1,396 @@
+#include <efi.h>
+#include <efilib.h>
+#include <efidef.h>
+#include <string.h>
+
+#include "disk.h"
+#include "vga.h"
+#include "vmmem.h"
+#include "ELF.h"
+#include "memorytypes.h"
+#include "paging_struct.h"
+#include "paging.h"
+#include "other.h"
+
+// pixel struct information(hardcoded to what qemu exposes)
+typedef struct _Pixel
+{
+ UINT8 B;
+ UINT8 G;
+ UINT8 R;
+ UINT8 Z;
+} Pixel;
+
+// struct that is going to be passed to the kernel about general system information
+typedef struct _OSDATA
+{
+ UINT32 Magic; // magic number to check
+
+ UINT32 FBWidth; // with of the framebuffer
+ UINT32 FBHeight; // height
+ UINT32 PixelSize; // size of each pixel(an rgb pixel might have a bigger size)
+ void * FBAddr; // address of the linear framebuffer
+
+ void * MEMMap; // pointer to the system memory map
+
+ void * RAMDisk; // pointer to a ramdisk loaded from the hdd
+
+ void* RSDP;
+} OSDATA;
+
+extern void BootDisableInterrupts(void); // asm code is not correct(callee doesn't set the stack correctly)
+typedef void (*kfn)(OSDATA *); // typedef to setup the entry point of the kernel and do a "jump" into it
+
+
+
+void
+EFIAPI
+efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ __asm__("hlt");
+
+ // Memory Map
+ UINTN mapsize = 0;
+ UINTN allocsize = 0;
+ EFI_MEMORY_DESCRIPTOR * map = NULL;
+ UINTN mapkey = 0;
+ UINTN descriptorsize = 0;
+ UINT32 version = 0;
+
+
+ InitializeLib(ImageHandle, SystemTable);
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); // clear the screen
+ //Pixel * fb = SetVideoMode(1024, 768, 32);
+ Pixel * fb = SetVideoMode(800, 600, 24);
+
+ PrintImageAddr(ImageHandle);
+
+ // Print(L"Number of tables: %d\n", SystemTable->NumberOfTableEntries);
+
+ EFI_GUID acpi_10 = ACPI_TABLE_GUID;
+ EFI_GUID acpi_20 = ACPI_20_TABLE_GUID;
+ void* acpi20table = NULL;
+
+
+ for(int i = 0; i < SystemTable->NumberOfTableEntries; i++)
+ {
+ if(AreEqual(&(SystemTable->ConfigurationTable[i].VendorGuid), &acpi_10, sizeof(EFI_GUID)))
+ {
+ // Print(L"ACPI 1.0 Found\n");
+ }
+ if(AreEqual(&(SystemTable->ConfigurationTable[i].VendorGuid), &acpi_20, sizeof(EFI_GUID)))
+ {
+ // Print(L"ACPI 2.0 Found\n");
+ acpi20table = SystemTable->ConfigurationTable[i].VendorTable; // <- this should be the RSDP
+ }
+ }
+
+ // some uefi implementations time out with their default setting, disable the timer
+ BS->SetWatchdogTimer(0, 0, 0, NULL);
+
+
+ //Print(L"Firmware Vendor: %s Rev: 0x%08x\n", ST->FirmwareVendor, ST->FirmwareRevision);
+
+ //while(1){};
+
+ // allocate the datat for the kernel(need to specify memory time not to be a generic loader data type)
+ OSDATA * osdata = AllocatePool(sizeof(OSDATA));
+
+ if(osdata == NULL)
+ {
+ Print(L"Os Data allocation failed\n");
+ }
+
+ int32_t kernel_size;
+
+ ELF * kernel = LoadFile(L"kernel.bin", MEM_KERNEL, &kernel_size); // we set the memory type to the one from the kernel
+
+ {
+ PH* ph = (PH*)(((uint64_t)kernel) + kernel->e_phoff); // use this to know how much and what pages to map
+ uint64_t phcount = (((uint64_t)kernel) + kernel->e_phnum);
+
+ //kernel_size = ph->p_filesz;
+ uint64_t size = (uint64_t)(kernel_size = ph->p_memsz);
+ uint64_t entry = (uint64_t)(kernel + ph->p_offset);
+
+ /*
+ Print(L"Kernel Size: 0x%llX\n", size);
+ Print(L"Kernel Entry: 0x%llX\n", entry);
+ Print(L"Program Header Count: 0x%llX\n", phcount);
+ */
+ }
+
+ // print general information about the kernel elf header
+ //PrintELFInfo(kernel);
+ Loaded_ELF* loaded_kernel = LoadELF(kernel);
+
+
+ // attempt to allocate the memory map, first try is going to be too small
+ // as such the firmware will return the correct size
+ EFI_STATUS memret = EFI_SUCCESS;
+ EFI_STATUS bootstatus = EFI_SUCCESS;
+
+ uefi_call_wrapper(BS->GetMemoryMap, 5, &mapsize, map, &mapkey, &descriptorsize, &version);
+
+
+ // as the allocation will probably modify the memory map allocate 4kb more(one page)
+ // so that the new memory map probably fits
+ allocsize = mapsize + 10*4098;
+
+ mapsize = allocsize;
+
+ uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, allocsize, (void**)&map);
+
+ uefi_call_wrapper(BS->GetMemoryMap, 5, &mapsize, map, &mapkey, &descriptorsize, &version);
+
+ // set virtual addresses in here
+ // try some paging
+ initCR3();
+
+ //uint64_t address = 0;
+ //uint64_t max = 0x400000000ull;//0x20000000;
+ // EFI_MEMORY_DESCRIPTOR * mapiterator = map;
+
+ uint64_t elements = mapsize/descriptorsize;
+
+ printCR3();
+
+ //Print(L"elements: %d\n", elements);
+
+
+
+ for(int entry = 0; entry < elements; ++entry)
+ {
+ // mapiterator = (EFI_MEMORY_DESCRIPTOR*)(((EFI_PHYSICAL_ADDRESS)mapiterator + descriptorsize));
+
+ EFI_MEMORY_DESCRIPTOR* mapiterator = (EFI_MEMORY_DESCRIPTOR*)(((uint8_t*)map) + entry*descriptorsize);
+
+ // EFI_MEMORY_DESCRIPTOR* mapiterator = &(map[entry]);
+ uint64_t page = mapiterator->PhysicalStart;
+
+ uint64_t Pstart = mapiterator->PhysicalStart;
+ uint64_t Vstart = mapiterator->VirtualStart;
+ uint64_t Npages = mapiterator->NumberOfPages;
+ uint64_t Tpage = mapiterator->Type;
+ uint64_t Att = mapiterator->Attribute;
+
+ //if(Pstart != Vstart)
+ /*
+ if(Vstart != 0)
+ {
+ Print(L"\n");
+ Print(L"---------------------------------------\n");
+ Print(L"NON MATCHING PHYSICAL AND VIRTUAL PAGES\n");
+ Print(L"Physical Start: 0x%llX\n", Pstart);
+ Print(L"Virtual Start: 0x%llX\n", Vstart);
+ Print(L"Number of Pages: 0x%llX\n", Npages);
+ Print(L"Type of Page: 0x%llX\n", Tpage);
+ Print(L"---------------------------------------\n");
+ Print(L"\n");
+ }
+ */
+
+ // if((Npages > 0) && (Vstart != 0))
+ // if(Vstart != 0)
+ // if((Pstart == 0) && (Vstart == 0))
+ // if(Pstart == Vstart)
+ if(Tpage == EfiConventionalMemory) // free pages
+ {
+ Print(L"\n");
+ Print(L"---------------------------------------\n");
+ Print(L"MAPPED MEMORY\n");
+ Print(L"Physical Start: 0x%llX\n", Pstart);
+ Print(L"Virtual Start: 0x%llX\n", Vstart);
+ Print(L"Number of Pages: 0x%llX\n", Npages);
+ Print(L"Type of Page: 0x%llX\n", Tpage);
+ Print(L"Attribute of Page: 0x%llX\n", Att);
+ Print(L"---------------------------------------\n");
+ Print(L"\n");
+ }
+
+ //Print(L"page: 0x%llX\n", page);
+ /* for(int pageentry = 0; pageentry < mapiterator->NumberOfPages; pageentry++)
+ {
+ //Print(L"SetAddr\n");
+ SetVirtualAddress(page, page);
+ page += 0x1000;
+ } */
+ }
+
+ while(1) {};
+
+ uint64_t maxaddr = 0x0000001000000000ull;
+ for(uint64_t page = 0x0; page < maxaddr; page += 0x1000)
+ {
+ SetVirtualAddress(page, page); // <- This is chanigng the memorymap 100%
+ }
+
+ // need to map the physical address the kernel is in to -2GB virtual
+ //uint64_t startvm = 0xffffffff7fffffffull;
+ //uint64_t startvm = kernel->e_entry;
+ //uint64_t currentvm = 0;
+
+ //PH* ph = (PH*)(((uint64_t)kernel) + kernel->e_phoff); // use this to know how much and what pages to map
+
+ //kernel_size = ph->p_filesz;
+ //kernel_size = ph->p_memsz;
+
+ /*
+ while(currentvm < kernel_size)
+ {
+ SetVirtualAddress((uint64_t)kernel + ph->p_offset + currentvm, startvm + currentvm);
+
+ currentvm += 0x1000;
+ }
+ */
+
+ Print(L"BEFORE MAPPING KERNEL ENTRY: 0x%llX\n", loaded_kernel->entry);
+
+ for(int i = 0; i < loaded_kernel->ph_num; i++)
+ {
+ Loaded_PH* ph = &(loaded_kernel->ph[i]);
+ Print(L"MAPPING PH: 0x%llX\n", (uint64_t)ph->vaddr);
+ uint64_t mapsize = ph->mem_size;
+ uint64_t mapped = 0;
+ while(mapped < mapsize)
+ {
+ SetVirtualAddress((uint64_t)ph->data + mapped, (uint64_t)ph->vaddr + mapped);
+ mapped += 0x1000;
+ }
+ }
+
+ // now map already allocated 8KB for the Kernel Stack
+
+
+ //printCR3();
+
+ //Print(L"kernel: 0x%llx\n", kernel);
+
+ // the call to exit boot services tells the firmware we are ready to take control of the system
+
+ // never ever call Print after the next line
+ // after the first call boot services can be partially disabled
+ // loop until the firmware reports a successful exit, the specification allows for partial shutdowns
+ // so more than one call might be necessary(on qemu with OVMF it is)
+ while((bootstatus = uefi_call_wrapper(BS->ExitBootServices, 2, ImageHandle, mapkey)) != EFI_SUCCESS) // <- actually we need an up to date mapkey, so maybe we could actually get a memorymap before, create a OS liked memory map and exit services?
+ {
+
+ mapsize = allocsize;
+
+ while((memret = uefi_call_wrapper(BS->GetMemoryMap, 5, &mapsize, map, &mapkey, &descriptorsize, &version)) == EFI_BUFFER_TOO_SMALL)
+ {
+
+ allocsize = allocsize + 2*4096; // add 8kb(2 pages)
+
+ uefi_call_wrapper(BS->FreePool, 1, map);
+
+ uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, allocsize, (void**)&map);
+
+ mapsize = allocsize;
+ }
+ }
+
+ SetCrc(&(SystemTable->Hdr)); // As we exited boot services we need to set the CRC32 again
+
+ // as we can't print to the screen the way of showing the return status of this function
+ // is to write a red or green square on the top left corner of the screen
+ if(SetVM(mapsize, descriptorsize, version, map, kernel) != EFI_SUCCESS)
+ {
+ int i = 0;
+ int j = 0;
+
+ for(i = 0; i < 256; ++i)
+ {
+ for(j = 0; j < 256; ++j)
+ {
+ Pixel p;
+ p.R = 255;
+ p.G = 0;
+ p.B = 0;
+ //p.Z = 255;
+ fb[j + 800*i] = p;
+ }
+ }
+ } else
+ {
+ int i = 0;
+ int j = 0;
+
+ for(i = 0; i < 64; ++i)
+ {
+ for(j = 0; j < 64; ++j)
+ {
+ Pixel p;
+ p.R = 0;
+ p.G = 255;
+ p.B = 0;
+ //p.Z = 255;
+ fb[j + 800*i] = p;
+ }
+ }
+ }
+
+ // we should now set s Print(L"Calling ExitBootServices\n");oe virtual mapping
+ //BootDisableInterrupts();
+
+
+ //OSDATA * osdata = (OSDATA*)(640*1024);
+
+
+
+ osdata->Magic = 0xDDEE;
+ osdata->FBWidth = 1024;
+ osdata->FBHeight = 768;
+ osdata->FBAddr = fb;
+ osdata->PixelSize = 24;
+ osdata->MEMMap = map;
+ osdata->RAMDisk = NULL;
+ osdata->RSDP = acpi20table;
+
+ // this while only serves not to call the kernel for now
+ // after calling exit boot services we can't return to the uefi environment because it's been destroyed
+ //
+
+ //kernel = (ELF*)0x280000000; // correct virtual pointer to 10GB (Sign: 0 PML4: 0 PDP:10 PD:0 Page:0)
+
+ // kfn kernel_jump = (void*)kernel->e_entry;//(void*)((EFI_PHYSICAL_ADDRESS)kernel + kernel->EntryPoint);
+ kfn kernel_jump = (void*)loaded_kernel->entry;//(void*)((EFI_PHYSICAL_ADDRESS)kernel + kernel->EntryPoint);
+
+
+ writeCR3();
+ //while(1){}
+ {
+ int i = 0;
+ int j = 0;
+
+ for(i = 0; i < 256; ++i)
+ {
+ for(j = 0; j < 256; ++j)
+ {
+ Pixel p;
+ p.R = 255;
+ p.G = 255;
+ p.B = 255;
+ p.Z = 255;
+ fb[j + 800*i] = p;
+ }
+ }
+ }
+
+ // disable interrupts
+ __asm__("cli");
+
+ //writeCR3();
+
+
+ //__asm__("hlt");
+
+ kernel_jump(osdata);
+
+ while(1){}
+
+ __asm__("hlt"); // sanity in case the kernel exists, should throw an error somehow
+ // not as if the kernel shouldn't have this same code at the end of the main though
+
+ // we should never ever reach this point(if kernel exists, it should shutdown the computer)
+}
diff --git a/bootloader/memory.c b/bootloader/memory.c
new file mode 100644
index 0000000..1e310ae
--- /dev/null
+++ b/bootloader/memory.c
@@ -0,0 +1,29 @@
+#include "memory.h"
+
+
+void * EFIAPI AllocatePagesType(IN UINTN size, IN UINTN type)
+{
+
+ void * ret = NULL;
+
+ Print(L"About to allocate\n");
+ EFI_STATUS status = uefi_call_wrapper(BS->AllocatePool, 3, type, size, &ret);
+
+ if(status == EFI_SUCCESS)
+ {
+ Print(L"Pool Allocated\n");
+ return ret;
+ }
+
+ Print(L"Allocation Failed\n");
+ return NULL;
+}
+
+void bootloader_memset(void * in, uint64_t size, uint8_t value)
+{
+ uint8_t * tmpin = in;
+ for(int i = 0; i < size; i++)
+ {
+ tmpin[i] = value;
+ }
+}
diff --git a/bootloader/memory.h b/bootloader/memory.h
new file mode 100644
index 0000000..1d42960
--- /dev/null
+++ b/bootloader/memory.h
@@ -0,0 +1,14 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <stdint.h>
+
+#include "memorytypes.h"
+
+void * EFIAPI AllocatePagesType(IN UINTN size, IN UINTN type);
+void bootloader_memset(void *, uint64_t size, uint8_t value);
+
+#endif
diff --git a/bootloader/memorytypes.h b/bootloader/memorytypes.h
new file mode 100644
index 0000000..53ba8fb
--- /dev/null
+++ b/bootloader/memorytypes.h
@@ -0,0 +1,12 @@
+#ifndef MEMORYTYPES_H
+#define MEMORYTYPES_H
+
+// memory types to mark the pages as of specific types
+// the specification allows custom types that are bigger than 0x80000000
+
+#define MEM_KERNEL 0x80000010
+#define MEM_RAMDISK 0x80000020
+#define MEM_ARGS 0x80000030
+#define MEM_PAGING 0x80000040
+
+#endif // MEMORYTYPES_H
diff --git a/bootloader/misc.s b/bootloader/misc.s
new file mode 100644
index 0000000..c228607
--- /dev/null
+++ b/bootloader/misc.s
@@ -0,0 +1,10 @@
+.text
+.global BootDisableInterrupts
+
+BootDisableInterrupts:
+ pushq %rbp
+ movq %rsp, %rbp
+ cli
+ popq %rbp
+ ret
+
diff --git a/bootloader/other.c b/bootloader/other.c
new file mode 100644
index 0000000..9286dac
--- /dev/null
+++ b/bootloader/other.c
@@ -0,0 +1,42 @@
+#include <efi.h>
+#include <efilib.h>
+#include <efidef.h>
+
+#include "other.h"
+
+void PrintImageAddr(EFI_HANDLE image)
+{
+ EFI_LOADED_IMAGE *loaded_image = NULL;
+ EFI_STATUS status;
+
+ status = uefi_call_wrapper(BS->HandleProtocol,
+ 3,
+ image,
+ &LoadedImageProtocol,
+ (void **)&loaded_image);
+
+ if (EFI_ERROR(status))
+ {
+ Print(L"handleprotocol: %r\n", status);
+ }
+
+ Print(L"Image base: 0x%lx\n", loaded_image->ImageBase);
+}
+
+bool AreEqual(void* lhs, void* rhs, uint64_t size)
+{
+ char* clhs = (char*)lhs;
+ char* crhs = (char*)rhs;
+
+ bool equal = true;
+
+ for(int i = 0; i < size; i++)
+ {
+ if(clhs[i] != crhs[i])
+ {
+ equal = false;
+ }
+ }
+
+ return equal;
+}
diff --git a/bootloader/other.h b/bootloader/other.h
new file mode 100644
index 0000000..a602956
--- /dev/null
+++ b/bootloader/other.h
@@ -0,0 +1,12 @@
+#ifndef OTHER_H
+#define OTHER_H
+
+#include <efi.h>
+#include <efilib.h>
+#include <efidef.h>
+
+void PrintImageAddr(EFI_HANDLE image);
+bool AreEqual(void* lhs, void* rhs, uint64_t size);
+
+#endif // OTHER_H
+
diff --git a/bootloader/paging.c b/bootloader/paging.c
new file mode 100644
index 0000000..d3d6dba
--- /dev/null
+++ b/bootloader/paging.c
@@ -0,0 +1,295 @@
+#include <efi.h>
+#include <efilib.h>
+#include <stdint.h>
+
+#include "memorytypes.h"
+#include "paging_struct.h"
+#include "memory.h"
+
+uint64_t size;
+uint64_t baseaddr;
+uint64_t current;
+
+uint64_t count;
+
+EFI_PHYSICAL_ADDRESS pages;
+uint64_t * CR3;
+
+uint64_t virtualmemory;
+uint64_t maxneg;
+//uint64_t base_memory;
+
+uint64_t GetNextEntry()
+{
+ uint64_t ret = current + 0x1000;//1024*4;
+
+ count++;
+
+ if(count > 1023)
+ {
+ // need to allocate new page
+ // 1024 pages for 4MB
+ EFI_STATUS allocstatus = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, MEM_PAGING, size, &pages);
+ if(allocstatus != EFI_SUCCESS)
+ {
+ Print(L"Paging space allocation failed\n");
+ Print(L"Current: 0x%llX \n", current);
+ return -1;
+ }
+ bootloader_memset((void*)pages, size*0x1000, 0x0);
+ baseaddr = (uint64_t)pages;
+ ret = baseaddr;
+
+ //Print(L"New Chunk: 0x%llX\n", baseaddr);
+ count = 0;
+
+ current = ret;
+
+ if(ret % 0x1000 != 0)
+ {
+ Print(L"WARNING Memory not aligned\n");
+ }
+
+ return ret;
+ }
+
+ //Print(L"New Entry: 0x%llX\n", ret);
+ current = ret;
+
+ if(ret % 0x1000 != 0)
+ {
+ Print(L"WARNING Memory not aligned\n");
+ }
+
+ return ret;
+}
+
+uint8_t NeedAllocation(uint64_t in)
+{
+ if(in == -1)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+UINT64 EFIAPI GetVMCPUID()
+{
+ long out = 0;
+ long id = 0x80000008;
+
+ __asm__ __volatile__ ("movq %1, %%rax;"
+ "cpuid;"
+ "movq %%rax, %0;"
+ :"=r"(out)
+ :"r"(id)
+ );
+
+ return out;
+}
+
+uint64_t powerTwo(uint64_t power)
+{
+ uint64_t ret = 1;
+
+ while(power > 0)
+ {
+ ret *= 2;
+
+ power--;
+ }
+
+ return ret;
+}
+
+void initCR3()
+{
+ UINT64 cpu = GetVMCPUID();
+
+ CPUIDsizes * sizes = (CPUIDsizes*)&cpu;
+
+ // Print(L"raw: %x\n", cpu);
+ // Print(L"Physical: %d\n", sizes->PhysicalAddress);
+ // Print(L"Virtual: %d\n", sizes->VirtualAddress);
+ virtualmemory = sizes->PhysicalAddress;
+
+ maxneg = powerTwo(virtualmemory) - 1;
+
+ size = 1024;
+
+ Print(L"Started CR3\n");
+
+ // 1024 pages for 4MB
+ EFI_STATUS allocstatus = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, MEM_PAGING, size, &pages);
+ if(allocstatus != EFI_SUCCESS)
+ {
+ Print(L"Paging space allocation failed\n");
+ return;
+ }
+
+ count = 1;
+
+ // 1024 pages at 4kb each
+ bootloader_memset((void*)pages, size*4*1024, 0x0);
+
+ baseaddr = (uint64_t)pages;
+ current = baseaddr;
+
+ CR3 = (uint64_t*)current;
+ *CR3 = 0;
+
+ *CR3 |= CR3_PCD;
+ *CR3 |= CR3_PWT;
+ //*CR3 |=(maxneg << CR3_ADDR_SHIFT);
+
+ //((s_CR3*)CR3)->PCD = 1;
+ //((s_CR3*)CR3)->PWT = 1;
+ //((s_CR3*)CR3)->base_addr = GetNextEntry();
+
+
+ //int32_t pml4es = sizeof(s_PML4E);
+
+
+ //((s_CR3*)CR3)->base_addr = maxneg;
+
+}
+
+void printCR3()
+{
+ Print(L"CR3 value: 0x%llX\n", *((uint64_t*)CR3));
+}
+
+void writeCR3()
+{
+ __asm__ __volatile__("movq %0, %%cr3;"
+ :
+ :"r"(*CR3));
+}
+
+void SetVirtualAddress(uint64_t phy, uint64_t virt)
+{
+ uint64_t* pml4 = (uint64_t*)MaskPhyAddr(*CR3);
+
+ // Get the offsets to each page table
+ uint64_t pml4offset = GetPML4Offset(virt);
+ uint64_t pdpoffset = GetPDPOffset(virt);
+ uint64_t pdoffset = GetPDOffset(virt);
+ uint64_t ptoffset = GetPTOffset(virt);
+
+
+ uint64_t pml4e = pml4[pml4offset];
+
+ // if not present, allocate the page
+ if((pml4e & PE_P) == 0x0ull)
+ {
+ //assign the physical addr, and clear all to zero
+ uint64_t tmpaddr = GetNextEntry();
+ pml4e |= MaskPhyAddr(tmpaddr);
+
+ // initialize the page
+ pml4e |= PE_P;
+ pml4e |= PE_RW;
+ pml4e |= PE_US;
+ pml4e |= PE_PWT;
+ pml4e |= PE_PCD;
+ }
+ // assign the values to the array
+ pml4[pml4offset] = pml4e;
+
+
+ uint64_t pdpe = ((uint64_t*)MaskPhyAddr(pml4e))[pdpoffset];
+ if((pdpe & PE_P) == 0x0ull)
+ {
+ // page not present
+ uint64_t tmpaddr = GetNextEntry();
+ pdpe |= MaskPhyAddr(tmpaddr);
+
+ pdpe |= PE_P;
+ pdpe |= PE_RW;
+ pdpe |= PE_US;
+ pdpe |= PE_PWT;
+ pdpe |= PE_PCD;
+ }
+ ((uint64_t*)MaskPhyAddr(pml4e))[pdpoffset] = pdpe;
+
+ uint64_t pde = ((uint64_t*)MaskPhyAddr(pdpe))[pdoffset];
+
+ if((pde & PE_P) == 0x0ull)
+ {
+ uint64_t tmpaddr = GetNextEntry();
+
+ pde |= MaskPhyAddr(tmpaddr);
+
+ pde |= PE_P;
+ pde |= PE_RW;
+ pde |= PE_US;
+ pde |= PE_PWT;
+ pde |= PE_PCD;
+ }
+ ((uint64_t*)MaskPhyAddr(pdpe))[pdoffset] = pde;
+
+ uint64_t pte = ((uint64_t*)MaskPhyAddr(pde))[ptoffset];
+
+ // need to make the pt entry
+
+ if((pte & PE_P) == 0x0ull)
+ {
+ pte |= PE_P;
+ pte |= PE_RW;
+ pte |= PE_US;
+ pte |= PE_PWT;
+ pte |= PE_PCD;
+ pte |= MaskPhyAddr(phy);
+ }
+ ((uint64_t*)MaskPhyAddr(pde))[ptoffset] = pte;
+}
+
+uint8_t checkIdentity(uint64_t phy)
+{
+ //uint8_t phyvalue = (uint8_t)(*(uint64_t*)phy);
+ uint8_t phyvalue = *(uint64_t*)phy;
+ uint8_t virtvalue;
+ uint64_t pml4e = CR3GetAddr(*CR3);// + GetPML4Offset(phy);
+ pml4e = *(((uint64_t*)pml4e) + GetPML4Offset(phy));
+ uint64_t pdpe = *(((uint64_t*)GetAddr(pml4e)) + GetPDPOffset(phy));
+ uint64_t pde = *(((uint64_t*)GetAddr(pdpe)) + GetPDOffset(phy));
+ uint64_t pte = *(((uint64_t*)GetAddr(pde)) + GetPTOffset(phy));
+ uint64_t pteptr = ((GetAddr(pte)) + GetPhyOffset(phy));
+ virtvalue = *(uint64_t*)((GetAddr(pte)) + GetPhyOffset(phy));
+
+ //s_PDPE * pdpe = ((s_PDPE*)(pml4e->PDPBA + 8*virt->PDP));
+ //s_PDE * pde = ((s_PDE*)(pdpe->PDBA + 8*virt->PD));
+ //s_PTE * pte = ((s_PTE*)(pde->PTBA + 8*virt->PT));
+ //virtvalue = *(uint8_t*)(pte->PPBA + virt->offset);
+
+ // get the correct virtual value
+
+ Print(L"ADDR: 0x%llx\n", phy);
+
+ Print(L"PML4E 0x%llx\n", pml4e);
+ Print(L"PDPE 0x%llx\n", pdpe);
+ Print(L"PDE 0x%llx\n", pde);
+ Print(L"PTE 0x%llx\n", pte);
+ Print(L"pageentry: 0x%llx\n", pteptr);
+ Print(L"PPBA 0x%llx\n", GetAddr(pte));
+
+ Print(L"PML4 %d\n", GetPML4Offset(phy));
+ Print(L"PDP %d\n", GetPDPOffset(phy));
+ Print(L"PD %d\n", GetPDOffset(phy));
+ Print(L"PT %d\n", GetPTOffset(phy));
+ Print(L"PHY 0x%llx\n", GetPhyOffset(phy));
+
+
+ Print(L"PHYSICAL: 0x%x\n", phyvalue);
+ Print(L"VIRTUAL: 0x%x\n", virtvalue);
+
+ if(phyvalue != virtvalue)
+ {
+ Print(L"Incorrect physical virtual value\n");
+ return 0;
+ }
+
+ Print(L"Correct physical virtual value\n");
+ return 1;
+}
diff --git a/bootloader/paging.h b/bootloader/paging.h
new file mode 100644
index 0000000..59eef1e
--- /dev/null
+++ b/bootloader/paging.h
@@ -0,0 +1,17 @@
+#ifndef PAGING_H
+#define PAGING_H
+
+#include <stdint.h>
+
+uint64_t GetNextEntry();
+void initCR3();
+void printCR3();
+void writeCR3();
+void SetVirtualAddress(uint64_t phy, uint64_t virt);
+uint8_t checkIdentity(uint64_t phy);
+
+
+//void * SetPagingStructs();
+
+#endif // PAGING_H
+
diff --git a/bootloader/paging_struct.h b/bootloader/paging_struct.h
new file mode 100644
index 0000000..2c3781f
--- /dev/null
+++ b/bootloader/paging_struct.h
@@ -0,0 +1,189 @@
+#ifndef PAGING_STRUCT_H
+#define PAGING_STRUCT_H
+
+#include <efi.h>
+#include <efilib.h>
+#include <stdint.h>
+
+typedef UINT64 uchar; // need to replace this for other more sensible thing or location
+
+UINT64 GetVMCPUID(); // implemented in misc.s
+
+extern uint64_t maxneg;
+
+typedef struct _CPUIDsizes
+{
+ UINT64 PhysicalAddress:8;
+ UINT64 VirtualAddress:8;
+ UINT64 Padding:48;
+} CPUIDsizes;
+
+// these entries are for 4KB pages
+
+
+// Virtual pointer bits breakdown (4KB pages)
+// +---------------+-------------+------------+-----------+-----------+-----------------------+
+// | 63 - 48 | 47 - 39 | 38 - 30 | 29 - 21 | 20 - 12 | 11 - 0 |
+// +---------------+-------------+------------+-----------+-----------+-----------------------+
+// | sign extend | PML4 offset | PDP offset | PD offset | PT offset | physical page offset |
+// +---------------+-------------+------------+-----------+-----------+-----------------------+
+
+// Virtual pointer bits breakdown (2MB pages)
+// +---------------+-------------+------------+-----------+-----------------------------------+
+// | 63 - 48 | 47 - 39 | 38 - 30 | 29 - 21 | 20 - 0 |
+// +---------------+-------------+------------+-----------+-----------------------------------+
+// | sign extend | PML4 offset | PDP offset | PD offset | physical page offset |
+// +---------------+-------------+------------+-----------+-----------------------------------+
+
+
+// paging structure:
+
+// CR3
+// the contents of this struct go into CR3
+typedef struct __attribute__((packed))
+{
+ uint64_t reserved1:3;
+ uint64_t PWT:1; // page level writethough
+ uint64_t PCD:1; // page level cache disable
+ uint64_t reserved2:7;
+ uint64_t base_addr:40; // base address to the table of PML4 entries
+ uint64_t reserved3:13;
+} s_CR3;
+
+// Virtual Pointer
+#define VP_OFF_PHY 0ull
+#define VP_OFF_PT 12ull
+#define VP_OFF_PD 21ull
+#define VP_OFF_PDP 30ull
+#define VP_OFF_PML4 39ull
+#define VP_OFF_SIGN 48ull
+
+#define GetPhyOffset(x) (x & 0xFFFull)
+#define GetPTOffset(x) ((x >> VP_OFF_PT) & 0x1FFull)
+#define GetPDOffset(x) ((x >> VP_OFF_PD) & 0x1FFull)
+#define GetPDPOffset(x) ((x >> VP_OFF_PDP) & 0x1FFull)
+#define GetPML4Offset(x) ((x >> VP_OFF_PML4) & 0x1FFull)
+#define GetSignOffset(x) ((x >> VP_OFF_SIGN) & 0xFFFFull)
+
+
+// CR3
+#define CR3_PWT (1ull << 3ull)
+#define CR3_PCD (1ull << 4ull)
+#define CR3_ADDR_SHIFT 12ull
+#define CR3_ERASE (~(maxneg << CR3_ADDR_SHIFT))
+
+#define CR3GetAddr(x) ((x >> CR3_ADDR_SHIFT) & maxneg)
+#define CR3SetAddr(x) ((x & maxneg) << CR3_ADDR_SHIFT)
+
+// Page Entry
+#define PE_P (1ull << 0ull)
+#define PE_RW (1ull << 1ull)
+#define PE_US (1ull << 2ull)
+#define PE_PWT (1ull << 3ull)
+#define PE_PCD (1ull << 4ull)
+#define PE_A (1ull << 5ull)
+#define PE_D (1ull << 6ull)
+#define PE_PS (1ull << 7ull)
+#define PE_G (1ull << 8ull)
+#define PE_BA (1ull << 12ull)
+#define PE_NX (1ull << 63ull)
+#define PE_ADDR_SHIFT 12ull
+#define PE_ERASE (~(maxneg << PE_ADDR_SHIFT))
+
+#define MaskTable(x) (x & maxneg)
+#define MaskPhyAddr(x) (x & 0xFFFFFFF000ull)
+#define SetAddr(x) (x << PE_ADDR_SHIFT)
+#define GetAddr(x) (x >> PE_ADDR_SHIFT)
+//#define GetAddr(x) (x & ~0xFFFull)
+
+
+
+// PML4E
+
+typedef struct __attribute__((packed))
+{
+ uint64_t P:1; // present bit
+ uint64_t RW:1; // read write (if 0 write protected)
+ uint64_t US:1; // user/supervisor if 0 no user mode access
+ uint64_t PWT:1; // page level write though
+ uint64_t PCD:1; // page level cache disable
+ uint64_t A:1; // accesed
+ uint64_t PS:1; // value must be 1 for 1GB pages
+ uint64_t MBZ:2;
+ uint64_t AVL:3;
+ uint64_t PDPBA:40; // physical address of the table pointed by this entry
+ uint64_t available:11; // need to look into what values go here
+ uint64_t NX:1; // execute disable
+} s_PML4E;
+
+
+
+// PDPE
+
+typedef struct __attribute__((packed))
+{
+ uint64_t P:1;
+ uint64_t RW:1;
+ uint64_t US:1;
+ uint64_t PWT:1;
+ uint64_t PCD:1;
+ uint64_t A:1;
+ uint64_t PS:1; // value must be 1 for 2MB pages
+ uint64_t zero:1; // zero
+ uint64_t MBZ:1;
+ uint64_t AVL:3;
+ uint64_t PDBA:40;
+ uint64_t available:11;
+ uint64_t NX:1;
+} s_PDPE;
+
+// PDE
+
+typedef struct __attribute__((packed))
+{
+ uint64_t P:1;
+ uint64_t RW:1;
+ uint64_t US:1;
+ uint64_t PWT:1;
+ uint64_t PCD:1;
+ uint64_t A:1;
+ uint64_t ignored1:1;
+ uint64_t zero:1;
+ uint64_t ignored2:1;
+ uint64_t AVL:3;
+ uint64_t PTBA:40;
+ uint64_t available:11;
+ uint64_t NX:1;
+} s_PDE;
+
+// PTE
+
+typedef struct __attribute__((packed))
+{
+ uint64_t P:1;
+ uint64_t RW:1;
+ uint64_t US:1;
+ uint64_t PWT:1;
+ uint64_t PCD:1;
+ uint64_t A:1;
+ uint64_t D:1;
+ uint64_t PAT:1;
+ uint64_t G:1;
+ uint64_t AVL:3;
+ uint64_t PPBA:40;
+ uint64_t available:11;
+ uint64_t NX:1;
+} s_PTE;
+
+typedef struct __attribute__((packed))
+{
+ uint64_t offset:12;
+ uint64_t PT:9;
+ uint64_t PD:9;
+ uint64_t PDP:9;
+ uint64_t PML4:9;
+ uint64_t sign:16;
+} s_VPTR;
+
+#endif // PAGING_STRUCT_H
+
diff --git a/bootloader/vga.c b/bootloader/vga.c
new file mode 100644
index 0000000..355c17f
--- /dev/null
+++ b/bootloader/vga.c
@@ -0,0 +1,108 @@
+#include <efi.h>
+#include <efilib.h>
+
+#include "vga.h"
+
+void * EFIAPI SetVideoMode(int width, int height, int bitdepth)
+{
+ // find the location of the Graphics Output protocol to aquire a linear framebuffer
+ EFI_GUID EfiGOPGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+ struct _EFI_GRAPHICS_OUTPUT_PROTOCOL * Graphics = NULL;
+
+ Print(L"Searching for GOP\n");
+
+ EFI_STATUS localteprotocolstat = uefi_call_wrapper(BS->LocateProtocol, 3, &EfiGOPGuid, NULL, &Graphics);
+
+ if(localteprotocolstat != EFI_SUCCESS)
+ {
+ Print(L"Failed to locate GOP\n");
+ }
+
+ // we now search for a 1024x768 mode with a bit depth of 32bits
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * GOPMode;
+
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * GOPInfo = NULL;
+
+ GOPMode = Graphics->Mode;
+
+ UINT32 MaxModes = GOPMode->MaxMode;
+
+ UINTN infosize = 0;
+
+ uefi_call_wrapper(Graphics->QueryMode, 4, Graphics, 0, &infosize, &GOPMode);
+
+ Print(L"Size of GOP Info: %d\n", infosize);
+
+ // print information about the available modes
+ UINT32 i;
+ uint64_t foundmode = 0;
+
+ for(i = 0; i < MaxModes; ++i)
+ {
+ uefi_call_wrapper(Graphics->QueryMode, 4, Graphics, i, &infosize, &GOPInfo);
+
+ /*
+ switch(GOPInfo->PixelFormat)
+ {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ Print(L"RGBZ\n");
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ Print(L"BGRZ\n");
+ break;
+ case PixelBitMask:
+ Print(L"By Mask\n");
+ break;
+ case PixelBltOnly:
+ Print(L"Only Blt\n"); // this mode doesn't expose a linear framebuffer
+ default:
+ Print(L"Unknown\n");
+ break;
+ }
+ */
+ if(GOPInfo->HorizontalResolution == width && GOPInfo->VerticalResolution == height)
+ {
+ foundmode = i;
+ }
+
+ // Print(L"Mode %d: Width: %d Height: %d\n", i, GOPInfo->HorizontalResolution, GOPInfo->VerticalResolution);
+ }
+
+ uefi_call_wrapper(Graphics->SetMode, 2, Graphics, foundmode); // hardcoded to mode 2(1024x768), this is only tue for the cirrus vga that qemu exposes
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); // clear the screen
+ //uefi_call_wrapper(Graphics->QueryMode, 4, Graphics, i, &infosize, &GOPInfo);
+ Print(L"Width: %d Height: %d Format: ", Graphics->Mode->Info->HorizontalResolution, Graphics->Mode->Info->VerticalResolution);
+ switch(Graphics->Mode->Info->PixelFormat)
+ {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ Print(L"RGBZ\n");
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ Print(L"BGRZ\n");
+ break;
+ case PixelBitMask:
+ Print(L"By Mask\n");
+ break;
+ case PixelBltOnly:
+ Print(L"Only Blt\n");
+ default:
+ Print(L"Unknown\n");
+ break;
+ }
+
+ Print(L"RedBitmask: %d\n", Graphics->Mode->Info->PixelInformation.RedMask);
+ Print(L"GreenBitmask: %d\n", Graphics->Mode->Info->PixelInformation.GreenMask);
+ Print(L"BlueBitmask: %d\n", Graphics->Mode->Info->PixelInformation.BlueMask);
+ Print(L"ReservedBitmask: %d\n", Graphics->Mode->Info->PixelInformation.ReservedMask);
+ Print(L"Pixels Per ScanLine: %d\n", Graphics->Mode->Info->PixelsPerScanLine);
+
+ // pixels seem to be 4 bytes wide(32bits)
+ // format seems to be RGB Reserved
+
+ //Print(L"FrameBuffer Size: %d\n", Graphics->Mode->FrameBufferSize);
+ //Print(L"FrameBuffer Addr: %d\n", Graphics->Mode->FrameBufferBase);
+
+ return (void*)Graphics->Mode->FrameBufferBase;
+}
+
diff --git a/bootloader/vga.h b/bootloader/vga.h
new file mode 100644
index 0000000..ba0843c
--- /dev/null
+++ b/bootloader/vga.h
@@ -0,0 +1,16 @@
+#ifndef VGA_H
+#define VGA_H
+
+#include <efi.h>
+#include <efilib.h>
+
+typedef struct _FBinfo
+{
+ int width;
+ int height;
+
+} FBinfo;
+
+void * EFIAPI SetVideoMode(int width, int height, int bitdepth);
+
+#endif // VGA_H
diff --git a/bootloader/vmmem.c b/bootloader/vmmem.c
new file mode 100644
index 0000000..f15c9ac
--- /dev/null
+++ b/bootloader/vmmem.c
@@ -0,0 +1,25 @@
+#include "vmmem.h"
+
+//#include "paging_struct.h"
+
+
+EFI_STATUS EFIAPI SetVM(IN UINTN size, IN UINTN descriptorsize, IN UINTN descriptorversion, EFI_MEMORY_DESCRIPTOR * map, void * kernel)
+{
+
+ // the code for setting up paging should go here
+
+ // edit the memory mapping so that the uefi runtime knows about it
+
+ EFI_MEMORY_DESCRIPTOR * tmp = map;
+
+ UINTN elements = size/descriptorsize;
+ UINTN i;
+ for(i = 0; i < elements; ++i)
+ {
+ tmp = (EFI_MEMORY_DESCRIPTOR*)(((EFI_PHYSICAL_ADDRESS)tmp + descriptorsize));
+ tmp->VirtualStart = tmp->PhysicalStart;
+ }
+
+ return uefi_call_wrapper(RT->SetVirtualAddressMap, 4, size, descriptorsize, descriptorversion, map);
+}
+
diff --git a/bootloader/vmmem.h b/bootloader/vmmem.h
new file mode 100644
index 0000000..97252ed
--- /dev/null
+++ b/bootloader/vmmem.h
@@ -0,0 +1,9 @@
+#ifndef VMMEM_H
+#define VMMEM_H
+
+#include <efi.h>
+#include <efilib.h>
+
+EFI_STATUS EFIAPI SetVM(IN UINTN size, IN UINTN descriptorsize, IN UINTN descriptorversion, EFI_MEMORY_DESCRIPTOR * map, void * kernel);
+
+#endif // VMMEM_H