...
 
Commits (12)
......@@ -6,13 +6,17 @@ build:
stage: build
cache:
paths:
- deps
- build/*-prefix
script:
- make images
- mkdir build
- cd build
- cmake ..
- make all iso VERBOSE=1
artifacts:
name: "$CI_BUILD_REF_NAME"
paths:
- bin
- build/pxkrnl
- build/phoenixos.iso
pages:
stage: docs
......
cmake_minimum_required(VERSION 3.11.4)
include(ExternalProject)
include(cmake/toolchain.cmake)
project(pxos ASM C CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib -ffreestanding")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -ffreestanding")
set(SRCDIR "${CMAKE_SOURCE_DIR}/src")
include(cmake/modules.cmake)
include(cmake/kernel.cmake)
include(cmake/deps.cmake)
include(cmake/iso.cmake)
include(cmake/launch.cmake)
include(cmake/cpplint.cmake)
include(cmake/pvs.cmake)
add_lint_target("${LINT_SOURCES}")
set noparent
filter=-build/include_what_you_use,-readability/todo
filter=-build/include_what_you_use,-readability/todo,-runtime/indentation_namespace
linelength=120
# PhoeniX OS Makefile
# Copyright © 2017-2019 Yury Popov a.k.a. PhoeniX
.PHONY: all
all: kernel
MAKEROOT := $(PWD)/makefiles
sinclude $(MAKEROOT)/root.mk
function(add_lint_target SOURCES_LIST)
find_program(LINT cpplint)
list(REMOVE_DUPLICATES SOURCES_LIST)
list(SORT SOURCES_LIST)
list(FILTER SOURCES_LIST INCLUDE REGEX "\\.(c(c|uh?|pp|xx|\\+\\+|)?|h(pp|\\+\\+|xx)?)$")
add_custom_target(lint
COMMAND "${CMAKE_COMMAND}" -E chdir
"${CMAKE_CURRENT_SOURCE_DIR}"
"${LINT}" ${SOURCES_LIST}
DEPENDS ${SOURCES_LIST}
VERBATIM
)
endfunction()
ExternalProject_Add(
ovmf.fd
URL https://mirrors.edge.kernel.org/ubuntu/pool/universe/e/edk2/ovmf_0~20180205.c0d9813c-2_all.deb
URL_HASH SHA256=6c73c1b99fe745d95dd5fc3e1d09924018628d40d8cbad556696f2906d335636
EXCLUDE_FROM_ALL TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ${TAR} xf <SOURCE_DIR>/data.tar.xz -C <BINARY_DIR> --strip-components 4 ./usr/share/ovmf/OVMF.fd
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(ovmf.fd BINARY_DIR)
set(OVMF_PATH ${BINARY_DIR}/OVMF.fd)
ExternalProject_Add(
syslinux
URL https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/6.xx/syslinux-6.03.tar.xz
URL_HASH SHA256=26d3986d2bea109d5dc0e4f8c4822a459276cf021125e8c9f23c3cca5d8c850e
EXCLUDE_FROM_ALL TRUE
DOWNLOAD_NO_EXTRACT ON
CONFIGURE_COMMAND ""
BUILD_COMMAND ${TAR} xf <DOWNLOADED_FILE> -C <SOURCE_DIR> --strip-components 3 syslinux-6.03/bios/core/isolinux.bin syslinux-6.03/bios/com32/elflink/ldlinux/ldlinux.c32 syslinux-6.03/bios/com32/lib/libcom32.c32 syslinux-6.03/bios/com32/mboot/mboot.c32
COMMAND cp <SOURCE_DIR>/isolinux.bin <SOURCE_DIR>/elflink/ldlinux/ldlinux.c32 <SOURCE_DIR>/lib/libcom32.c32 <SOURCE_DIR>/mboot/mboot.c32 <BINARY_DIR>/
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(syslinux BINARY_DIR)
set(SYSLINUX_PATH ${BINARY_DIR})
set(ISOROOT isodir)
set(ISONAME "PhoeniX-OS")
set(ISOOPTS -quiet -U -A ${ISONAME} -V ${ISONAME} -volset ${ISONAME} -J -joliet-long -r)
set(ISOOPTS ${ISOOPTS} -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table)
set(ISOOPTS ${ISOOPTS} -eltorito-alt-boot -e efiboot.img -no-emul-boot)
add_custom_target(phoenixos.iso
mkdir -p ${ISOROOT}
COMMAND truncate -s 4m ${ISOROOT}/efiboot.img
COMMAND ${MKFAT} -t 1 -h 1 -s 8192 -v EFI -L 32 -i ${ISOROOT}/efiboot.img
COMMAND ${MMD} -i ${ISOROOT}/efiboot.img ::efi
COMMAND ${MMD} -i ${ISOROOT}/efiboot.img ::efi/boot
COMMAND ${MCOPY} -i ${ISOROOT}/efiboot.img pxkrnl ::efi/boot/bootx64.efi
COMMAND cp pxkrnl ${SYSLINUX_PATH}/isolinux.bin ${SYSLINUX_PATH}/ldlinux.c32 ${SYSLINUX_PATH}/libcom32.c32 ${SYSLINUX_PATH}/mboot.c32 ${ISOROOT}/
COMMAND echo 'default /mboot.c32 /pxkrnl' > ${ISOROOT}/isolinux.cfg
COMMAND ${MKISO} ${ISOOPTS} -o phoenixos.iso ${ISOROOT}
DEPENDS pxkrnl syslinux
)
add_custom_target(iso DEPENDS phoenixos.iso)
set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/ld/system.ld")
set(KERNDIR_TAG kernel.cmake)
file(GLOB_RECURSE KERNDIRS RELATIVE ${SRCDIR} ${SRCDIR}/**/${KERNDIR_TAG})
list(TRANSFORM KERNDIRS REPLACE "/${KERNDIR_TAG}$" "")
list(TRANSFORM KERNDIRS REPLACE "/" ".")
foreach(kerndir ${KERNDIRS})
list (APPEND INCDIRS "${SRCDIR}/${kerndir}/include")
endforeach(kerndir)
list(REMOVE_ITEM KERNDIRS "boot")
foreach(kerndir ${KERNDIRS})
file(GLOB SRCS "${SRCDIR}/${kerndir}/*.s" "${SRCDIR}/${kerndir}/*.c" "${SRCDIR}/${kerndir}/*.cpp")
add_library(${kerndir} STATIC ${SRCS})
file(GLOB_RECURSE INCS ${SRCDIR}/${kerndir}/include/*.h ${SRCDIR}/${kerndir}/include/*.hpp)
list(APPEND LINT_SOURCES ${INCS})
list(APPEND LINT_SOURCES ${SRCS})
target_include_directories(${kerndir} PRIVATE ${INCDIRS})
endforeach(kerndir)
file(GLOB kern_SRCS "${SRCDIR}/boot/*.s" "${SRCDIR}/boot/*.c" "${SRCDIR}/boot/*.cpp")
add_executable(pxkrnl.elf ${kern_SRCS})
file(GLOB_RECURSE kern_INCS ${SRCDIR}/boot/include/*.h ${SRCDIR}/boot/include/*.hpp)
list(APPEND LINT_SOURCES ${kern_INCS})
list(APPEND LINT_SOURCES ${kern_SRCS})
target_include_directories(pxkrnl.elf PRIVATE ${INCDIRS})
set_target_properties(pxkrnl.elf PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})
set_target_properties(pxkrnl.elf PROPERTIES LINK_FLAGS "-T ${LINKER_SCRIPT}")
target_link_libraries(pxkrnl.elf ${KERNDIRS} modules-linked)
add_custom_target(pxkrnl ALL
${CMAKE_LLVM_OBJCOPY} --strip-all pxkrnl.elf pxkrnl.elf.strip
COMMAND ${CMAKE_OBJCOPY} -Opei-x86-64 --subsystem efi-app --file-alignment 1 --section-alignment 1 pxkrnl.elf.strip pxkrnl
DEPENDS pxkrnl.elf
)
set(EFIROOT efi)
add_custom_target(${EFIROOT}
mkdir -p ${EFIROOT}/efi/boot/
COMMAND cp pxkrnl ${EFIROOT}/efi/boot/bootx64.efi
DEPENDS pxkrnl
)
set(QEMU_FLAGS -smp cores=2,threads=2 -cpu Broadwell -serial stdio)
add_custom_target(launch
${QEMU} ${QEMU_FLAGS} -kernel pxkrnl
DEPENDS pxkrnl
)
add_custom_target(launch-efi
${QEMU} ${QEMU_FLAGS} -drive file=fat:rw:${EFIROOT},format=raw,media=disk -bios ${OVMF_PATH}
DEPENDS ${EFIROOT} ovmf.fd
)
add_custom_target(launch-iso
${QEMU} ${QEMU_FLAGS} -cdrom phoenixos.iso
DEPENDS iso
)
add_custom_target(launch-iso-efi
${QEMU} ${QEMU_FLAGS} -cdrom phoenixos.iso -bios ${OVMF_PATH}
DEPENDS iso ovmf.fd
)
set(MODDIR_TAG module.cmake)
file(GLOB_RECURSE MODDIRS RELATIVE ${SRCDIR} ${SRCDIR}/**/${MODDIR_TAG})
list(TRANSFORM MODDIRS REPLACE "/${MODDIR_TAG}$" "")
file(WRITE ${CMAKE_BINARY_DIR}/modules.s ".section .modules, \"a\"\n")
file(APPEND ${CMAKE_BINARY_DIR}/modules.s ".global __modules_start__\n__modules_start__:\n")
add_library(modules-linked STATIC ${CMAKE_BINARY_DIR}/modules.s)
foreach(moddir ${MODDIRS})
string(REPLACE "/" "." mod ${moddir})
set(ROOT_${mod} ${SRCDIR}/${moddir})
file(GLOB SRCS_${mod} ${ROOT_${mod}}/*.s ${ROOT_${mod}}/*.c ${ROOT_${mod}}/*.cpp)
add_library(mod_${mod} SHARED ${SRCS_${mod}})
add_custom_command(
TARGET mod_${mod} POST_BUILD
COMMAND ${CMAKE_LLVM_OBJCOPY} --strip-non-alloc --strip-debug --strip-unneeded libmod_${mod}.so libmod_${mod}.strip.so
COMMAND touch ${CMAKE_BINARY_DIR}/modules.s
)
list(APPEND LINT_SOURCES ${SRCS_${mod}})
file(GLOB_RECURSE INCS_${mod} ${ROOT_${mod}}/*.h ${ROOT_${mod}}/*.hpp)
list(APPEND LINT_SOURCES ${INCS_${mod}})
add_dependencies(modules-linked mod_${mod})
file(APPEND ${CMAKE_BINARY_DIR}/modules.s ".global __module_${mod}\n__module_${mod}:\n")
file(APPEND ${CMAKE_BINARY_DIR}/modules.s ".incbin \"libmod_${mod}.strip.so\"\n")
endforeach(moddir)
file(APPEND ${CMAKE_BINARY_DIR}/modules.s ".global __modules_end__\n__modules_end__:\n")
find_program(PVS_ANALYZER pvs-studio-analyzer)
find_program(PLOG_CONVERT plog-converter)
set(PVS_LOG ${CMAKE_BINARY_DIR}/pvs.log)
set(PVS_TASKS ${CMAKE_BINARY_DIR}/pvs.tasks)
set(PVS_HTML ${CMAKE_BINARY_DIR}/pvs.html)
set(PVS_FILTER "GA:1,2;OP:1,2,3;64:1;CS:1,2,3")
add_custom_target(check-pvs
COMMAND "${PVS_ANALYZER}" analyze -i -j4 -a13 -o "${PVS_LOG}"
COMMAND "${PLOG_CONVERT}" -m cwe -a "${PVS_FILTER}" -t tasklist -o "${PVS_TASKS}" "${PVS_LOG}"
COMMAND "${PLOG_CONVERT}" -m cwe -a "${PVS_FILTER}" -t fullhtml -o "${PVS_HTML}" "${PVS_LOG}"
DEPENDS ${LINT_SOURCES}
VERBATIM
)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_CROSSCOMPILING ON)
set(CROSS_LLVM_PATH /usr/local/opt/llvm/bin)
set(CROSS_BINUTILS_PATH /usr/local/opt/binutils/bin)
find_program(CMAKE_C_COMPILER clang HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_CXX_COMPILER clang++ HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_LLVM_OBJCOPY llvm-objcopy HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_OBJCOPY objcopy HINTS ${CROSS_BINUTILS_PATH})
find_program(CMAKE_AR llvm-ar HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_NM llvm-nm HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_RANLIB llvm-ranlib HINTS ${CROSS_LLVM_PATH})
find_program(CMAKE_LINKER ld.lld HINTS ${CROSS_LLVM_PATH})
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
set(CROSS_LINKER_FLAGS "")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> -o <TARGET> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_LINKER> --shared -o <TARGET> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_EXE_LINKER_FLAGS "${CROSS_LINKER_FLAGS} -g -nostdlib -O2 --hash-style=sysv" CACHE STRING "" FORCE)
set(CMAKE_MODULE_LINKER_FLAGS "${CROSS_LINKER_FLAGS} -g -nostdlib -O2 --hash-style=sysv" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "${CROSS_LINKER_FLAGS} -g -nostdlib -O2 --hash-style=sysv" CACHE STRING "" FORCE)
set(CMAKE_STATIC_LINKER_FLAGS ${CROSS_LINKER_FLAGS} CACHE STRING "" FORCE)
set(CROSS_TARGET x86_64-none-elf)
set(CROSS_COMPILER_FLAGS "")
set(CMAKE_ASM_COMPILER_TARGET ${CROSS_TARGET})
set(CMAKE_C_COMPILER_TARGET ${CROSS_TARGET})
set(CMAKE_CXX_COMPILER_TARGET ${CROSS_TARGET})
set(CMAKE_C_FLAGS "${CROSS_COMPILER_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 -mno-sse")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions -fno-rtti -fshort-wchar")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 -Os")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -fpic -fpie")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wproperty-attribute-mismatch")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wold-style-cast -Wcast-qual -Wcast-align -Winline")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "${CMAKE_C_ARCHIVE_CREATE}")
find_program(TAR tar)
find_program(MKISO xorriso)
if(MKISO)
set(MKISO ${MKISO} -as mkisofs)
else()
find_program(MKISO mkisofs)
endif()
find_program(MKFAT mformat)
find_program(MCOPY mcopy)
find_program(MMD mmd)
find_program(QEMU qemu-system-x86_64)
project(stub)
SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
......@@ -5,8 +5,7 @@
OUTPUT_FORMAT(elf64-x86-64)
ENTRY(_efi_start)
PROVIDE(__stack_end__ = 0x2000);
PROVIDE(__pagetable__ = 0x20000);
PROVIDE(__stack_end__ = 0x4000);
PHDRS
{
......@@ -32,10 +31,7 @@ SECTIONS
} :text
.rodata : ALIGN(1) {
. = ALIGN(8);
__modules_start__ = . ;
*(.modules)
. = ALIGN(64);
__modules_end__ = . ;
. = ALIGN(8);
__data_start__ = . ;
......
CFLAGS := -g -m64 -mno-sse
CFLAGS += -nostdlib -std=c++11
CFLAGS += -O2 -Os -Wall -Wextra -Werror
CFLAGS += -Wproperty-attribute-mismatch
CFLAGS += -Wcast-qual -Wcast-align -Winline
CFLAGS += -ffreestanding -fno-exceptions -fno-rtti -fshort-wchar
CFLAGS += -ffunction-sections -fdata-sections -fpic -fpie
LDFLAGS := -g -nostdlib -O2
ODIR=.output
OOBJDIR=$(ODIR)/obj
OMODDIR=$(ODIR)/mod
OBINDIR=$(ODIR)/bin
OLIBDIR=$(ODIR)/lib
OIMGDIR=$(ODIR)/img
ISOROOT=$(ODIR)/iso
SRCDIR=src
BIN=$(OIMGDIR)/pxkrnl
define SCANDIRS
$(foreach f,$(wildcard $(1)/$(2)) $(foreach s,$(wildcard $(1)/*),$(call SCANDIRS,$(s),$(2))),$(dir $(f)))
endef
define UNIQ
$(if $1,$(firstword $1) $(call UNIQ,$(filter-out $(firstword $1),$1)))
endef
define SRCOBJ
$(patsubst $(SRCDIR)/%,$(OOBJDIR)/%,$(patsubst %.cpp,%.o,$(patsubst %.s,%.o,$(1))))
endef
define DEPSRC
$(patsubst %.o,%.d,$(call SRCOBJ,$(1)))
endef
define RULESCAN
LIBNAME_$(1) := $$(subst /,_,$$(patsubst %/,%,$(1)))
CSRCS_$(1) := $$(wildcard $(SRCDIR)/$(1)*.cpp)
ASRCS_$(1) := $$(wildcard $(SRCDIR)/$(1)*.s)
SRCS_$(1) := $$(CSRCS_$(1)) $$(ASRCS_$(1))
OBJS_$(1) := $$(call SRCOBJ,$$(SRCS_$(1)))
INCLUDES_$(1) := $$(wildcard $(SRCDIR)/$(1)include)
INCLUDES += $$(INCLUDES_$(1))
SOURCES += $$(SRCS_$(1))
endef
define KERNRULES
$(call RULESCAN,$(1))
KERNOBJS += $(OLIBDIR)/$$(LIBNAME_$(1)).a
$(OLIBDIR)/$$(LIBNAME_$(1)).a: $$(OBJS_$(1))
@ mkdir -p $$(dir $$@)
$(QECHO) AR $$(subst $(OLIBDIR)/,,$$@)
$(Q) $(AR) cru $$@ $$?
endef
define LIBRULES
LIBOBJS += $(OLIBDIR)/$$(patsubst %/,%,$(1)).a
endef
define MODRULES
$(call RULESCAN,$(1))
MODOBJS += $(OOBJDIR)/mod_$$(LIBNAME_$(1)).o
$(OOBJDIR)/mod_$$(LIBNAME_$(1)).o: $$(OBJS_$(1))
@ mkdir -p $$(dir $$@)
$(QECHO) MODLD $$(patsubst %/,%,$(1))
$(Q) $(LD) $(LDFLAGS) --shared -s -o $$@ $$?
endef
define DOWN_RULE
deps/$(DEP_$(1)_FILE):
@ mkdir -p $$(dir $$@)
$(QECHO) DL $$@
$(Q) wget -q '$(DEP_$(1)_URL)' -O $$@
@ touch $$@
endef
DEP_LIST := SYSLINUX OVMF
DEP_SYSLINUX_VER = 6.03
DEP_SYSLINUX_URL = https://www.kernel.org/pub/linux/utils/boot/syslinux/6.xx/syslinux-6.03.zip
DEP_SYSLINUX_FILE = syslinux-$(DEP_SYSLINUX_VER).zip
DEP_OVMF_VER = 20180205
DEP_OVMF_URL = https://mirrors.edge.kernel.org/ubuntu/pool/universe/e/edk2/ovmf_0~20180205.c0d9813c-2_all.deb
DEP_OVMF_FILE = ovmf-$(DEP_OVMF_VER).deb
$(foreach d,$(DEP_LIST),$(eval $(call DOWN_RULE,$(d))))
bin/phoenixos: $(BIN)
@ mkdir -p $(dir $@)
$(QECHO) CP $@
$(Q) cp $^ $@
SYSLINUX_DEP_FILELIST := \
bios/core/isolinux.bin \
bios/com32/elflink/ldlinux/ldlinux.c32 \
bios/com32/lib/libcom32.c32 \
bios/com32/mboot/mboot.c32
SYSLINUX_FILELIST := $(notdir $(SYSLINUX_DEP_FILELIST))
ISOFILES := $(foreach f, $(SYSLINUX_FILELIST) phoenixos isolinux.cfg efiboot.img, $(ISOROOT)/$(f))
define SYSLINUX_EXTRACT
$(ISOROOT)/$(1): deps/$(DEP_SYSLINUX_FILE)
@ mkdir -p $$(dir $$@)
$(Q) unzip -q -u -j -o deps/$(DEP_SYSLINUX_FILE) -d $(ISOROOT) $(SYSLINUX_DEP_FILELIST)
@ touch $(foreach f, $(SYSLINUX_FILELIST), $(ISOROOT)/$(f))
endef
$(foreach f,$(SYSLINUX_FILELIST),$(eval $(call SYSLINUX_EXTRACT,$(f))))
$(ISOROOT)/phoenixos: $(BIN)
@ mkdir -p $(dir $@)
$(Q) cp $< $@
$(ISOROOT)/isolinux.cfg:
@ mkdir -p $(dir $@)
$(Q) echo 'default /mboot.c32 /phoenixos' > $@
$(ISOROOT)/efiboot.img: $(BIN)
@ mkdir -p $(dir $@)
$(Q) truncate -s 4m $@
$(Q) $(MKFAT) -t 1 -h 1 -s 8192 -v EFI -L 32 -i $@
$(Q) $(MMD) -i $@ ::efi
$(Q) $(MMD) -i $@ ::efi/boot
$(Q) $(MCOPY) -i $@ $(BIN) ::efi/boot/bootx64.efi
ISOOPTS := -quiet -U -A $(ISONAME) -V $(ISONAME) -volset $(ISONAME) -J -joliet-long -r
ISOOPTS += -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table
ISOOPTS += -eltorito-alt-boot -e efiboot.img -no-emul-boot
bin/phoenixos.iso: $(ISOFILES)
@ mkdir -p $(dir $@)
$(QECHO) ISO $@
@ rm -f $@
$(Q) $(MKISO) $(ISOOPTS) -o $@ $(ISOROOT)
.PHONY: images kernel iso
kernel: bin/phoenixos
iso: bin/phoenixos.iso
images: kernel iso
sinclude $(MAKEROOT)/toolchain.mk
sinclude $(MAKEROOT)/defs.mk
sinclude $(MAKEROOT)/common.mk
sinclude $(MAKEROOT)/deps.mk
sinclude $(MAKEROOT)/rules.mk
sinclude $(MAKEROOT)/images.mk
sinclude $(MAKEROOT)/utils.mk
KERNEL_DIRS := $(subst $(SRCDIR)/,,$(call SCANDIRS,$(SRCDIR),kernel.mk))
LIBRARY_DIRS := $(subst $(SRCDIR)/,,$(call SCANDIRS,$(SRCDIR),library.mk))
MODULE_DIRS := $(subst $(SRCDIR)/,,$(call SCANDIRS,$(SRCDIR),module.mk))
$(foreach dir,$(KERNEL_DIRS),$(eval $(call KERNRULES,$(dir))))
$(foreach dir,$(LIBRARY_DIRS),$(eval $(call LIBRULES,$(dir))))
$(foreach dir,$(MODULE_DIRS),$(eval $(call MODRULES,$(dir))))
CFLAGS += $(patsubst %,-I%,$(INCLUDES))
DEPS := $(foreach src,$(SOURCES),$(call DEPSRC,$(src)))
ifeq ($(filter clean,$(MAKECMDGOALS)),)
sinclude $(DEPS)
endif
$(OOBJDIR)/%.d: $(SRCDIR)/%.cpp
@ mkdir -p $(dir $@)
$(Q) $(CC) $(CFLAGS) -MM -MT $(call SRCOBJ,$^) -c $^ -o $@
@ touch $@
$(OOBJDIR)/%.d: $(SRCDIR)/%.s
@ mkdir -p $(dir $@)
@ touch $@
$(OOBJDIR)/%.o: $(SRCDIR)/%.cpp
@ mkdir -p $(dir $@)
$(QECHO) CC $(subst $(SRCDIR)/,,$<)
$(Q) $(CC) $(CFLAGS) -c $< -o $@
$(OOBJDIR)/%.o: $(SRCDIR)/%.s
@ mkdir -p $(dir $@)
$(QECHO) AS $(subst $(SRCDIR)/,,$<)
$(Q) $(CC) -c $< -o $@
$(BIN).elf: $(KERNOBJS) $(OOBJDIR)/modules-linked.o
@ mkdir -p $(dir $@)
$(QECHO) LD $(subst $(OIMGDIR)/,,$@)
$(Q) $(LD) $(LDFLAGS) -Tld/system.ld -o $@ $^
$(BIN).elf.strip: $(BIN).elf
$(Q) $(STRIP) -o $@ $^
$(BIN): $(BIN).elf.strip
@ mkdir -p $(dir $@)
$(QECHO) OC $(subst $(OIMGDIR)/,,$@)
$(Q) $(OBJCOPY) -Opei-x86-64 --subsystem efi-app --file-alignment 1 --section-alignment 1 $^ $@
$(OOBJDIR)/modules-linked.o: $(MODOBJS)
@ mkdir -p $(dir $@)
$(Q) cat $^ > $(@:.o=.b); echo -n ' ' >> $(@:.o=.b)
$(Q) $(OBJCOPY) -Oelf64-x86-64 -Bi386 -Ibinary --rename-section .data=.modules --set-section-flags .data=alloc,load,data,readonly $(@:.o=.b) $@
PREFIX=x86_64-linux-gnu-
NPROC=1
CLANG_BIN?=$(dir $(shell which clang))
CLANG_BIN?=/usr/bin
ifeq ($(OS),Windows_NT)
PREFIX=x86_64-w64-mingw32-
else
UNAME_S=$(shell uname -s)
ifeq ($(UNAME_S),Darwin)
PREFIX=x86_64-elf-
CLANG_BIN=/usr/local/opt/llvm/bin
NPROC=$(shell sysctl -n hw.ncpu)
else
NPROC=$(shell grep -c ^processor /proc/cpuinfo)
endif
endif
ifneq ($(PARALLEL),0)
MAKEFLAGS += "-j $(NPROC)"
endif
ifeq ($(VERBOSE),1)
Q=
QECHO=@ true
else
Q=@
QECHO=@ echo
endif
ifeq ($(wildcard $(CLANG_BIN)/clang),)
$(error CLANG not found in $(CLANG_BIN), make sure that it is installed and set CLANG_BIN environment variable)
endif
CC=$(CLANG_BIN)/clang --target=x86_64-none-elf
LD=$(CLANG_BIN)/ld.lld
AR=$(CLANG_BIN)/llvm-ar
OBJCOPY=$(PREFIX)objcopy
STRIP=$(PREFIX)strip
CLANG_VER=$(shell $(CLANG_BIN)/clang -v 2>&1 | head -n1 | perl -p -e 's/.*clang version (\d+)(\.\d+)*.*/$$1/g')
CLANG_5_GT=$(shell [ $(CLANG_VER) -gt 4 ] && echo true)
ifneq ($(CLANG_5_GT),true)
$(error CLANG v$(CLANG_VER) is not supported, use v5 or later)
endif
ifeq ($(UNAME_S),Darwin)
OBJCOPY=gobjcopy
endif
QEMU=qemu-system-x86_64
ifneq ($(shell which cpplint),)
LINT=$(shell which cpplint) --quiet
else
LINT=@ sh -c "echo No lint found"; true
endif
ifneq ($(shell which xorriso),)
MKISO := $(shell which xorriso) -as mkisofs
else
ifneq ($(shell which mkisofs),)
MKISO := $(shell which mkisofs)
else
ifneq ($(shell which genisoimage),)
MKISO := $(shell which genisoimage)
else
MKISO=@ sh -c "echo Neither xorriso nor mkisofs nor genisoimage was found"; false
endif
endif
endif
ifneq ($(shell which mformat),)
MKFAT := $(shell which mformat)
else
MKFAT := @ sh -c "echo mformat not found"; false
endif
ifneq ($(shell which mcopy),)
MCOPY := $(shell which mcopy)
else
MCOPY := @ sh -c "echo mcopy not found"; false
endif
ifneq ($(shell which mmd),)
MMD := $(shell which mmd)
else
MMD := @ sh -c "echo mmd not found"; false
endif
EFIBIOS=$(ODIR)/bios/OVMF.fd
EFIROOT=$(ODIR)/efi
EFIKERN=$(EFIROOT)/efi/boot/bootx64.efi
.PHONY: clean check launch launch-efi
clean:
$(QECHO) RM $(ODIR) bin
$(Q) rm -rf $(ODIR) bin
CHECKSRCS := $(filter %.cpp,$(SOURCES))
CHECKHDRS := $(foreach i,$(INCLUDES),$(wildcard $(i)/*.hpp))
$(ODIR)/check-report.txt: $(CHECKSRCS) $(CHECKHDRS)
$(Q) $(LINT) $^ > $@ || rm $@
check: $(ODIR)/check-report.txt
@ [ -f $< ] && cat $<
all: check
$(EFIBIOS): deps/$(DEP_OVMF_FILE)
@ mkdir -p $(dir $@)
$(Q) tar xOf deps/$(DEP_OVMF_FILE) data.tar.xz | tar xO './usr/share/ovmf/OVMF.fd' > $@
$(EFIKERN): $(BIN)
@ mkdir -p $(dir $@)
$(Q) cp $< $@
launch: $(BIN)
$(QEMU) -kernel $< -smp cores=2,threads=2 -cpu Broadwell -serial stdio
launch-efi: $(EFIKERN) $(EFIBIOS)
$(QEMU) -drive file=fat:rw:$(EFIROOT),format=raw,media=disk -smp cores=2,threads=2 -cpu Broadwell -bios $(EFIBIOS) -serial stdio
......@@ -113,25 +113,31 @@ multiboot_entry:
mov %eax, %cr0
# Fill pagetable
lea __pagetable__-_start(%ebp), %edi
lea -0x203000+_start(%ebp), %edi
mov %edi, %cr3
xor %eax, %eax
mov $0x1C00, %ecx
mov $0x400, %ecx
rep stosl
mov %cr3, %edi
lea __pagetable__-_start+0x1007(%ebp), %esi
mov %esi, 0x0000(%edi)
add $0x1000, %esi; mov %esi, 0x1000(%edi)
add $0x1000, %esi; mov %esi, 0x2000(%edi)
add $0x1000, %esi; mov %esi, 0x2008(%edi)
add $0x1000, %esi; mov %esi, 0x2010(%edi)
add $0x1000, %esi; mov %esi, 0x2018(%edi)
lea -0x203000+0x3+_start(%ebp), %esi
add $0x3000, %edi
add $0x1000, %esi
mov %esi, 0x0000(%edi)
add $0x1000, %esi
mov %esi, 0x1000(%edi)
mov $0x00000007, %ebx
mov $0x800, %ecx
mov $0x200, %ecx
1:
add $0x1000, %esi
mov %esi, 0x2000(%edi)
add $8, %edi
loop 1b
add $0x2000, %edi
mov $0x00000003, %ebx
mov $0x1000, %ecx
1:
mov %ebx, (%edi)
add $0x1000, %ebx
......@@ -204,6 +210,7 @@ _efi_start: # EFI
x64_entry:
call reloc_vtables
call static_init
xor %rbp, %rbp
call _ZN9Pagetable4initEv
call _ZN7Display5setupEv
call _ZN10Interrupts4initEv
......
......@@ -4,7 +4,9 @@
#include "kernlib.hpp"
#include "efi.hpp"
const EFI_SYSTEM_TABLE *EFI::SystemTable = 0;
const void *EFI::ImageHandle = 0;
const EFI_SYSTEM_TABLE *EFI::getSystemTable() { return SystemTable; }
namespace EFI {
const struct EFI::SystemTable *SystemTable = 0;
const void *ImageHandle = 0;
}
const struct EFI::SystemTable *EFI::getSystemTable() { return SystemTable; }
const void *EFI::getImageHandle() { return ImageHandle; }
......@@ -6,300 +6,335 @@
#define EFIAPI __attribute__((ms_abi))
enum EFI_STATUS: uint64_t {
EFI_SUCCESS = 0,
EFI_ERROR = 0x8000000000000000LL,
EFI_LOAD_ERROR = EFI_ERROR | 1,
EFI_INVALID_PARAMETER = EFI_ERROR | 2,
EFI_UNSUPPORTED = EFI_ERROR | 3,
EFI_BAD_BUFFER_SIZE = EFI_ERROR | 4,
EFI_BUFFER_TOO_SMALL = EFI_ERROR | 5,
EFI_NOT_READY = EFI_ERROR | 6,
EFI_DEVICE_ERROR = EFI_ERROR | 7,
EFI_WRITE_PROTECTED = EFI_ERROR | 8,
EFI_OUT_OF_RESOURCES = EFI_ERROR | 9,
EFI_VOLUME_CORRUPTED = EFI_ERROR | 10,
EFI_VOLUME_FULL = EFI_ERROR | 11,
EFI_NO_MEDIA = EFI_ERROR | 12,
EFI_MEDIA_CHANGED = EFI_ERROR | 13,
EFI_NOT_FOUND = EFI_ERROR | 14,
EFI_ACCESS_DENIED = EFI_ERROR | 15,
EFI_NO_RESPONSE = EFI_ERROR | 16,
EFI_NO_MAPPING = EFI_ERROR | 17,
EFI_TIMEOUT = EFI_ERROR | 18,
EFI_NOT_STARTED = EFI_ERROR | 19,
EFI_ALREADY_STARTED = EFI_ERROR | 20,
EFI_ABORTED = EFI_ERROR | 21,
EFI_ICMP_ERROR = EFI_ERROR | 22,
EFI_TFTP_ERROR = EFI_ERROR | 23,
EFI_PROTOCOL_ERROR = EFI_ERROR | 24
};
static const uint64_t EFI_SYSTEM_TABLE_SIGNATURE = 0x4942492053595354LL;
enum EFI_COLOR {
EFI_COLOR_BLACK = 0x0,
EFI_COLOR_BLUE = 0x1,
EFI_COLOR_GREEN = 0x2,
EFI_COLOR_CYAN = (EFI_COLOR_BLUE | EFI_COLOR_GREEN),
EFI_COLOR_RED = 0x4,
EFI_COLOR_MAGENTA = (EFI_COLOR_RED | EFI_COLOR_BLUE),
EFI_COLOR_BROWN = (EFI_COLOR_RED | EFI_COLOR_GREEN),
EFI_COLOR_LIGHTGRAY = (EFI_COLOR_RED | EFI_COLOR_GREEN | EFI_COLOR_BLUE),
EFI_COLOR_BRIGHT = 0x8,
EFI_COLOR_DARKGRAY = (EFI_COLOR_BRIGHT),
EFI_COLOR_LIGHTBLUE = (EFI_COLOR_BLUE | EFI_COLOR_BRIGHT),
EFI_COLOR_LIGHTGREEN = (EFI_COLOR_GREEN | EFI_COLOR_BRIGHT),
EFI_COLOR_LIGHTCYAN = (EFI_COLOR_CYAN | EFI_COLOR_BRIGHT),
EFI_COLOR_LIGHTRED = (EFI_COLOR_RED | EFI_COLOR_BRIGHT),
EFI_COLOR_LIGHTMAGENTA = (EFI_COLOR_MAGENTA | EFI_COLOR_BRIGHT),
EFI_COLOR_YELLOW = (EFI_COLOR_BROWN | EFI_COLOR_BRIGHT),
EFI_COLOR_WHITE = (EFI_COLOR_LIGHTGRAY | EFI_COLOR_BRIGHT),
};
enum EFI_RESET_TYPE {
EfiResetCold,
EfiResetWarm,
EfiResetShutdown
};
enum EFI_TPL {
EFI_TPL_APPLICATION = 4,
EFI_TPL_CALLBACK = 8,
EFI_TPL_NOTIFY = 16,
EFI_TPL_HIGH_LEVEL = 31
};
enum EFI_MEMORY_TYPE: uint32_t {
EFI_MEMORY_TYPE_RESERVED,
EFI_MEMORY_TYPE_LOADER,
EFI_MEMORY_TYPE_DATA,
EFI_MEMORY_TYPE_BS_CODE,
EFI_MEMORY_TYPE_BS_DATA,
EFI_MEMORY_TYPE_RS_CODE,
EFI_MEMORY_TYPE_RS_DATA,
EFI_MEMORY_TYPE_CONVENTIONAL,
EFI_MEMORY_TYPE_UNUSABLE,
EFI_MEMORY_TYPE_ACPI_RECLAIM,
EFI_MEMORY_TYPE_ACPI_NVS,
EFI_MEMORY_TYPE_MAPPED_IO,
EFI_MEMORY_TYPE_MAPPED_IO_PORTSPACE,
EFI_MEMORY_TYPE_PAL_CODE
};
enum EFI_MEMORY_ATTR: uint64_t {
EFI_MEMORY_UC = 0x01,
EFI_MEMORY_WC = 0x02,
EFI_MEMORY_WT = 0x04,
EFI_MEMORY_WB = 0x08,
EFI_MEMORY_UCE = 0x10,
EFI_MEMORY_WP = 0x1000,
EFI_MEMORY_RP = 0x2000,
EFI_MEMORY_XP = 0x4000,
EFI_MEMORY_RUNTIME = 0x8000000000000000L
};
enum EFI_ALLOCATE_TYPE {
EFI_ALLOCATE_TYPE_ANY,
EFI_ALLOCATE_TYPE_MAX,
EFI_ALLOCATE_TYPE_ADDR
};
struct EFI_TABLE_HEADER {
uint64_t Signature;
uint32_t Revision;
uint32_t HeaderSize;
uint32_t CRC32;
uint32_t Reserved;
};
struct EFI_GUID {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint16_t Data4;
uint64_t Data5:48;
};
struct EFI_MEMORY_DESCRIPTOR {
EFI_MEMORY_TYPE Type;
uint32_t Pad;
uint64_t PhysicalStart;
uint64_t VirtualStart;
uint64_t NumberOfPages;
EFI_MEMORY_ATTR Attribute;
};
union EFI_TEXT_ATTR {
struct {
EFI_COLOR foreground:4;
EFI_COLOR background:4;
namespace EFI {
struct GUID {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint16_t Data4;
uint64_t Data5:48;
};
static const constexpr uint64_t SystemHandleSignature = 0x4942492053595354LL;
static const constexpr GUID GUID_ConfigTableACPI1 = { 0xEB9D2D30, 0x2D88, 0x11D3, 0x169A, 0x4DC13F279000 };
static const constexpr GUID GUID_ConfigTableACPI2 = { 0x8868E871, 0xE4F1, 0x11D3, 0x22BC, 0x81883CC78000 };
static const constexpr GUID GUID_LoadedImageProtocol = { 0x5B1B31A1, 0x9562, 0x11d2, 0x3F8E, 0x3B7269C9A000 };
static const constexpr GUID GUID_GraphicsOutputProtocol = { 0x9042A9DE, 0x23DC, 0x4A38, 0xFB96, 0x6A5180D0DE7A };
enum Status: uint64_t {
SUCCESS = 0,
ERROR = 0x8000000000000000LL,
LOAD_ERROR = ERROR | 1,
INVALID_PARAMETER = ERROR | 2,
UNSUPPORTED = ERROR | 3,
BAD_BUFFER_SIZE = ERROR | 4,
BUFFER_TOO_SMALL = ERROR | 5,
NOT_READY = ERROR | 6,
DEVICE_ERROR = ERROR | 7,
WRITE_PROTECTED = ERROR | 8,
OUT_OF_RESOURCES = ERROR | 9,
VOLUME_CORRUPTED = ERROR | 10,
VOLUME_FULL = ERROR | 11,
NO_MEDIA = ERROR | 12,
MEDIA_CHANGED = ERROR | 13,
NOT_FOUND = ERROR | 14,
ACCESS_DENIED = ERROR | 15,
NO_RESPONSE = ERROR | 16,
NO_MAPPING = ERROR | 17,
TIMEOUT = ERROR | 18,
NOT_STARTED = ERROR | 19,
ALREADY_STARTED = ERROR | 20,
ABORTED = ERROR | 21,
ICMP_ERROR = ERROR | 22,
TFTP_ERROR = ERROR | 23,
PROTOCOL_ERROR = ERROR | 24
};
enum Color {
COLOR_BLACK = 0x0,
COLOR_BLUE = 0x1,
COLOR_GREEN = 0x2,
COLOR_CYAN = (COLOR_BLUE | COLOR_GREEN),
COLOR_RED = 0x4,
COLOR_MAGENTA = (COLOR_RED | COLOR_BLUE),
COLOR_BROWN = (COLOR_RED | COLOR_GREEN),
COLOR_LIGHTGRAY = (COLOR_RED | COLOR_GREEN | COLOR_BLUE),
COLOR_BRIGHT = 0x8,
COLOR_DARKGRAY = (COLOR_BRIGHT),
COLOR_LIGHTBLUE = (COLOR_BLUE | COLOR_BRIGHT),
COLOR_LIGHTGREEN = (COLOR_GREEN | COLOR_BRIGHT),
COLOR_LIGHTCYAN = (COLOR_CYAN | COLOR_BRIGHT),
COLOR_LIGHTRED = (COLOR_RED | COLOR_BRIGHT),
COLOR_LIGHTMAGENTA = (COLOR_MAGENTA | COLOR_BRIGHT),
COLOR_YELLOW = (COLOR_BROWN | COLOR_BRIGHT),
COLOR_WHITE = (COLOR_LIGHTGRAY | COLOR_BRIGHT),
};
enum ResetType {
RESET_COLD,
RESET_WARM,
RESET_SHUTDOWN
};
enum TPL {
TPL_APPLICATION = 4,
TPL_CALLBACK = 8,
TPL_NOTIFY = 16,
TPL_HIGH_LEVEL = 31
};
enum MemoryType: uint32_t {
MEMORY_TYPE_RESERVED,
MEMORY_TYPE_LOADER,
MEMORY_TYPE_DATA,
MEMORY_TYPE_BS_CODE,
MEMORY_TYPE_BS_DATA,
MEMORY_TYPE_RS_CODE,
MEMORY_TYPE_RS_DATA,
MEMORY_TYPE_CONVENTIONAL,
MEMORY_TYPE_UNUSABLE,
MEMORY_TYPE_ACPI_RECLAIM,
MEMORY_TYPE_ACPI_NVS,
MEMORY_TYPE_MAPPED_IO,
MEMORY_TYPE_MAPPED_IO_PORTSPACE,
MEMORY_TYPE_PAL_CODE
};
enum MemoryAttr: uint64_t {
MEMORY_UC = 0x01,
MEMORY_WC = 0x02,
MEMORY_WT = 0x04,
MEMORY_WB = 0x08,
MEMORY_UCE = 0x10,
MEMORY_WP = 0x1000,
MEMORY_RP = 0x2000,
MEMORY_XP = 0x4000,
MEMORY_RUNTIME = 0x8000000000000000L
};
enum AllocateType {
ALLOCATE_TYPE_ANY,
ALLOCATE_TYPE_MAX,
ALLOCATE_TYPE_ADDR
};
enum GraphicsPixelFormat: uint32_t {
GRAPHICS_PIXEL_FORMAT_RGBX_8BPP,
GRAPHICS_PIXEL_FORMAT_BGRX_8BPP,
GRAPHICS_PIXEL_FORMAT_BITMASK,
GRAPHICS_PIXEL_FORMAT_BLTONLY
};
struct TableHeader {
uint64_t Signature;
uint32_t Revision;
uint32_t HeaderSize;
uint32_t CRC32;
uint32_t Reserved;
};
struct MemoryDescriptor {
MemoryType Type;
uint32_t Pad;
uint64_t PhysicalStart;
uint64_t VirtualStart;
uint64_t NumberOfPages;
MemoryAttr Attribute;
};
union TextAttr {
struct {
Color foreground:4;
Color background:4;
} PACKED;
uint8_t raw;
} PACKED;
uint8_t raw;
} PACKED;
struct EFI_SIMPLE_TEXT_OUTPUT_MODE {
uint32_t MaxMode;
uint32_t Mode;
uint32_t Attribute;
uint32_t CursorColumn;
uint32_t CursorRow;
bool CursorVisible;
};
struct EFI_TIME {
uint16_t Year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t pad1;
uint32_t nanosecond;
int16_t timezone;
uint8_t daylight;
uint8_t pad2;
};
struct EFI_TIME_CAPABILITIES {
uint32_t Resolution;
uint32_t Accuracy;
bool SetsToZero;
};
struct EFI_INPUT_KEY {
uint16_t Scancode;
wchar_t UnicodeChar;
};
struct EFI_SIMPLE_TEXT_OUTPUT_INTERFACE {
EFI_STATUS EFIAPI(*const Reset)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, bool ExtendedVerification);
EFI_STATUS EFIAPI(*const OutputString)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, const wchar_t *string);
EFI_STATUS EFIAPI(*const TestString)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, const wchar_t *string);
EFI_STATUS EFIAPI(*const QueryMode)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, uint64_t ModeNumber,
uint64_t *cols, uint64_t *rows);
EFI_STATUS EFIAPI(*const SetMode)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, uint64_t ModeNumber);
EFI_STATUS EFIAPI(*const SetAttribute)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, EFI_TEXT_ATTR Attribute);
EFI_STATUS EFIAPI(*const ClearScreen)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self);
EFI_STATUS EFIAPI(*const SetCursorPosition)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self,
uint64_t column, uint64_t row);
EFI_STATUS EFIAPI(*const EnableCursor)(
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *self, bool enable);
const EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
};
struct EFI_SIMPLE_INPUT_INTERFACE {
EFI_STATUS EFIAPI(*const Reset)(
const EFI_SIMPLE_INPUT_INTERFACE *self, bool ExtendedVerification);
EFI_STATUS EFIAPI(*const ReadKeyStroke)(
const EFI_SIMPLE_INPUT_INTERFACE *self, EFI_INPUT_KEY *key);
const void *WaitForKey;
};
struct EFI_BOOT_SERVICES_TABLE {
EFI_TABLE_HEADER Hdr;
EFI_STATUS EFIAPI(*const RaisePriority)(EFI_TPL NewTpl);
EFI_STATUS EFIAPI(*const RestorePriority)(EFI_TPL OldTpl);
EFI_STATUS EFIAPI(*const AllocatePages)(
EFI_ALLOCATE_TYPE Type, EFI_MEMORY_TYPE MemoryType, uint64_t NoPages,
void **Address);
EFI_STATUS EFIAPI(*const FreePages)(void *pages, uint64_t NoPages);
EFI_STATUS EFIAPI(*const GetMemoryMap)(
uint64_t *MemoryMapSize, EFI_MEMORY_DESCRIPTOR *MemoryMap,
uint64_t *MapKey, uint64_t *DescriptorSize, uint32_t *DescriptorVersion);
const void *AllocatePool;
const void *FreePool;
const void *CreateEvent;
const void *SetTimer;
const void *WaitForEvent;
const void *SignalEvent;
const void *CloseEvent;
const void *CheckEvent;
const void *InstallProtocolInterface;
const void *ReInstallProtocolInterface;
const void *UnInstallProtocolInterface;
EFI_STATUS EFIAPI(*const HandleProtocol)(
const void *Handle, const EFI_GUID *Protocol, void **Interface);
const void *PCHandleProtocol;
const void *RegisterProtocolNotify;
const void *LocateHandle;
const void *LocateDevicePath;
const void *InstallConfigurationTable;
const void *ImageLoad;
const void *ImageStart;
EFI_STATUS EFIAPI(*const Exit)(
void *ImageHandle, EFI_STATUS ImageStatus,
uint64_t ExitDataSize, const wchar_t *ExitData);
const void *ImageUnLoad;
EFI_STATUS EFIAPI(*const ExitBootServices)(
const void *ImageHandle, uint64_t MapKey);
EFI_STATUS EFIAPI(*const GetNextMonotonicCount)(uint64_t *Count);
EFI_STATUS EFIAPI(*const Stall)(uint64_t Microseconds);
EFI_STATUS EFIAPI(*const SetWatchdogTimer)(
uint64_t Timeout, uint64_t WatchdogCode, uint64_t DataSize,
const wchar_t *WatchdogData);
const void *ConnectController;
const void *DisConnectController;
const void *OpenProtocol;
const void *CloseProtocol;
const void *OpenProtocolInformation;
const void *ProtocolsPerHandle;
const void *LocateHandleBuffer;
EFI_STATUS EFIAPI(*const LocateProtocol)(
const EFI_GUID *Protocol, const void *Registration, void **Interface);
const void *InstallMultipleProtocolInterfaces;
const void *UnInstallMultipleProtocolInterfaces;
EFI_STATUS EFIAPI(*const CalculateCrc32)(
const void *Data, uint64_t DataSize, uint32_t *Crc32);
EFI_STATUS EFIAPI(*const CopyMem)(
void *Destination, const void *Source, uint64_t Length);
EFI_STATUS EFIAPI(*const SetMem)(
void *Buffer, uint64_t Size, uint8_t Value);
const void *CreateEventEx;
};
struct EFI_RUNTIME_SERVICES_TABLE {
EFI_TABLE_HEADER Hdr;
EFI_STATUS EFIAPI(*const GetTime)(
EFI_TIME *Time, EFI_TIME_CAPABILITIES *Capabilities);
EFI_STATUS EFIAPI(*const SetTime)(EFI_TIME *Time);
EFI_STATUS EFIAPI(*const GetWakeUpTime)(
bool *Enabled, bool *Pending, EFI_TIME *Time);
EFI_STATUS EFIAPI(*const SetWakeUpTime)(bool Enabled, EFI_TIME *Time);
EFI_STATUS EFIAPI(*const SetVirtualAddressMap)(
uint64_t MemoryMapSize, uint64_t DescriptorSize,
uint32_t DescriptorVersion, EFI_MEMORY_DESCRIPTOR *VirtualMap);
EFI_STATUS EFIAPI(*const ConvertPointer)(
uint64_t DebugDisposition, void **Address);
EFI_STATUS EFIAPI(*const GetVariable)(
const wchar_t *VariableName, EFI_GUID *VendorGuid, uint32_t *Attributes,
uint64_t *DataSize, void *Data);
EFI_STATUS EFIAPI(*const GetNextVariableName)(
uint64_t VariableNameSize, wchar_t *VariableName, EFI_GUID *VendorGuid);
EFI_STATUS EFIAPI(*const SetVariable)(
const wchar_t *VariableName, EFI_GUID *VendorGuid, uint32_t Attributes,
uint64_t DataSize, const void *Data);
EFI_STATUS EFIAPI(*const GetNextHighMonoCount)(uint32_t *HighCount);
EFI_STATUS EFIAPI(*const ResetSystem)(
EFI_RESET_TYPE ResetType, EFI_STATUS ResetStatus, uint64_t DataSize,
const wchar_t *ResetData);
};
struct EFI_CONFIGURATION_TABLE {
EFI_GUID VendorGuid;
const void *VendorTable;
};
static inline bool operator ==(const EFI_GUID lhs, const EFI_GUID rhs) {
struct SimpleTextOutputMode {
uint32_t MaxMode;
uint32_t Mode;
uint32_t Attribute;
uint32_t CursorColumn;
uint32_t CursorRow;
bool CursorVisible;
};
struct Time {
uint16_t Year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t pad1;
uint32_t nanosecond;
int16_t timezone;
uint8_t daylight;
uint8_t pad2;
};
struct TimeCapabilities {
uint32_t Resolution;
uint32_t Accuracy;
bool SetsToZero;
};
struct InputKey {
uint16_t Scancode;
wchar_t UnicodeChar;
};
struct SimpleTextOutputInterface {
Status EFIAPI(*const Reset)(const SimpleTextOutputInterface *self, bool ExtendedVerification);
Status EFIAPI(*const OutputString)(const SimpleTextOutputInterface *self, const wchar_t *string);
Status EFIAPI(*const TestString)(const SimpleTextOutputInterface *self, const wchar_t *string);
Status EFIAPI(*const QueryMode)(
const SimpleTextOutputInterface *self, uint64_t ModeNumber, uint64_t *cols, uint64_t *rows);
Status EFIAPI(*const SetMode)(const SimpleTextOutputInterface *self, uint64_t ModeNumber);
Status EFIAPI(*const SetAttribute)(const SimpleTextOutputInterface *self, TextAttr Attribute);
Status EFIAPI(*const ClearScreen)(const SimpleTextOutputInterface *self);
Status EFIAPI(*const SetCursorPosition)(const SimpleTextOutputInterface *self, uint64_t column, uint64_t row);
Status EFIAPI(*const EnableCursor)(const SimpleTextOutputInterface *self, bool enable);
const SimpleTextOutputMode *Mode;
};
struct SimpleInputInterface {
Status EFIAPI(*const Reset)(const SimpleInputInterface *self, bool ExtendedVerification);
Status EFIAPI(*const ReadKeyStroke)(const SimpleInputInterface *self, InputKey *key);
const void *WaitForKey;
};
struct BootServicesTable {
TableHeader Hdr;
Status EFIAPI(*const RaisePriority)(TPL NewTpl);
Status EFIAPI(*const RestorePriority)(TPL OldTpl);
Status EFIAPI(*const AllocatePages)(AllocateType Type, MemoryType MemoryType, uint64_t NoPages, void **Address);
Status EFIAPI(*const FreePages)(void *pages, uint64_t NoPages);
Status EFIAPI(*const GetMemoryMap)(
uint64_t *MemoryMapSize, MemoryDescriptor *MemoryMap, uint64_t *MapKey, uint64_t *DescriptorSize,
uint32_t *DescriptorVersion);
const void *AllocatePool;
const void *FreePool;
const void *CreateEvent;
const void *SetTimer;
const void *WaitForEvent;
const void *SignalEvent;
const void *CloseEvent;
const void *CheckEvent;
const void *InstallProtocolInterface;
const void *ReInstallProtocolInterface;
const void *UnInstallProtocolInterface;
Status EFIAPI(*const HandleProtocol)(const void *Handle, const GUID *Protocol, void **Interface);
const void *PCHandleProtocol;
const void *RegisterProtocolNotify;
const void *LocateHandle;
const void *LocateDevicePath;
const void *InstallConfigurationTable;
const void *ImageLoad;
const void *ImageStart;
Status EFIAPI(*const Exit)(void *ImageHandle, Status ImageStatus, uint64_t ExitDataSize, const wchar_t *ExitData);
const void *ImageUnLoad;
Status EFIAPI(*const ExitBootServices)(const void *ImageHandle, uint64_t MapKey);
Status EFIAPI(*const GetNextMonotonicCount)(uint64_t *Count);
Status EFIAPI(*const Stall)(uint64_t Microseconds);
Status EFIAPI(*const SetWatchdogTimer)(
uint64_t Timeout, uint64_t WatchdogCode, uint64_t DataSize, const wchar_t *WatchdogData);
const void *ConnectController;
const void *DisConnectController;
const void *OpenProtocol;
const void *CloseProtocol;
const void *OpenProtocolInformation;
const void *ProtocolsPerHandle;
const void *LocateHandleBuffer;
Status EFIAPI(*const LocateProtocol)(const GUID *Protocol, const void *Registration, void **Interface);
const void *InstallMultipleProtocolInterfaces;
const void *UnInstallMultipleProtocolInterfaces;
Status EFIAPI(*const CalculateCrc32)(const void *Data, uint64_t DataSize, uint32_t *Crc32);
Status EFIAPI(*const CopyMem)(void *Destination, const void *Source, uint64_t Length);
Status EFIAPI(*const SetMem)(void *Buffer, uint64_t Size, uint8_t Value);
const void *CreateEventEx;
};
struct RuntimeServicesTable {
TableHeader Hdr;
Status EFIAPI(*const GetTime)(Time *Time, TimeCapabilities *Capabilities);
Status EFIAPI(*const SetTime)(Time *Time);
Status EFIAPI(*const GetWakeUpTime)(bool *Enabled, bool *Pending, Time *Time);
Status EFIAPI(*const SetWakeUpTime)(bool Enabled, Time *Time);
Status EFIAPI(*const SetVirtualAddressMap)(
uint64_t MemoryMapSize, uint64_t DescriptorSize, uint32_t DescriptorVersion, MemoryDescriptor *VirtualMap);
Status EFIAPI(*const ConvertPointer)(uint64_t DebugDisposition, void **Address);
Status EFIAPI(*const GetVariable)(
const wchar_t *VariableName, GUID *VendorGuid, uint32_t *Attributes, uint64_t *DataSize, void *Data);
Status EFIAPI(*const GetNextVariableName)(uint64_t VariableNameSize, wchar_t *VariableName, GUID *VendorGuid);
Status EFIAPI(*const SetVariable)(
const wchar_t *VariableName, GUID *VendorGuid, uint32_t Attributes, uint64_t DataSize, const void *Data);
Status EFIAPI(*const GetNextHighMonoCount)(uint32_t *HighCount);
Status EFIAPI(*const ResetSystem)(
ResetType ResetType, Status ResetStatus, uint64_t DataSize, const wchar_t *ResetData);
};
struct ConfigurationTable {
GUID VendorGuid;
const void *VendorTable;
};
struct SystemTable {
TableHeader Hdr;
const wchar_t *FirmwareVendor;
uint32_t FirmwareRevision;
const void *ConsoleInHandle;
const SimpleInputInterface *ConIn;
const void *ConsoleOutHandle;
const SimpleTextOutputInterface *ConOut;
const void *StandardErrorHandle;
const SimpleTextOutputInterface *StdErr;
const RuntimeServicesTable *RuntimeServices;
const BootServicesTable *BootServices;
uint64_t NumberOfTableEntries;
const ConfigurationTable *ConfigurationTable;
};
struct LoadedImage {
uint32_t Revision;
void *ParentHandle;
SystemTable *SystemTable;
void *DeviceHandle;
wchar_t *FilePath;
void *Reserved;
uint32_t LoadOptionsSize;
void *LoadOptions;
void *ImageBase;
uint64_t ImageSize;
MemoryType ImageCodeType;
MemoryType ImageDataType;
Status EFIAPI(*const Unload)(const void *ImageHandle);
};
struct PixelBitmask {
uint32_t RedMask;
uint32_t GreenMask;
uint32_t BlueMask;
uint32_t ReservedMask;
};
struct GraphicsOutputModeInformation {
uint32_t Version;
uint32_t HorizontalResolution;
uint32_t VerticalResolution;
GraphicsPixelFormat PixelFormat;
PixelBitmask PixelInformation;
uint32_t PixelsPerScanLine;
};
struct GraphicsOutputProtocolMode {
uint32_t MaxMode;
uint32_t Mode;
GraphicsOutputModeInformation *Info;
uint64_t SizeOfInfo;
void *FrameBufferBase;
uint64_t FrameBufferSize;
};
struct GraphicsOutput {
Status EFIAPI(*const QueryMode)(
GraphicsOutput *This, uint32_t ModeNumber, uint64_t *SizeOfInfo, GraphicsOutputModeInformation **Info);
Status EFIAPI(*const SetMode)(GraphicsOutput *This, uint32_t ModeNumber);
const void *Blt;
GraphicsOutputProtocolMode *Mode;
};
const struct SystemTable *getSystemTable() PURE;
const void *getImageHandle() PURE;
}; // namespace EFI
static inline bool operator ==(const EFI::GUID &lhs, const EFI::GUID &rhs) {
return
lhs.Data1 == rhs.Data1 &&
lhs.Data2 == rhs.Data2 &&
......@@ -307,102 +342,4 @@ static inline bool operator ==(const EFI_GUID lhs, const EFI_GUID rhs) {
lhs.Data4 == rhs.Data4 &&
lhs.Data5 == rhs.Data5;
}
static const EFI_GUID EFI_CONF_TABLE_GUID_ACPI1 =
{ 0xEB9D2D30, 0x2D88, 0x11D3, 0x169A, 0x4DC13F279000 };
static const EFI_GUID EFI_CONF_TABLE_GUID_ACPI2 =
{ 0x8868E871, 0xE4F1, 0x11D3, 0x22BC, 0x81883CC78000 };
static const EFI_GUID EFI_LOADED_IMAGE_PROTOCOL =
{ 0x5B1B31A1, 0x9562, 0x11d2, 0x3F8E, 0x3B7269C9A000 };
static const EFI_GUID EFI_GRAPHICS_OUTPUT_PROTOCOL =
{ 0x9042A9DE, 0x23DC, 0x4A38, 0xFB96, 0x6A5180D0DE7A };
struct EFI_SYSTEM_TABLE {
EFI_TABLE_HEADER Hdr;
const wchar_t *FirmwareVendor;
uint32_t FirmwareRevision;
const void *ConsoleInHandle;
const EFI_SIMPLE_INPUT_INTERFACE *ConIn;
const void *ConsoleOutHandle;
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
const void *StandardErrorHandle;
const EFI_SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
const EFI_RUNTIME_SERVICES_TABLE *RuntimeServices;
const EFI_BOOT_SERVICES_TABLE *BootServices;
uint64_t NumberOfTableEntries;
const EFI_CONFIGURATION_TABLE *ConfigurationTable;
};
struct EFI_LOADED_IMAGE {
uint32_t Revision;
void *ParentHandle;
EFI_SYSTEM_TABLE *SystemTable;
void *DeviceHandle;
wchar_t *FilePath;
void *Reserved;
uint32_t LoadOptionsSize;
void *LoadOptions;
void *ImageBase;
uint64_t ImageSize;
EFI_MEMORY_TYPE ImageCodeType;
EFI_MEMORY_TYPE ImageDataType;
EFI_STATUS EFIAPI(*const Unload)(const void *ImageHandle);
};
struct EFI_PIXEL_BITMASK {
uint32_t RedMask;
uint32_t GreenMask;
uint32_t BlueMask;
uint32_t ReservedMask;
};
enum EFI_GRAPHICS_PIXEL_FORMAT: uint32_t {
EFI_GRAPHICS_PIXEL_FORMAT_RGBX_8BPP,
EFI_GRAPHICS_PIXEL_FORMAT_BGRX_8BPP,
EFI_GRAPHICS_PIXEL_FORMAT_BITMASK,
EFI_GRAPHICS_PIXEL_FORMAT_BLTONLY
};
struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION {
uint32_t Version;
uint32_t HorizontalResolution;
uint32_t VerticalResolution;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
EFI_PIXEL_BITMASK PixelInformation;
uint32_t PixelsPerScanLine;
};
struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE {
uint32_t MaxMode;
uint32_t Mode;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
uint64_t SizeOfInfo;
void *FrameBufferBase;
uint64_t FrameBufferSize;
};
struct EFI_GRAPHICS_OUTPUT {
EFI_STATUS EFIAPI(*const QueryMode)(
EFI_GRAPHICS_OUTPUT *This, uint32_t ModeNumber,
uint64_t *SizeOfInfo, EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info);
EFI_STATUS EFIAPI(*const SetMode)(
EFI_GRAPHICS_OUTPUT *This, uint32_t ModeNumber);
const void *Blt;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
};
class EFI {
private:
static const EFI_SYSTEM_TABLE *SystemTable;
static const void *ImageHandle;
public:
static const EFI_SYSTEM_TABLE *getSystemTable() PURE;
static const void *getImageHandle() PURE;
};
#undef EFIAPI
......@@ -4,55 +4,54 @@
#pragma once
#include "kernlib.hpp"
enum MUTLIBOOT_FLAGS: uint32_t {
MB_FLAG_MEM = (1 << 0),
MB_FLAG_BOOTDEV = (1 << 1),
MB_FLAG_CMDLINE = (1 << 2),
MB_FLAG_MODS = (1 << 3),
MB_FLAG_SYMTAB = (1 << 4),
MB_FLAG_ELFSYMTAB = (1 << 5),
MB_FLAG_MEMMAP = (1 << 6),
MB_FLAG_DRIVEMAP = (1 << 7),
MB_FLAG_CONFTAB = (1 << 8),
MB_FLAG_BLNAME = (1 << 9),
MB_FLAG_APMTAB = (1 << 10),
MB_FLAG_VBETAB = (1 << 11)
};
struct MULTIBOOT_PAYLOAD {
MUTLIBOOT_FLAGS flags;
size_t mem_lower:32, mem_upper:32;
uint32_t boot_device;