...
 
Commits (10)
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}")
# 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
)
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)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
set(CMAKE_LINKER ${CROSS_LLVM_PATH}/ld.lld)
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})
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})
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
......
......@@ -299,7 +299,7 @@ struct EFI_CONFIGURATION_TABLE {
const void *VendorTable;
};
static inline bool operator ==(const EFI_GUID lhs, const EFI_GUID rhs) {
static inline bool operator ==(const EFI_GUID &lhs, const EFI_GUID &rhs) {
return
lhs.Data1 == rhs.Data1 &&
lhs.Data2 == rhs.Data2 &&
......
......@@ -21,6 +21,7 @@ class ConsoleDisplay: public Display {
do {
*(display++) = ' ';
*(display++) = 0x0F;
pos += 2;
} while (pos % 8 != 0);
} else {
*(display++) = c;
......@@ -67,8 +68,7 @@ class FramebufferDisplay: public Display {
size_t pixelBytes() {
switch (pixelFormat) {
case PixelFormatRGBX: return 4;
case PixelFormatBGRX: return 4;
case PixelFormatRGBX: case PixelFormatBGRX: return 4;
}
return 0;
}
......@@ -84,17 +84,17 @@ class FramebufferDisplay: public Display {
} else if (c == '\t') {
offset += 8 - ((offset % charWidth()) % 8);
} else {
const uint8_t *fontsym = fb_font_8x16 + ((size_t)c * 16);
const uint8_t *fontsym = fb_font_8x16 + (size_t(c) * 16);
size_t offsetX = offset % charWidth();
size_t offsetY = offset / charWidth();
size_t pb = pixelBytes();
char *fbptr = static_cast<char*>(framebuffer)
uint8_t *fbptr = static_cast<uint8_t*>(framebuffer)
+ offsetY * 16 * width * pb
+ offsetX * 8 * pb;
for (size_t y = 0; y < 16; y++) {
char *line = fbptr + y * width * pb;
uint8_t *line = fbptr + y * width * pb;
uint8_t fontline = fontsym[y];
for (size_t x = 0; x < 8; x++) {
if (fontline & (1 << (8 - x))) {
......@@ -123,8 +123,8 @@ class FramebufferDisplay: public Display {
PixelFormat pixelFormat):
framebuffer(framebuffer), width(width), height(height),
pixelFormat(pixelFormat), offset(0) {
for (uintptr_t ptr = (uintptr_t)framebuffer;
ptr < (uintptr_t)framebuffer + bufferSize() + 0xFFF;
for (uintptr_t ptr = uintptr_t(framebuffer);
ptr < uintptr_t(framebuffer) + bufferSize() + 0xFFF;
ptr += 0x1000) {
Pagetable::map(reinterpret_cast<void*>(ptr));
}
......
......@@ -10,3 +10,4 @@
#include "kernlib/ports.hpp"
#include "kernlib/printf.hpp"
#include "kernlib/std.hpp"
#include "kernlib/rand.hpp"
......@@ -7,7 +7,7 @@
inline static uint64_t rdtsc() {
uint32_t eax, edx;
asm volatile("rdtsc":"=a"(eax), "=d"(edx));
return (((uint64_t)edx << 32) | eax);
return ((uint64_t(edx) << 32) | eax);
}
inline static uint64_t __attribute__((always_inline)) EnterCritical() {
......
// PhoeniX OS Kernel library standard functions
// Copyright © 2017 Yury Popov a.k.a. PhoeniX
#pragma once
#include <stdint.h>
class RAND {
private:
static uint64_t _get64();
public:
template<typename T> static inline T get() { return static_cast<T>(_get64()); }
};
......@@ -15,13 +15,13 @@ class List {
Item& insert() {
if (count == capacity) {
capacity += MAX(256 / sizeof(Item), (size_t)1);
capacity += MAX(256 / sizeof(Item), size_t(1));
items = static_cast<Item*>(Heap::realloc(items, sizeof(Item) * capacity));
}
return items[count++];
}
void add(const Item item) { insert() = item; }
void add(const Item &item) { insert() = item; }
size_t getCount() { return count; }
......
......@@ -10,7 +10,7 @@ static inline char *longlong_to_string(
int pos = len;
char table_start = fl_caps ? 'A' : 'a';
bool negative = 0;
if (fl_signed && (int64_t)n < 0) {
if (fl_signed && int64_t(n) < 0) {
negative = 1;
n = -n;
}
......@@ -243,7 +243,7 @@ parse_size:
case 'p':
flags.fl_altfmt = 1;
numsig = 0;
numval = (uintptr_t)va_arg(ap, void*);
numval = uintptr_t(va_arg(ap, void*));
numbase = 16;
goto out_num;
case 'x':
......
// PhoeniX OS Kernel library printf functions
// Copyright © 2017 Yury Popov a.k.a. PhoeniX
#include "kernlib.hpp"
#include "kernlib/rand.hpp"
static inline bool check_rdrand() {
uint32_t cpuid;
asm volatile("cpuid":"=c"(cpuid):"a"(uint32_t(1)), "c"(uint32_t(0)):"ebx", "edx");
return cpuid & (1 << 30);
}
static uint64_t _genseed() {
if (check_rdrand()) {
uint64_t val;
asm volatile("rdrandq %q0":"=r"(val));
return val;
}
return rdtsc();
}
static uint64_t seed = _genseed();
uint64_t RAND::_get64() {
uint64_t x = seed;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
seed = x;
return x * 0x2545f4914f6cdd1dllu;
}
......@@ -12,7 +12,7 @@ extern "C" {
size_t strlen(const char* c, size_t limit) {
const char *e = c;
while (((size_t)(e - c) < limit) && (*e++) != 0) {}
while ((size_t(e - c) < limit) && (*e++) != 0) {}
return e - c - 1;
}
......
......@@ -31,9 +31,9 @@ size_t MemoryStream::read(void* dest, size_t size) {
Stream* MemoryStream::substream(int64_t offset, size_t limit) {
if (offset == -1)
offset = this->offset;
if ((limit == (size_t)-1) || (limit > this->limit - offset))
if ((limit == size_t(-1)) || (limit > this->limit - offset))
limit = this->limit - offset;
return new MemoryStream(memory + (size_t)offset, limit);
return new MemoryStream(memory + size_t(offset), limit);
}
char* MemoryStream::readstr() {
size_t len = strlen(memory + offset, limit - offset);
......
......@@ -84,7 +84,7 @@ ACPI::ACPI() {
LapicOut(LAPIC_TMRINITCNT, -1);
while ((inportb(0x61) & 0x20) == (t & 0x20)) {}
LapicOut(LAPIC_LVT_TMR, LAPIC_DISABLE);
busfreq = ((-1 - LapicIn(LAPIC_TMRCURRCNT)) << 4) * 100;
busfreq = (static_cast<uint64_t>(-1 - LapicIn(LAPIC_TMRCURRCNT)) << 4) * 100;
}
void ACPI::ParseDT(const AcpiHeader *header) {
Pagetable::map(header);
......@@ -119,7 +119,7 @@ void ACPI::ParseXsdt(const AcpiHeader *xsdt) {
void ACPI::ParseApic(const AcpiMadt *madt) {
Pagetable::map(madt);
localApicAddr = reinterpret_cast<char*>(madt->localApicAddr);
localApicAddr = reinterpret_cast<char*>(uintptr_t(madt->localApicAddr));
Pagetable::map(localApicAddr);
const uint8_t *p = reinterpret_cast<const uint8_t*>(madt + 1);
......@@ -137,7 +137,7 @@ void ACPI::ParseApic(const AcpiMadt *madt) {
acpiCpuIds[acpiCpuCount++] = s->apicId;
} else if (type == 1) {
const ApicIoApic *s = reinterpret_cast<const ApicIoApic*>(p);
ioApicAddr = reinterpret_cast<char*>(s->ioApicAddress);
ioApicAddr = reinterpret_cast<char*>(uintptr_t(s->ioApicAddress));
Pagetable::map(ioApicAddr);
} else if (type == 2) {
const ApicInterruptOverride *s =
......@@ -171,7 +171,7 @@ bool ACPI::ParseRsdp(const void *ptr) {
Pagetable::map(rsdtPtr + 1);
uint32_t rsdtAddr = *rsdtPtr;
if (revision == 0) {
ParseRsdt(reinterpret_cast<AcpiHeader*>(rsdtAddr));
ParseRsdt(reinterpret_cast<AcpiHeader*>(uintptr_t(rsdtAddr)));
} else if (revision == 2) {
Pagetable::map(xsdtPtr);
Pagetable::map(xsdtPtr + 1);
......@@ -180,7 +180,7 @@ bool ACPI::ParseRsdp(const void *ptr) {
if (xsdtAddr)
ParseXsdt(reinterpret_cast<AcpiHeader*>(xsdtAddr));
else
ParseRsdt(reinterpret_cast<AcpiHeader*>(rsdtAddr));
ParseRsdt(reinterpret_cast<AcpiHeader*>(uintptr_t(rsdtAddr)));
}
return true;
......
......@@ -5,8 +5,8 @@
#include "kernlib.hpp"
#include "heap.hpp"
char CPU::vendor[13] = "";
char CPU::brandString[49] = "";
char CPU::vendor[16] = "";
char CPU::brandString[52] = "";
uint64_t CPU::features = 0;
uint64_t CPU::features_ext = 0;
uint64_t CPU::ext_features = 0;
......@@ -105,7 +105,7 @@ uint64_t CPU::getFeatures() {
asm volatile("cpuid" :
"=a"(eax), "=c"(ecx), "=d"(edx) :
"a"(eax) :"ebx");
features = ((uint64_t)edx << 32) | (uint64_t)ecx;
features = (uint64_t(ecx) << 32) | uint64_t(edx);
struct CPUID_INFO {
uint32_t stepping:3;
uint32_t model:4;
......@@ -133,7 +133,7 @@ uint64_t CPU::getFeaturesExt() {
asm volatile("cpuid" :
"=a"(eax), "=b"(ebx), "=c"(ecx) :
"a"(eax), "c"(ecx): "edx");
features_ext = (uint64_t)ebx | ((uint64_t)ecx << 32);
features_ext = uint64_t(ebx) | (uint64_t(ecx) << 32);
}
return features_ext;
}
......@@ -144,7 +144,7 @@ uint64_t CPU::getExtFeatures() {
asm volatile("cpuid" :
"=a"(eax), "=c"(ecx), "=d"(edx) :
"a"(eax): "ebx");
ext_features = (uint64_t)edx | ((uint64_t)ecx << 32);
ext_features = uint64_t(edx) | (uint64_t(ecx) << 32);
}
return ext_features;
}
......@@ -172,19 +172,19 @@ char* CPU::getFeaturesStr() {
char *end = buf;
for (int i = 0; i < 64; i++) {
if (((f & (1 << i)) != 0) && CPUID_FEAT_STR[i][0]) {
if (((f & (1ll << i)) != 0) && CPUID_FEAT_STR[i][0]) {
end += snprintf(end, bufsize - (end - buf), "%s ", CPUID_FEAT_STR[i]);
}
}
for (int i = 0; i < 64; i++) {
if (((ef & (1 << i)) != 0) && CPUID_EXT_FEAT_STR[i][0]) {
if (((ef & (1ll << i)) != 0) && CPUID_EXT_FEAT_STR[i][0]) {
end += snprintf(end, bufsize - (end - buf), "%s ", CPUID_EXT_FEAT_STR[i]);
}
}
for (int i = 0; i < 64; i++) {
if (((fe & (1 << i)) != 0) && CPUID_FEAT_EXT_STR[i][0]) {
if (((fe & (1ll << i)) != 0) && CPUID_FEAT_EXT_STR[i][0]) {
end += snprintf(end, bufsize - (end - buf), "%s ", CPUID_FEAT_EXT_STR[i]);
}
}
......
......@@ -46,7 +46,7 @@ find_page:
uintptr_t page = 0xFFFFFFFFFFFFFFFF;
while (pages) {
for (size_t i = 0; i < 511; i++) {
uintptr_t paddr = (uintptr_t)pages->pages[i];
uintptr_t paddr = uintptr_t(pages->pages[i]);
if (paddr == 0) continue;
if (page > paddr && paddr >= ptr) {
page = paddr;
......@@ -79,15 +79,15 @@ check_ptr:
pages = heap_pages;
while (pages) {
for (size_t i = 0; i < 511; i++) {
if ((uintptr_t)pages->pages[i] == pg) goto next_page;
if (uintptr_t(pages->pages[i]) == pg) goto next_page;
}
pages = pages->next;
}
pages = heap_pages;
while (pages) {
for (size_t i = 0; i < 511; i++) {
if ((uintptr_t)pages->pages[i] > ptr) {
ptr = (uintptr_t)pages->pages[i];
if (uintptr_t(pages->pages[i]) > ptr) {
ptr = uintptr_t(pages->pages[i]);
goto check_ptr;
}
}
......@@ -100,7 +100,7 @@ next_page:
table = allocs;
while (table) {
for (size_t i = 0; i < 255; i++) {
uintptr_t alloc_base = (uintptr_t)table->allocs[i].addr;
uintptr_t alloc_base = uintptr_t(table->allocs[i].addr);
uintptr_t alloc_top = alloc_base + table->allocs[i].size;
if (ptr >= alloc_top || ptr_top < alloc_base) continue;
ptr = alloc_top;
......
......@@ -184,13 +184,13 @@ struct cpu_info {
class CPU {
private:
static char vendor[13];
static char vendor[16];
static uint64_t features;
static uint64_t features_ext;
static uint64_t ext_features;
static struct cpu_info info;
static uint32_t maxCPUID;
static char brandString[49];
static char brandString[52];
public:
static char* getVendor();
static uint64_t getFeatures();
......
......@@ -86,8 +86,8 @@ struct GDT_ENT {
bool granularity :1;
uint64_t base_high :8;
uint64_t getBase() { return ((uint64_t)base_high << 24) | base_low; }
uint64_t getLimit() { return ((uint64_t)seg_lim_high << 16) | seg_lim_low; }
uint64_t getBase() { return (uint64_t(base_high) << 24) | base_low; }
uint64_t getLimit() { return (uint64_t(seg_lim_high) << 16) | seg_lim_low; }
void setBase(uint64_t base) {
base_low = base & 0xFFFFFF;
......@@ -116,7 +116,7 @@ struct GDT_SYS_ENT {
uint64_t base_high :32;
uint32_t rsvd;
uint64_t getBase() { return ((uintptr_t)base_high << 32) | ent.getBase(); }
uint64_t getBase() { return (uintptr_t(base_high) << 32) | ent.getBase(); }
void setBase(uint64_t base) {
ent.setBase(base);
......@@ -158,6 +158,7 @@ struct intcb_regs {
typedef bool intcb(uint32_t intr, uint32_t code, intcb_regs *regs);
class Process;
class Interrupts {
private:
static List<intcb*> *callbacks;
......@@ -171,7 +172,7 @@ class Interrupts {
static uint64_t handle(uint8_t intr, uint64_t stack, uint64_t *cr3);
public:
static void print(uint8_t num, intcb_regs *regs, uint32_t code);
static void print(uint8_t num, intcb_regs *regs, uint32_t code, const Process *process = nullptr);
static void maskIRQ(uint16_t mask);
static uint16_t getIRQmask();
static void addCallback(uint8_t intr, intcb* cb);
......
......@@ -31,10 +31,10 @@ struct PTE {
flags(flags), rsvd(0), avl(avl), _ptr(ptr >> 12) {}
PTE(uintptr_t ptr, uint8_t flags):
flags(flags), rsvd(0), avl(0), _ptr(ptr >> 12) {}
PTE(void *ptr, uint8_t avl, uint8_t flags):
flags(flags), rsvd(0), avl(avl), _ptr((uintptr_t)ptr >> 12) {}
PTE(void *ptr, uint8_t flags):
flags(flags), rsvd(0), avl(0), _ptr((uintptr_t)ptr >> 12) {}
PTE(const void *ptr, uint8_t avl, uint8_t flags):
flags(flags), rsvd(0), avl(avl), _ptr(uintptr_t(ptr) >> 12) {}
PTE(const void *ptr, uint8_t flags):
flags(flags), rsvd(0), avl(0), _ptr(uintptr_t(ptr) >> 12) {}
static PTE* find(uintptr_t ptr, PTE *pagetable) {
uint16_t ptx = (ptr >> (12 + 9 + 9 + 9)) & 0x1FF;
......@@ -52,7 +52,7 @@ struct PTE {
return &page[pml4x];
}
static PTE* find(void *addr, PTE *pagetable) {
return find((uintptr_t)addr, pagetable);
return find(uintptr_t(addr), pagetable);
}
} PACKED;
......@@ -71,9 +71,9 @@ class Pagetable {
inline static void MmioWrite32(void *p, uint32_t data) {
Pagetable::map(p);
*(volatile uint32_t *)(p) = data;
*reinterpret_cast<volatile uint32_t *>(p) = data;
}
inline static uint32_t MmioRead32(const void *p) {
Pagetable::map(p);
return *(const volatile uint32_t *)(p);
return *reinterpret_cast<const volatile uint32_t *>(p);
}
......@@ -4,6 +4,7 @@
#include "interrupts.hpp"
#include "acpi.hpp"
#include "pagetable.hpp"
#include "process.hpp"
INTERRUPT64 *Interrupts::idt = 0;
GDT *Interrupts::gdt = 0;
......@@ -158,7 +159,7 @@ struct int_info {
uint64_t rip, cs, rflags, rsp, ss;
} PACKED;
void Interrupts::print(uint8_t num, intcb_regs *regs, uint32_t code) {
void Interrupts::print(uint8_t num, intcb_regs *regs, uint32_t code, const Process *process) {
uint64_t cr2;
asm volatile("mov %%cr2, %0":"=a"(cr2));
uint32_t cpuid = ACPI::getController()->getCPUID();
......@@ -197,6 +198,8 @@ void Interrupts::print(uint8_t num, intcb_regs *regs, uint32_t code) {
regs->rax, regs->rcx, regs->rdx, regs->rbx,
regs->r8, regs->r9, regs->r10, regs->r11,
regs->r12, regs->r13, regs->r14, regs->r15);
Process::print_stacktrace(regs->rbp, process);
}
uint64_t __attribute__((sysv_abi)) Interrupts::handle(
......@@ -206,7 +209,7 @@ uint64_t __attribute__((sysv_abi)) Interrupts::handle(
uint64_t *rsp = reinterpret_cast<uint64_t*>(stack);
bool has_code = (intr < 0x20) && FAULTS[intr].has_error_code;
uint64_t error_code = 0;
int_regs *regs = reinterpret_cast<int_regs*>(rsp - (12 + 3));
int_regs *regs = reinterpret_cast<int_regs*>(rsp - (12 + 3) - 1);
if (has_code)
error_code = *(rsp++);
int_info *info = reinterpret_cast<int_info*>(rsp);
......@@ -218,13 +221,14 @@ uint64_t __attribute__((sysv_abi)) Interrupts::handle(
cpuid, *pagetable,
info->rip,
(uint16_t)(info->cs & 0xFFF8), info->rflags, info->rsp,
(uint16_t)(info->ss & 0xFFF8), (uint8_t)(info->cs & 7),
uint16_t(info->cs & 0xFFF8), info->rflags, info->rsp,
uint16_t(info->ss & 0xFFF8), uint8_t(info->cs & 7),
regs->rax,
regs->rcx, regs->rdx, regs->rbx, regs->rbp, regs->rsi, regs->rdi,
regs->r8, regs->r9, regs->r10, regs->r11, regs->r12, regs->r13, regs->r14,
regs->r15 };
regs->rax, regs->rcx, regs->rdx, regs->rbx,
regs->rbp, regs->rsi, regs->rdi,
regs->r8, regs->r9, regs->r10, regs->r11,
regs->r12, regs->r13, regs->r14, regs->r15
};
size_t idx = 0;
intcb *cb;
......@@ -246,9 +250,9 @@ uint64_t __attribute__((sysv_abi)) Interrupts::handle(
cb_regs.rbx, cb_regs.rdx, cb_regs.rcx, cb_regs.rax,
};
*info = {
cb_regs.rip, (uint64_t)(cb_regs.cs | cb_regs.dpl),
cb_regs.rip, uint64_t(cb_regs.cs | cb_regs.dpl),
cb_regs.rflags | 0x202,
cb_regs.rsp, (uint64_t)(cb_regs.ss | cb_regs.dpl)
cb_regs.rsp, uint64_t(cb_regs.ss | cb_regs.dpl)
};
*pagetable = cb_regs.cr3;
return has_code ? 8 : 0;
......@@ -277,19 +281,19 @@ void Interrupts::init() {
gdt->ents[0] = GDT_ENT();
gdt->ents[1] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0xA, 0, 1, 1, 0, 1, 0, 1);
gdt->ents[2] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0x2, 0, 1, 1, 0, 0, 1, 1);
gdt->ents[3] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0xA, 3, 1, 1, 0, 1, 0, 1);
gdt->ents[4] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0x2, 3, 1, 1, 0, 0, 1, 1);
gdt->ents[3] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0x2, 3, 1, 1, 0, 0, 1, 1);
gdt->ents[4] = GDT_ENT(0, 0xFFFFFFFFFFFFFFFF, 0xA, 3, 1, 1, 0, 1, 0, 1);
for (uint32_t idx = 0; idx < ncpu; idx++) {
void *stack = Pagetable::alloc();
uintptr_t stack_ptr = (uintptr_t)stack + 0x1000;
uintptr_t stack_ptr = uintptr_t(stack) + 0x1000;
Memory::zero(&tss[idx], sizeof(tss[idx]));
tss[idx].ist[0] = stack_ptr;
gdt->sys_ents[idx] = GDT_SYS_ENT(
(uintptr_t)&tss[idx], sizeof(TSS64_ENT),
uintptr_t(&tss[idx]), sizeof(TSS64_ENT),
0x9, 0, 0, 1, 0, 1, 0, 0);
}
DTREG gdtreg = { (uint16_t)(GDT::size(ncpu) -1), &gdt->ents[0] };
DTREG gdtreg = { uint16_t(GDT::size(ncpu) -1), &gdt->ents[0] };
asm volatile(
"mov %%rsp, %%rcx;"
......@@ -320,11 +324,11 @@ void Interrupts::init() {
::"a"(lapic_eoi)
);
for (int i = 0; i < 256; i++) {
uintptr_t jmp_from = (uintptr_t)&(handlers[i].reljmp);
uintptr_t jmp_from = uintptr_t(&(handlers[i].reljmp));
uintptr_t diff = addr - jmp_from - 5;
handlers[i] = int_handler(i, diff);
uintptr_t hptr = (uintptr_t)(&handlers[i]);
uintptr_t hptr = uintptr_t(&handlers[i]);
idt[i] = INTERRUPT64(hptr, 8, 1, 0xE, 0, true);
}
callbacks = new List<intcb*>[256]();
......
This diff is collapsed.
......@@ -57,7 +57,7 @@ void SMP::init() {
info = reinterpret_cast<StartupInfo*>(startupCode + ALIGN(smp_init_size, 8));
Memory::copy(startupCode, smp_init, smp_init_size);
char smp_init_vector = (((uintptr_t)startupCode) >> 12) & 0xFF;
char smp_init_vector = (uintptr_t(startupCode) >> 12) & 0xFF;
info->lapicAddr = acpi->getLapicAddr();
info->cpuids = new uint64_t[cpuCount]();
......
......@@ -70,7 +70,7 @@ x64_entry:
mov (%rcx,%r9,8), %rsp
# Jump back to SMP initializer
mov %rsp, %rbp
xor %rbp, %rbp
jmpq *%rdx
.align 8
......
......@@ -17,8 +17,12 @@ static void syscall_puts(uintptr_t strptr) {
static void syscall_exit(int code) {
ProcessManager *manager = ProcessManager::getManager();
Process *process = manager->currentProcess();
process->exit(code);
ProcessManager::process_loop();
asm volatile(
"callq _ZN7Process4exitEi;"
"sti;"
"jmp _ZN14ProcessManager12process_loopEv"
::"D"(process), "S"(code)
);
}
#define SYSCALL_ENT(name) { \
......@@ -47,7 +51,7 @@ static uint64_t syscall_index(uint64_t hash) {
uint64_t Syscall::callByName(const char *name) {
uint64_t hash = syscall_hash(name);
if (syscall_index(hash) == (uint64_t)-1) return 0;
if (syscall_index(hash) == uint64_t(-1)) return 0;
return hash;
}
......@@ -131,9 +135,8 @@ void Syscall::setup() {
asm volatile(
"mov %%cr3, %%rax; mov %%rax, 2 + _wrapper_mov_cr3(%%rip)":::"%rax"
);
wrmsr(MSR_STAR,
((uint64_t)USER_CS) << 48 |
((uint64_t)KERNEL_CS) << 32);
wrmsr(MSR_LSTAR, (uintptr_t)wrapper);
wrmsr(MSR_STAR, uint64_t(0x10) << 48 | uint64_t(0x8) << 32);
wrmsr(MSR_LSTAR, uintptr_t(wrapper));
wrmsr(MSR_SFMASK, MSR_SFMASK_IE);
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | MSR_EFER_SCE);
}
static const uint32_t MSR_EFER = 0xC0000080;
static const uint32_t MSR_STAR = 0xC0000081;
static const uint32_t MSR_LSTAR = 0xC0000082;
static const uint32_t MSR_SFMASK = 0xC0000084;
static const uint64_t MSR_SFMASK_IE = 1 << 9;
static const uint64_t MSR_EFER_SCE = 1 << 0;
static const uint16_t KERNEL_CS = 8;
static const uint16_t USER_CS = 24;
static inline void wrmsr(uint32_t msr_id, uint64_t msr_value) {
asm volatile("wrmsr"::"c"(msr_id), "A"(msr_value), "d"(msr_value >> 32));
......@@ -12,5 +12,5 @@ static inline void wrmsr(uint32_t msr_id, uint64_t msr_value) {
static inline uint64_t rdmsr(uint32_t msr_id) {
uint32_t msr_hi, msr_lo;
asm volatile("rdmsr":"=A"(msr_lo), "=d"(msr_hi):"c"(msr_id));
return ((uint64_t)msr_hi << 32) | (uint64_t)msr_lo;
return (uint64_t(msr_hi) << 32) | uint64_t(msr_lo);
}
......@@ -28,6 +28,7 @@ class Process {
List<ProcessSymbol> symbols;
uintptr_t entry;
void addPage(uintptr_t vaddr, void* paddr, uint8_t flags);
uintptr_t _aslrCode, _aslrStack;
public:
Process();
......@@ -47,8 +48,10 @@ class Process {
uintptr_t linkLibrary(const char* funcname);
void writeData(uintptr_t address, void* src, size_t size);
void readData(void* dst, uintptr_t address, size_t size);
char* readString(uintptr_t address);
void readData(void* dst, uintptr_t address, size_t size) const;
char* readString(uintptr_t address) const;
void* getPhysicalAddress(uintptr_t ptr) PURE;
void* getPhysicalAddress(uintptr_t ptr) const PURE;
static void print_stacktrace(uintptr_t base = 0, const Process *process = nullptr);
};
......@@ -85,10 +85,10 @@ void ModuleManager::parseInitRD() {
MULTIBOOT_PAYLOAD *multiboot = Multiboot::getPayload();
if (!multiboot || (multiboot->flags & MB_FLAG_MODS) == 0) return;
const MULTIBOOT_MODULE *mods =
reinterpret_cast<const MULTIBOOT_MODULE*>(multiboot->pmods_addr);
reinterpret_cast<const MULTIBOOT_MODULE*>(uintptr_t(multiboot->pmods_addr));
for (uint32_t i = 0; i < multiboot->mods_count; i++) {
const char *base = reinterpret_cast<const char*>(mods[i].start);
const char *top = reinterpret_cast<const char*>(mods[i].end);
const char *base = reinterpret_cast<const char*>(uintptr_t(mods[i].start));
const char *top = reinterpret_cast<const char*>(uintptr_t(mods[i].end));
size_t length = top - base;
MemoryStream ms(base, length);
loadStream(&ms, 1);
......
......@@ -10,33 +10,35 @@ Process::Process() {
id = -1;
pagetable = 0;
entry = 0;
_aslrCode = ((RAND::get<uintptr_t>() << 12) & 0x7FFFFFFF000) | 0x40000000000;
_aslrStack = ((RAND::get<uintptr_t>() << 12) & 0x7FFFFFFF000) | 0x80000000000;
}
Process::~Process() {
if (pagetable != 0) {
PTE addr;
for (uint16_t ptx = 0; ptx < 512; ptx++) {
for (uintptr_t ptx = 0; ptx < 512; ptx++) {
addr = pagetable[ptx];
if (!addr.present)
continue;
PTE *ppde = addr.getPTE();
for (uint16_t pdx = 0; pdx < 512; pdx++) {
for (uintptr_t pdx = 0; pdx < 512; pdx++) {
addr = ppde[pdx];
if (!addr.present)
continue;
PTE *pppde = addr.getPTE();
for (uint16_t pdpx = 0; pdpx < 512; pdpx++) {
for (uintptr_t pdpx = 0; pdpx < 512; pdpx++) {
addr = pppde[pdpx];
if (!addr.present)
continue;
PTE *ppml4e = addr.getPTE();
for (uint16_t pml4x = 0; pml4x < 512; pml4x++) {
for (uintptr_t pml4x = 0; pml4x < 512; pml4x++) {
addr = ppml4e[pml4x];
if (!addr.present)
continue;
void *page = addr.getPtr();
if ((uintptr_t)page == (((uintptr_t)ptx << (12 + 9 + 9 + 9))
| ((uintptr_t)pdx << (12 + 9 + 9))
| ((uintptr_t)pdpx << (12 + 9)) | ((uintptr_t)pml4x << (12))))