...
 
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; }
This diff is collapsed.
......@@ -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;
uint32_t pcmdline;
uint32_t mods_count;
uint32_t pmods_addr;
uint32_t syms[3];
uint32_t mmap_length;
uint32_t pmmap_addr;
uint32_t drives_length;
uint32_t pdrives_addr;
uint32_t pconfig_table;
uint32_t pboot_loader_name;
uint32_t papm_table;
uint64_t pvbe_control_info, pvbe_mode_info, pvbe_mode, pvbe_interface_seg,
pvbe_interface_off, pvbe_interface_len;
} PACKED;
struct MULTIBOOT_MODULE {
uint32_t start;
uint32_t end;
};
struct MULTIBOOT_MMAP_ENT {
uint32_t size;
void *base;
size_t length;
uint32_t type;
} PACKED;
class Multiboot {
public:
enum 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 Payload {
Flags flags;
size_t mem_lower:32, mem_upper:32;
uint32_t boot_device;
uint32_t pcmdline;
uint32_t mods_count;
uint32_t pmods_addr;
uint32_t syms[3];
uint32_t mmap_length;
uint32_t pmmap_addr;
uint32_t drives_length;
uint32_t pdrives_addr;
uint32_t pconfig_table;
uint32_t pboot_loader_name;
uint32_t papm_table;
uint64_t pvbe_control_info, pvbe_mode_info, pvbe_mode, pvbe_interface_seg,
pvbe_interface_off, pvbe_interface_len;
} PACKED;
struct MmapEnt {
uint32_t size;
void *base;
size_t length;
uint32_t type;
} PACKED;
struct Module {
uint32_t start;
uint32_t end;
};
private:
static MULTIBOOT_PAYLOAD *payload;
static Payload *payload;
public:
static MULTIBOOT_PAYLOAD *getPayload() PURE;
static Payload *getPayload() PURE;
};
......@@ -3,7 +3,7 @@
#include "multiboot_info.hpp"
MULTIBOOT_PAYLOAD *Multiboot::payload = 0;
MULTIBOOT_PAYLOAD *Multiboot::getPayload() {
Multiboot::Payload *Multiboot::payload = 0;
Multiboot::Payload *Multiboot::getPayload() {
return payload;
}
......@@ -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));
}
......@@ -153,20 +153,20 @@ class SerialDisplay: public Display {
public:
SerialDisplay() {
// Disable interrupts
outportb(port + 1, 0);
Port<port + 1>::out<uint8_t>(0);
// Enable DLAB
outportb(port + 3, 0x80);
Port<port + 3>::out<uint8_t>(0x80);
// Set divisor
outportb(port + 0, divisor & 0xFF);
outportb(port + 1, (divisor >> 16) & 0xFF);
Port<port + 0>::out<uint8_t>(divisor & 0xFF);
Port<port + 1>::out<uint8_t>((divisor >> 16) & 0xFF);
// Set port mode (8N1), disable DLAB
outportb(port + 3, 0x03);
Port<port + 3>::out<uint8_t>(0x03);
}
void write(const char *str) {
uint64_t t = EnterCritical();
mutex.lock();
char c;
while ((c = *str++) != 0) outportb(port, c);
while ((c = *str++) != 0) Port<port>::out<uint8_t>(c);
mutex.release();
LeaveCritical(t);
}
......@@ -187,18 +187,18 @@ static Display *getSerialDisplay() { return &serialConsole; }
void Display::setup() {
if (instance != &serialConsole) return;
const EFI_SYSTEM_TABLE *ST = EFI::getSystemTable();
const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST) { // EFI Framebuffer
EFI_GRAPHICS_OUTPUT *graphics_output = 0;
EFI::GraphicsOutput *graphics_output = 0;
ST->BootServices->LocateProtocol(
&EFI_GRAPHICS_OUTPUT_PROTOCOL, 0,
&EFI::GUID_GraphicsOutputProtocol, 0,
reinterpret_cast<void**>(&graphics_output));
PixelFormat pixelFormat;
switch (graphics_output->Mode->Info->PixelFormat) {
case EFI_GRAPHICS_PIXEL_FORMAT_RGBX_8BPP:
case EFI::GRAPHICS_PIXEL_FORMAT_RGBX_8BPP:
pixelFormat = PixelFormatRGBX;
break;
case EFI_GRAPHICS_PIXEL_FORMAT_BGRX_8BPP:
case EFI::GRAPHICS_PIXEL_FORMAT_BGRX_8BPP:
pixelFormat = PixelFormatBGRX;
break;
default:
......
......@@ -10,3 +10,4 @@
#include "kernlib/ports.hpp"
#include "kernlib/printf.hpp"
#include "kernlib/std.hpp"
#include "kernlib/rand.hpp"
......@@ -4,11 +4,13 @@
#pragma once
#include "std.hpp"
inline static uint64_t rdtsc() {
uint32_t eax, edx;
asm volatile("rdtsc":"=a"(eax), "=d"(edx));
return (((uint64_t)edx << 32) | eax);
}
namespace klib {
inline static uint64_t rdtsc() {
uint32_t eax, edx;
asm volatile("rdtsc":"=a"(eax), "=d"(edx));
return ((uint64_t(edx) << 32) | eax);
}
} // namespace klib
inline static uint64_t __attribute__((always_inline)) EnterCritical() {
uint64_t flags;
......
......@@ -4,32 +4,37 @@
#pragma once
#include "std.hpp"
inline static uint8_t inportb(uint16_t port) {
uint8_t c;
asm volatile("inb %w1, %b0":"=a"(c):"d"(port));
return c;
}
inline static uint16_t inports(uint16_t port) {
uint16_t c;
asm volatile("inw %w1, %w0":"=a"(c):"d"(port));
return c;
}
inline static uint32_t inportl(uint16_t port) {
uint32_t c;
asm volatile("inl %w1, %d0":"=a"(c):"d"(port));
return c;
}
inline static void outportb(uint16_t port, uint8_t c) {
asm volatile("outb %b0, %w1"::"a"(c), "d"(port));
}
inline static void outports(uint16_t port, uint16_t c) {
asm volatile("outw %w0, %w1"::"a"(c), "d"(port));
}
inline static void outportl(uint16_t port, uint32_t c) {
asm volatile("outl %d0, %w1"::"a"(c), "d"(port));
}
template<uint16_t port> struct Port {
template<typename T> inline static T in();
template<typename T> inline static void out(T value);
template<> inline static uint8_t in() {
uint8_t c;
asm volatile("inb %w1, %b0":"=a"(c):"d"(port));
return c;
}
template<> inline static uint16_t in() {
uint16_t c;
asm volatile("inw %w1, %w0":"=a"(c):"d"(port));
return c;
}
template<> inline static uint32_t in() {
uint32_t c;
asm volatile("inl %w1, %d0":"=a"(c):"d"(port));
return c;
}
template<> inline static void out(uint8_t c) {
asm volatile("outb %b0, %w1"::"a"(c), "d"(port));
}
template<> inline static void out(uint16_t c) {
asm volatile("outw %w0, %w1"::"a"(c), "d"(port));
}
template<> inline static void out(uint32_t c) {
asm volatile("outl %d0, %w1"::"a"(c), "d"(port));
}
};
// 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()); }
};
......@@ -14,16 +14,18 @@
#define alloca(size) __builtin_alloca((size))
template<typename T> inline static T PURE MAX(T a, T b) { return a > b ? a : b; }
template<typename T> inline static T PURE MIN(T a, T b) { return a < b ? a : b; }
template<typename T> inline static T PURE ABS(T a) { return a > 0 ? a : -a; }
namespace klib {
template<typename T> inline static T PURE max(T a, T b) { return a > b ? a : b; }
template<typename T> inline static T PURE min(T a, T b) { return a < b ? a : b; }
template<typename T> inline static T PURE abs(T a) { return a > 0 ? a : -a; }
size_t strlen(const char*, size_t limit = -1) PURE;
char* strdup(const char*);
int strcmp(const char*, const char*) PURE;
size_t strlen(const char*, size_t limit = -1) PURE;
char* strdup(const char*);
int strcmp(const char*, const char*) PURE;
inline static uintptr_t ALIGN(uintptr_t base, size_t align) {
if (base % align == 0)
return base;
return base + align - (base % align);
}
inline static uintptr_t __align(uintptr_t base, size_t align) {
if (base % align == 0)
return base;
return base + align - (base % align);
}
} // namespace klib
......@@ -15,13 +15,13 @@ class List {
Item& insert() {
if (count == capacity) {
capacity += MAX(256 / sizeof(Item), (size_t)1);
capacity += klib::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':
......@@ -326,7 +326,7 @@ out_num:
out_str:
int pad = width - strlen(strval);
int pad = width - klib::strlen(strval);
if (!flags.fl_leftfmt && (flags.fl_leadzero || flags.fl_leadspace)) {
c = flags.fl_leadzero ? '0' : ' ';
while (pad-- > 0) printf_putc(str, &size, &out_len, c);
......
// 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 klib::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;
}
......@@ -10,21 +10,23 @@ extern "C" {
int CONST __cxa_atexit(void (*)(void*), void*, void*) { return 0; }
}
size_t strlen(const char* c, size_t limit) {
const char *e = c;
while (((size_t)(e - c) < limit) && (*e++) != 0) {}
return e - c - 1;
}
namespace klib {
size_t strlen(const char* c, size_t limit) {
const char *e = c;
while ((size_t(e - c) < limit) && (*e++) != 0) {}
return e - c - 1;
}
char* strdup(const char* c) {
size_t len = strlen(c);
char* r = new char[len + 1]();
Memory::copy(r, c, len + 1);
return r;
}
char* strdup(const char* c) {
size_t len = strlen(c);
char* r = new char[len + 1]();
Memory::copy(r, c, len + 1);
return r;
}
int strcmp(const char* a, const char* b) {
size_t i = 0;
while (a[i] != 0 && b[i] != 0 && a[i] == b[i]) { i++; }
return a[i] - b[i];
}
int strcmp(const char* a, const char* b) {
size_t i = 0;
while (a[i] != 0 && b[i] != 0 && a[i] == b[i]) { i++; }
return a[i] - b[i];
}
} // namespace klib
......@@ -31,12 +31,12 @@ 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);
size_t len = klib::strlen(memory + offset, limit - offset);
char* res = new char[len + 1]();
Memory::copy(res, memory + offset, len);
res[len] = 0;
......
......@@ -31,18 +31,18 @@ ACPI::ACPI() {
acpiCpuCount = 0;
activeCpuCount = 1;
if (!(CPU::getFeatures() & CPUID_FEAT_APIC)) {
if (!(CPU::getFeatures() & CPU::CPUID_FEAT_APIC)) {
acpiCpuCount = 1;
return;
}
const EFI_SYSTEM_TABLE *ST = EFI::getSystemTable();
const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST && ST->ConfigurationTable) {
const EFI_CONFIGURATION_TABLE *acpi1 = 0, *acpi2 = 0;
const EFI::ConfigurationTable *acpi1 = 0, *acpi2 = 0;
for (uint64_t i = 0; i < ST->NumberOfTableEntries; i++) {
const EFI_CONFIGURATION_TABLE *tbl = ST->ConfigurationTable + i;
if (tbl->VendorGuid == EFI_CONF_TABLE_GUID_ACPI1) acpi1 = tbl;
if (tbl->VendorGuid == EFI_CONF_TABLE_GUID_ACPI2) acpi2 = tbl;
const EFI::ConfigurationTable *tbl = ST->ConfigurationTable + i;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI1) acpi1 = tbl;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI2) acpi2 = tbl;
}
bool found = 0;
......@@ -73,26 +73,26 @@ ACPI::ACPI() {
LapicOut(LAPIC_TMRDIV, 3);
LapicOut(LAPIC_LVT_TMR, 0x20 | LAPIC_SW_ENABLE);
outportb(0x61, (inportb(0x61) & 0xFD) | 1);
outportb(0x43, 0xB2);
outportb(0x42, 0x9B);
inportb(0x60);
outportb(0x42, 0x2E);
uint8_t t = inportb(0x61) & 0xFE;
outportb(0x61, t);
outportb(0x61, t | 1);
Port<0x61>::out<uint8_t>((Port<0x61>::in<uint8_t>() & 0xFD) | 1);
Port<0x43>::out<uint8_t>(0xB2);
Port<0x42>::out<uint8_t>(0x9B);
Port<0x60>::in<uint8_t>();
Port<0x42>::out<uint8_t>(0x2E);
uint8_t t = Port<0x61>::in<uint8_t>() & 0xFE;
Port<0x61>::out<uint8_t>(t);
Port<0x61>::out<uint8_t>(t | 1);
LapicOut(LAPIC_TMRINITCNT, -1);
while ((inportb(0x61) & 0x20) == (t & 0x20)) {}
while ((Port<0x61>::in<uint8_t>() & 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) {
void ACPI::ParseDT(const Header *header) {
Pagetable::map(header);
if (header->signature == 0x43495041) // 'CIPA'
ParseApic(reinterpret_cast<const AcpiMadt*>(header));
ParseApic(reinterpret_cast<const Madt*>(header));
}
void ACPI::ParseRsdt(const AcpiHeader *rsdt) {
void ACPI::ParseRsdt(const Header *rsdt) {
Pagetable::map(rsdt);
const uint32_t *p = reinterpret_cast<const uint32_t*>(rsdt + 1);
const uint32_t *end = p + (rsdt->length - sizeof(*rsdt)) / sizeof(uint32_t);
......@@ -101,10 +101,10 @@ void ACPI::ParseRsdt(const AcpiHeader *rsdt) {
Pagetable::map(p);
Pagetable::map(p + 1);
uintptr_t address = ((*p++) & 0xFFFFFFFF);
ParseDT(reinterpret_cast<AcpiHeader*>(address));
ParseDT(reinterpret_cast<Header*>(address));
}
}
void ACPI::ParseXsdt(const AcpiHeader *xsdt) {
void ACPI::ParseXsdt(const Header *xsdt) {
Pagetable::map(xsdt);
const uint64_t *p = reinterpret_cast<const uint64_t*>(xsdt + 1);
const uint64_t *end = p + (xsdt->length - sizeof(*xsdt)) / sizeof(uint64_t);
......@@ -113,17 +113,17 @@ void ACPI::ParseXsdt(const AcpiHeader *xsdt) {
Pagetable::map(p);
Pagetable::map(p + 1);
uint64_t address = *p++;
ParseDT(reinterpret_cast<AcpiHeader*>(address));
ParseDT(reinterpret_cast<Header*>(address));
}
}
void ACPI::ParseApic(const AcpiMadt *madt) {
void ACPI::ParseApic(const Madt *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);
const uint8_t *end = p + (madt->header.length - sizeof(AcpiMadt));
const uint8_t *end = p + (madt->header.length - sizeof(Madt));
while (p < end) {
const ApicHeader *header = reinterpret_cast<const ApicHeader*>(p);
......@@ -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,16 +171,16 @@ 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<Header*>(uintptr_t(rsdtAddr)));
} else if (revision == 2) {
Pagetable::map(xsdtPtr);
Pagetable::map(xsdtPtr + 1);
uint64_t xsdtAddr = *xsdtPtr;
if (xsdtAddr)
ParseXsdt(reinterpret_cast<AcpiHeader*>(xsdtAddr));
ParseXsdt(reinterpret_cast<Header*>(xsdtAddr));
else
ParseRsdt(reinterpret_cast<AcpiHeader*>(rsdtAddr));
ParseRsdt(reinterpret_cast<Header*>(uintptr_t(rsdtAddr)));
}
return true;
......@@ -231,20 +231,15 @@ void ACPI::IOapicOut(uint32_t reg, uint32_t data) {
MmioWrite32(ioApicAddr + IOAPIC_REGSEL, reg);
MmioWrite32(ioApicAddr + IOAPIC_REGWIN, data);
}
union ioapic_redir_ints {
ioapic_redir r;
uint32_t i[2];
};
void ACPI::IOapicMap(uint32_t idx, ioapic_redir r) {
ioapic_redir_ints a = { .r = r };
IOapicOut(IOAPIC_REDTBL + idx * 2 + 0, a.i[0]);
IOapicOut(IOAPIC_REDTBL + idx * 2 + 1, a.i[1]);
void ACPI::IOapicMap(uint32_t idx, IOApicRedir r) {
IOapicOut(IOAPIC_REDTBL + idx * 2 + 0, r.raw[0]);
IOapicOut(IOAPIC_REDTBL + idx * 2 + 1, r.raw[1]);
}
ioapic_redir ACPI::IOapicReadMap(uint32_t idx) {
ioapic_redir_ints a;
a.i[0] = IOapicIn(IOAPIC_REDTBL + idx * 2 + 0);
a.i[1] = IOapicIn(IOAPIC_REDTBL + idx * 2 + 1);
return a.r;
ACPI::IOApicRedir ACPI::IOapicReadMap(uint32_t idx) {
IOApicRedir a;
a.raw[0] = IOapicIn(IOAPIC_REDTBL + idx * 2 + 0);
a.raw[1] = IOapicIn(IOAPIC_REDTBL + idx * 2 + 1);
return a;
}
void* ACPI::getLapicAddr() {
return localApicAddr;
......@@ -313,7 +308,7 @@ void ACPI::initIOAPIC() {
if (ioApicAddr == 0)
return;
ioApicMaxCount = (IOapicIn(IOAPIC_VER) >> 16) & 0xFF;
ioapic_redir kbd;
IOApicRedir kbd;
kbd.vector = 0x21;
kbd.deliveryMode = 1;
kbd.destinationMode = 0;
......
......@@ -5,12 +5,12 @@
#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;
struct cpu_info CPU::info = { 0xFFFFFFFF, 0, 0, 0 };
CPU::Info CPU::info = { 0xFFFFFFFF, 0, 0, 0 };