├── init ├── .gitignore ├── include │ ├── code16gcc.h │ └── boot_32.hpp ├── linker.ld └── Makefile ├── .gitmodules ├── kernel ├── include │ ├── thor_acenvex.hpp │ ├── net │ │ ├── alpha.hpp │ │ ├── checksum.hpp │ │ └── packet.hpp │ ├── kernel.hpp │ ├── mmap.hpp │ ├── drivers │ │ ├── rtc.hpp │ │ ├── serial.hpp │ │ ├── pit.hpp │ │ ├── hpet.hpp │ │ ├── loopback.hpp │ │ ├── rtl8139.hpp │ │ ├── mouse.hpp │ │ ├── ramdisk.hpp │ │ ├── keyboard.hpp │ │ ├── ata_constants.hpp │ │ ├── pci.hpp │ │ └── ata.hpp │ ├── system_calls.hpp │ ├── acpi.hpp │ ├── gdt.hpp │ ├── scheduler_asm.hpp │ ├── ioctl.hpp │ ├── acpica.hpp │ ├── syscalls.hpp │ ├── irqs.hpp │ ├── kalloc.hpp │ ├── thor_acpi.hpp │ ├── terminal_driver.hpp │ ├── thor.hpp │ ├── e820.hpp │ ├── arch.hpp │ ├── isrs.hpp │ ├── e820_types.hpp │ ├── assert.hpp │ ├── vfs │ │ └── file.hpp │ ├── logging.hpp │ ├── disks.hpp │ ├── stdio.hpp │ ├── text_console.hpp │ ├── print.hpp │ ├── virtual_debug.hpp │ ├── conc │ │ ├── spinlock.hpp │ │ ├── int_lock.hpp │ │ ├── condition_variable.hpp │ │ ├── deferred_unique_mutex.hpp │ │ └── wait_list.hpp │ ├── timer.hpp │ ├── virtual_allocator.hpp │ ├── vesa.hpp │ ├── interrupts.hpp │ ├── console.hpp │ ├── kernel_utils.hpp │ └── physical_allocator.hpp ├── src │ ├── crtn.s │ ├── crti.s │ ├── net │ │ └── alpha.cpp │ ├── arch.cpp │ ├── kernel_utils.cpp │ ├── gdt.cpp │ ├── arch.s │ ├── ioctl.cpp │ ├── drivers │ │ ├── serial.cpp │ │ ├── loopback.cpp │ │ └── pit.cpp │ ├── irqs.s │ ├── assert.cpp │ ├── syscalls.s │ ├── terminal_driver.cpp │ ├── isrs.s │ ├── mmap.cpp │ ├── task_switch.s │ ├── text_console.cpp │ └── e820.cpp ├── linker.ld └── test_suite │ └── test.cpp ├── tools ├── debug_bochsrc.txt ├── gdb_bochsrc.txt ├── bochsrc.txt └── font_convert.tmpl ├── .gitignore ├── tlib ├── src │ ├── crtn.s │ ├── crti.s │ ├── ssp.cpp │ ├── io.cpp │ └── graphics.cpp ├── include │ └── tlib │ │ ├── flags.hpp │ │ ├── ioctl_codes.hpp │ │ ├── statfs_info.hpp │ │ ├── io.hpp │ │ ├── directory_entry.hpp │ │ ├── mount_point.hpp │ │ ├── datetime.hpp │ │ ├── malloc.hpp │ │ ├── stat_info.hpp │ │ ├── graphics.hpp │ │ ├── dns.hpp │ │ ├── system.hpp │ │ ├── print.hpp │ │ ├── config.hpp │ │ └── elf.hpp └── Makefile ├── programs ├── args │ ├── Makefile │ └── src │ │ └── main.cpp ├── cat │ ├── Makefile │ └── src │ │ └── main.cpp ├── date │ ├── Makefile │ └── src │ │ └── main.cpp ├── df │ ├── Makefile │ └── src │ │ └── main.cpp ├── free │ └── Makefile ├── long │ ├── Makefile │ └── src │ │ └── main.cpp ├── loop │ ├── Makefile │ └── src │ │ └── main.cpp ├── ls │ └── Makefile ├── mkfs │ └── Makefile ├── nc │ └── Makefile ├── odin │ └── Makefile ├── ping │ └── Makefile ├── ps │ └── Makefile ├── rand │ ├── Makefile │ └── src │ │ └── main.cpp ├── rm │ ├── Makefile │ └── src │ │ └── main.cpp ├── stat │ └── Makefile ├── tsh │ └── Makefile ├── wget │ └── Makefile ├── alpha │ ├── Makefile │ └── src │ │ └── main.cpp ├── bench │ └── Makefile ├── cpuid │ └── Makefile ├── dctor │ ├── Makefile │ └── src │ │ └── main.cpp ├── lse820 │ └── Makefile ├── lspci │ └── Makefile ├── mkdir │ ├── Makefile │ └── src │ │ └── main.cpp ├── mount │ └── Makefile ├── reboot │ ├── Makefile │ └── src │ │ └── main.cpp ├── touch │ ├── Makefile │ └── src │ │ └── main.cpp ├── uptime │ ├── Makefile │ └── src │ │ └── main.cpp ├── which │ ├── Makefile │ └── src │ │ └── main.cpp ├── writer │ ├── Makefile │ └── src │ │ └── main.cpp ├── divzero │ ├── Makefile │ └── src │ │ └── main.cpp ├── ifconfig │ └── Makefile ├── keyboard │ ├── Makefile │ └── src │ │ └── main.cpp ├── longone │ ├── Makefile │ └── src │ │ └── main.cpp ├── longtwo │ ├── Makefile │ └── src │ │ └── main.cpp ├── nslookup │ └── Makefile ├── readelf │ └── Makefile ├── shutdown │ ├── Makefile │ └── src │ │ └── main.cpp ├── linker.ld └── Makefile ├── bootloader ├── Makefile └── intel_16.asm ├── tstl ├── Makefile ├── include │ ├── new.hpp │ ├── math.hpp │ ├── cstring.hpp │ ├── literals.hpp │ ├── nth_type.hpp │ ├── lock_guard.hpp │ ├── enable_if.hpp │ ├── deleter.hpp │ ├── utility.hpp │ ├── memory.hpp │ ├── iostream.hpp │ ├── initializer_list.hpp │ ├── bit_field.hpp │ ├── function.hpp │ ├── atomic.hpp │ ├── queue.hpp │ ├── types.hpp │ ├── optional.hpp │ ├── pair.hpp │ ├── random.hpp │ ├── integer_sequence.hpp │ └── stack.hpp └── test_suite │ ├── expected.cpp │ ├── test.hpp │ ├── function.cpp │ ├── circular_buffer.cpp │ └── shared_ptr.cpp ├── ci └── Jenkins.groovy ├── LICENSE ├── printf └── include │ └── printf_dec.hpp ├── sonar-project.properties └── .clang-format /init/.gitignore: -------------------------------------------------------------------------------- 1 | debug 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "kernel/acpica"] 2 | path = kernel/acpica 3 | url = https://github.com/acpica/acpica.git 4 | ignore = dirty 5 | -------------------------------------------------------------------------------- /kernel/include/thor_acenvex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __ACENVEX_H__ 2 | #define __ACENVEX_H__ 3 | 4 | // No extensions 5 | 6 | #endif /* __ACENVEX_H__ */ 7 | -------------------------------------------------------------------------------- /tools/debug_bochsrc.txt: -------------------------------------------------------------------------------- 1 | display_library: x, options="gui_debug" 2 | magic_break: enabled=1 3 | ata0-master: type=disk, path="hdd.img", mode=flat, cylinders=1000, heads=16, spt=63 4 | boot: disk -------------------------------------------------------------------------------- /tools/gdb_bochsrc.txt: -------------------------------------------------------------------------------- 1 | display_library: sdl 2 | magic_break: enabled=1 3 | gdbstub: enabled=1, port=1234 4 | ata0-master: type=disk, path="hdd.img", mode=flat, cylinders=1000, heads=16, spt=63 5 | boot: disk 6 | -------------------------------------------------------------------------------- /tools/bochsrc.txt: -------------------------------------------------------------------------------- 1 | display_library: sdl 2 | magic_break: enabled=1 3 | port_e9_hack: enabled=1 4 | mouse: enabled=1 5 | ata0-master: type=disk, path="hdd.img", mode=flat, cylinders=1000, heads=16, spt=63 6 | boot: disk 7 | memory: guest=32, host=32 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.flp 3 | *.img 4 | *.out 5 | commands 6 | mnt 7 | *.a 8 | kernel/debug 9 | init/debug 10 | programs/*/debug 11 | programs/dist/ 12 | tstl/debug 13 | tlib/debug 14 | 15 | # Ignore the generated log (Qemu) 16 | *.log 17 | 18 | # Ignore the generated pcap files (Qemu) 19 | *.pcap 20 | -------------------------------------------------------------------------------- /kernel/src/crtn.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | 3 | .section .init 4 | /* gcc will nicely put the contents of crtend.o's .init section here. */ 5 | 6 | pop rbp 7 | ret 8 | 9 | .section .fini 10 | /* gcc will nicely put the contents of crtend.o's .fini section here. */ 11 | 12 | pop rbp 13 | ret 14 | -------------------------------------------------------------------------------- /tlib/src/crtn.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | 3 | .section .init 4 | /* gcc will nicely put the contents of crtend.o's .init section here. */ 5 | 6 | pop rbp 7 | ret 8 | 9 | .section .fini 10 | /* gcc will nicely put the contents of crtend.o's .fini section here. */ 11 | 12 | pop rbp 13 | ret 14 | -------------------------------------------------------------------------------- /programs/args/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=args 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/cat/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=cat 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/date/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=date 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/df/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=df 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/free/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=free 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/long/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=long 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/loop/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=loop 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/ls/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=ls 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/mkfs/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=mkfs 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/nc/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=nc 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/odin/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=odin 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/ping/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=ping 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/ps/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=ps 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/rand/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=rand 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/rm/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=rm 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/stat/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=stat 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/tsh/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=tsh 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/wget/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=wget 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/alpha/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=alpha 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/bench/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=bench 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/cpuid/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=cpuid 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/dctor/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=dctor 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/lse820/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=lse820 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/lspci/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=lspci 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/mkdir/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=mkdir 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/mount/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=mount 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/reboot/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=reboot 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/touch/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=touch 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/uptime/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=uptime 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/which/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=which 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/writer/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=writer 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/divzero/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=divzero 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/ifconfig/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=ifconfig 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/keyboard/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=keyboard 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/longone/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=longone 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/longtwo/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=longtwo 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/nslookup/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=nslookup 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/readelf/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=readelf 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /programs/shutdown/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | EXEC_NAME=shutdown 4 | 5 | default: link 6 | 7 | include ../../cpp.mk 8 | 9 | $(eval $(call program_compile_cpp_folder,src)) 10 | $(eval $(call program_link_executable,$(EXEC_NAME))) 11 | 12 | clean: 13 | @ echo -e "Remove compiled files" 14 | @ rm -rf debug 15 | -------------------------------------------------------------------------------- /bootloader/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | .PHONY: all clean 4 | 5 | stage1.bin: stage1.asm 6 | nasm -w+all -f bin -o stage1.bin stage1.asm 7 | 8 | stage2.bin: stage2.asm 9 | nasm -w+all -f bin -o stage2.bin stage2.asm 10 | 11 | all: stage1.bin stage2.bin 12 | 13 | clean: 14 | rm -f stage1.bin 15 | rm -f stage2.bin 16 | rm -f padding.bin 17 | rm -f bootloader.bin 18 | -------------------------------------------------------------------------------- /tstl/Makefile: -------------------------------------------------------------------------------- 1 | default: debug/bin/tester 2 | 3 | include ../cpp.mk 4 | 5 | TESTSUITE_CPP_FILES=$(wildcard test_suite/*.cpp) 6 | 7 | TEST_CXX ?= g++ 8 | 9 | debug/bin/tester: $(TESTSUITE_CPP_FILES) 10 | @ mkdir -p debug/bin/ 11 | $(TEST_CXX) $(WARNING_FLAGS) --std=c++11 -Iinclude -o debug/bin/tester -g $(TESTSUITE_CPP_FILES) 12 | 13 | test: debug/bin/tester 14 | ./debug/bin/tester 15 | 16 | clean: 17 | rm -rf debug 18 | -------------------------------------------------------------------------------- /kernel/src/crti.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | 3 | .section .init 4 | .global _init 5 | .type _init, @function 6 | _init: 7 | push rbp 8 | mov rbp, rsp 9 | 10 | /* gcc will nicely put the contents of crtbegin.o's .init section here. */ 11 | 12 | .section .fini 13 | .global _fini 14 | .type _fini, @function 15 | _fini: 16 | push rbp 17 | mov rbp, rsp 18 | 19 | /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ 20 | -------------------------------------------------------------------------------- /tlib/src/crti.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | 3 | .section .init 4 | .global _init 5 | .type _init, @function 6 | _init: 7 | push rbp 8 | mov rbp, rsp 9 | 10 | /* gcc will nicely put the contents of crtbegin.o's .init section here. */ 11 | 12 | .section .fini 13 | .global _fini 14 | .type _fini, @function 15 | _fini: 16 | push rbp 17 | mov rbp, rsp 18 | 19 | /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ 20 | -------------------------------------------------------------------------------- /programs/loop/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | int main(){ 9 | while(true){}; 10 | 11 | return 1; 12 | } -------------------------------------------------------------------------------- /init/include/code16gcc.h: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | /* 9 | * Hack to make GCC output 16-bit code. 10 | */ 11 | 12 | asm(".code16gcc"); 13 | -------------------------------------------------------------------------------- /programs/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS { 4 | . = 0x8000400000; 5 | 6 | .text BLOCK(4096) : ALIGN(4096) 7 | { 8 | *(.start) 9 | *(.text) 10 | *(.text*) 11 | } 12 | 13 | . = 0x8000600000; 14 | 15 | .data BLOCK(4096) : ALIGN(4096) 16 | { 17 | *(.data) 18 | } 19 | 20 | .rodata BLOCK(4096) : ALIGN(4096) 21 | { 22 | *(.rodata) 23 | *(.rodata*) 24 | } 25 | 26 | .bss BLOCK(4096) : ALIGN(4096) 27 | { 28 | *(.bss) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /programs/reboot/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | int main(){ 11 | tlib::reboot(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /kernel/src/net/alpha.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "net/alpha.hpp" 9 | 10 | void network::alpha(){ 11 | // alpha is not implemented now 12 | } 13 | -------------------------------------------------------------------------------- /programs/shutdown/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | int main(){ 11 | tlib::shutdown(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /programs/alpha/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | int main(int, char*[]){ 11 | tlib::alpha(); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /kernel/include/net/alpha.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef NET_ALPHA_H 9 | #define NET_ALPHA_H 10 | 11 | namespace network { 12 | 13 | void alpha(); 14 | 15 | } // end of network namespace 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /init/include/boot_32.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef BOOT_32_HPP 9 | #define BOOT_32_HPP 10 | 11 | extern "C" { 12 | 13 | void __attribute((noreturn)) pm_main(); 14 | 15 | } //end of exern "C" 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /programs/divzero/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | volatile int a = 0; 11 | 12 | int main(int /*argc*/, char* /*argv*/[]){ 13 | a = 42 / a; 14 | 15 | return a; 16 | } 17 | -------------------------------------------------------------------------------- /kernel/include/kernel.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef KERNEL_HPP 9 | #define KERNEL_HPP 10 | 11 | void suspend_boot() __attribute__((noreturn)); 12 | void suspend_kernel() __attribute__((noreturn)); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /kernel/src/arch.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "arch.hpp" 9 | 10 | extern "C" { 11 | 12 | void _arch_enable_sse(); 13 | 14 | } //end of extern "C" 15 | 16 | void arch::enable_sse(){ 17 | _arch_enable_sse(); 18 | } 19 | -------------------------------------------------------------------------------- /kernel/include/mmap.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MMAP_H 9 | #define MMAP_H 10 | 11 | #include 12 | 13 | void* mmap_phys(size_t phys, size_t size); 14 | bool munmap_phys(void* virt, size_t size); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /kernel/include/drivers/rtc.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef RTC_H 9 | #define RTC_H 10 | 11 | #include 12 | 13 | namespace rtc { 14 | 15 | rtc::datetime all_data(); 16 | 17 | } //end of rtc namespace 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tlib/include/tlib/flags.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef FLAGS_H 9 | #define FLAGS_H 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | constexpr const size_t OPEN_CREATE = 0x1; 16 | 17 | } // end of namespace 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /kernel/include/system_calls.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ATA_H 9 | #define ATA_H 10 | 11 | #include "interrupts.hpp" 12 | 13 | void system_call_entry(const interrupt::syscall_regs& regs); 14 | 15 | void install_system_calls(); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /kernel/src/kernel_utils.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "kernel_utils.hpp" 9 | #include "print.hpp" 10 | 11 | void print_stack(const char* s, size_t check){ 12 | printf("%s stack: %u (16B-a:%u) \n", s, check, static_cast(check % 16)); 13 | } 14 | -------------------------------------------------------------------------------- /kernel/include/acpi.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ACPI_HPP 9 | #define ACPI_HPP 10 | 11 | namespace acpi { 12 | 13 | void init(); 14 | bool initialized(); 15 | 16 | void shutdown(); 17 | bool reboot(); 18 | 19 | } //end of acpi namespace 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /kernel/include/gdt.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef GDT_H 9 | #define GDT_H 10 | 11 | #include "gdt_types.hpp" 12 | 13 | namespace gdt { 14 | 15 | void flush_tss(); 16 | 17 | task_state_segment_t& tss(); 18 | 19 | } //end of namespace gdt 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /kernel/include/scheduler_asm.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef SCHEDULER_H 9 | #define SCHEDULER_H 10 | 11 | extern "C" { 12 | 13 | uint64_t get_context_address(size_t pid); 14 | uint64_t get_process_cr3(size_t pid); 15 | 16 | } //end of extern "C" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /kernel/include/drivers/serial.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef SERIAL_H 9 | #define SERIAL_H 10 | 11 | namespace serial { 12 | 13 | void init(); 14 | 15 | bool is_transmit_buffer_empty(); 16 | void transmit(char a); 17 | 18 | } //end of serial namespace 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /programs/args/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | int main(int argc, char* argv[]){ 11 | for(size_t i = 0; i < size_t(argc); ++i){ 12 | tlib::printf("arg:%u:%p:%s\n", i, argv[i], argv[i]); 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /tstl/include/new.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef NEW_H 9 | #define NEW_H 10 | 11 | inline void* operator new( size_t , void* place){ 12 | return place; 13 | } 14 | 15 | inline void* operator new[]( size_t , void* place){ 16 | return place; 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /kernel/include/drivers/pit.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DRIVER_PIT_H 9 | #define DRIVER_PIT_H 10 | 11 | #include 12 | 13 | namespace pit { 14 | 15 | bool install(); 16 | void remove(); 17 | 18 | uint64_t counter(); 19 | 20 | } //end of namespace pit 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tstl/include/math.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MATH_HPP 9 | #define MATH_HPP 10 | 11 | namespace std { 12 | 13 | template 14 | T ceil_divide(T base, T divisor){ 15 | return (base + divisor - 1) / divisor; 16 | } 17 | 18 | } //end of namespace std 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /kernel/include/ioctl.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef IOCTL_HPP 9 | #define IOCTL_HPP 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | std::expected ioctl(size_t device_fd, io::ioctl_request request, void* data); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /kernel/include/drivers/hpet.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DRIVER_HPET_H 9 | #define DRIVER_HPET_H 10 | 11 | #include 12 | 13 | namespace hpet { 14 | 15 | bool install(); 16 | void late_install(); 17 | 18 | void init(); 19 | 20 | uint64_t counter(); 21 | 22 | } //end of namespace hpet 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tlib/include/tlib/ioctl_codes.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef IOCTL_CODES_H 9 | #define IOCTL_CODE_H 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | THOR_NAMESPACE(tlib, io) { 16 | 17 | enum class ioctl_request : size_t { 18 | GET_BLK_SIZE = 1 19 | }; 20 | 21 | } // end of namespace 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /kernel/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_Z11kernel_mainv) 2 | 3 | SECTIONS 4 | { 5 | /* This is where the bootloader will load the code */ 6 | . = 0x100000; 7 | 8 | /* 4K of code */ 9 | .text : ALIGN(0x1000) 10 | { 11 | *(.start) 12 | *(.text) 13 | *(.text.*) 14 | } 15 | 16 | /* 4K of Read-only data */ 17 | .rodata : ALIGN(0x1000) 18 | { 19 | *(.rodata) 20 | } 21 | 22 | /* 4K of Read-write initialized data. */ 23 | .data : ALIGN(0x1000) 24 | { 25 | *(.data) 26 | } 27 | 28 | /* 4K of Read-write uninitialized data. */ 29 | .bss : ALIGN(0x1000) 30 | { 31 | *(.bss) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kernel/src/gdt.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "gdt.hpp" 9 | #include "early_memory.hpp" 10 | 11 | void gdt::flush_tss(){ 12 | asm volatile("mov ax, %0; ltr ax;" : : "i" (gdt::TSS_SELECTOR + 0x3) : "rax"); 13 | } 14 | 15 | gdt::task_state_segment_t& gdt::tss(){ 16 | return *reinterpret_cast(early::tss_address); 17 | } 18 | -------------------------------------------------------------------------------- /tlib/Makefile: -------------------------------------------------------------------------------- 1 | default: debug/libtlib.a 2 | 3 | include ../cpp.mk 4 | 5 | $(eval $(call tlib_compile_cpp_folder,src)) 6 | $(eval $(call compile_assembly_folder,src)) 7 | 8 | # Compile the assembly code 9 | 10 | O_FILES := $(filter-out debug/src/crti.s.o,$(O_FILES)) 11 | O_FILES := $(filter-out debug/src/crtn.s.o,$(O_FILES)) 12 | 13 | debug/libtlib.a: debug/src/crti.s.o debug/src/crtn.s.o $(O_FILES) 14 | @ mkdir -p debug/ 15 | @ echo -e "$(MODE_COLOR)[debug]$(NO_COLOR) Link (tlib) $(FILE_COLOR)$@$(NO_COLOR)" 16 | @ ${AR} rcs debug/libtlib.a $(O_FILES) 17 | 18 | -include $(D_FILES) 19 | 20 | clean: 21 | @ echo -e "Remove compiled files (deps/objects)" 22 | @ rm -rf debug 23 | -------------------------------------------------------------------------------- /programs/rand/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | int main(){ 14 | std::default_random_engine engine(tlib::ms_time()); 15 | std::uniform_int_distribution<> dist(0, 100); 16 | 17 | tlib::printf("%d\n", dist(engine)); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tstl/include/cstring.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef CSTRING_H 9 | #define CSTRING_H 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | inline uint64_t str_len(const char* a){ 16 | uint64_t length = 0; 17 | while(*a++){ 18 | ++length; 19 | } 20 | return length; 21 | } 22 | 23 | } //end of namespace std 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlib/include/tlib/statfs_info.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_STATFS_INFO_HPP 9 | #define USER_STATFS_INFO_HPP 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | THOR_NAMESPACE(tlib, vfs) { 16 | 17 | struct statfs_info { 18 | size_t total_size; 19 | size_t free_size; 20 | }; 21 | 22 | } // end of namespace tlib 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /kernel/include/drivers/loopback.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LOOPBACK_H 9 | #define LOOPBACK_H 10 | 11 | #include 12 | 13 | #include "net/network.hpp" 14 | 15 | namespace loopback { 16 | 17 | void init_driver(network::interface_descriptor& interface); 18 | void finalize_driver(network::interface_descriptor& interface); 19 | 20 | } //end of namespace loopback 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /programs/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: dist default clean force_look 2 | 3 | include ../cpp.mk 4 | 5 | PROGRAMS_DIRS=$(filter-out dist/, $(filter %/, $(wildcard */))) 6 | PROGRAMS=$(PROGRAMS_DIRS:%/=%) 7 | 8 | default: dist 9 | 10 | tlib/libtlib.a: force_look 11 | cd ../tlib; $(MAKE) 12 | 13 | force_look: 14 | true 15 | 16 | dist: tlib/libtlib.a 17 | @ /bin/echo -e "$(MODE_COLOR)[debug]$(NO_COLOR) Build all programs" 18 | @ $(foreach var,$(PROGRAMS),cd $(var); $(MAKE); cd ..;) 19 | @ mkdir -p dist 20 | @ $(foreach var,$(PROGRAMS),cp $(var)/debug/$(var) dist/;) 21 | @ strip dist/* 22 | 23 | clean: 24 | @ /bin/echo -e "Clean all programs" 25 | @ $(foreach var,$(PROGRAMS),cd $(var); $(MAKE) clean; cd ..;) 26 | @ rm -rf dist 27 | -------------------------------------------------------------------------------- /kernel/include/acpica.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef THOR_ACPICA_HPP 9 | #define THOR_ACPICA_HPP 10 | 11 | extern "C" { 12 | 13 | #include "thor_acenv.hpp" 14 | #include "thor_acenvex.hpp" 15 | 16 | //ACPICA 17 | #include 18 | #include 19 | 20 | } //end of extern "C" 21 | 22 | #include 23 | 24 | constexpr const size_t FADT2_REVISION_ID = 3; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /kernel/include/syscalls.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef SYSCALLS_H 9 | #define SYSCALLS_H 10 | 11 | extern "C" { 12 | 13 | void _syscall0(); 14 | void _syscall1(); 15 | void _syscall2(); 16 | void _syscall3(); 17 | void _syscall4(); 18 | void _syscall5(); 19 | void _syscall6(); 20 | void _syscall7(); 21 | void _syscall8(); 22 | void _syscall9(); 23 | 24 | } //end of extern "C" 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tlib/src/ssp.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "tlib/print.hpp" 9 | #include "tlib/system.hpp" 10 | 11 | extern "C" { 12 | 13 | #define STACK_CHK_GUARD 0x595e9fbd94fda766 14 | 15 | uintptr_t __stack_chk_guard = STACK_CHK_GUARD; 16 | 17 | __attribute__((noreturn)) void __stack_chk_fail(){ 18 | tlib::printf("Stack smashing detected \n"); 19 | tlib::exit(1); 20 | } 21 | 22 | } // end of extern "C" 23 | -------------------------------------------------------------------------------- /tlib/include/tlib/io.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef IO_HPP 9 | #define IO_HPP 10 | 11 | #include 12 | #include 13 | 14 | #include "tlib/ioctl_codes.hpp" 15 | #include "tlib/config.hpp" 16 | 17 | ASSERT_ONLY_THOR_PROGRAM 18 | 19 | namespace tlib { 20 | 21 | int64_t ioctl(size_t device, tlib::ioctl_request request, void* data); 22 | 23 | } //end of namespace tlib 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlib/include/tlib/directory_entry.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_DIRECTORY_ENTRY_HPP 9 | #define USER_DIRECTORY_ENTRY_HPP 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | THOR_NAMESPACE(tlib, vfs) { 16 | 17 | struct directory_entry { 18 | size_t type; 19 | size_t offset_next; 20 | size_t length; 21 | char name; //First char 22 | }; 23 | 24 | } // end of namespace tlib 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /kernel/include/irqs.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef IRQS_H 9 | #define IRQS_H 10 | 11 | extern "C" { 12 | 13 | void _irq0(); 14 | void _irq1(); 15 | void _irq2(); 16 | void _irq3(); 17 | void _irq4(); 18 | void _irq5(); 19 | void _irq6(); 20 | void _irq7(); 21 | void _irq8(); 22 | void _irq9(); 23 | void _irq10(); 24 | void _irq11(); 25 | void _irq12(); 26 | void _irq13(); 27 | void _irq14(); 28 | void _irq15(); 29 | 30 | } //end of extern "C" 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /tlib/include/tlib/mount_point.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_MOUNT_POINT_HPP 9 | #define USER_MOUNT_POINT_HPP 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | THOR_NAMESPACE(tlib, vfs) { 16 | 17 | struct mount_point { 18 | size_t offset_next; 19 | size_t length_mp; 20 | size_t length_dev; 21 | size_t length_type; 22 | char name; //First char 23 | }; 24 | 25 | } // end of namespace tlib 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /kernel/include/drivers/rtl8139.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef RTL_8139_H 9 | #define RTL_8139_H 10 | 11 | #include 12 | 13 | #include "net/network.hpp" 14 | 15 | #include "drivers/pci.hpp" 16 | 17 | namespace rtl8139 { 18 | 19 | void init_driver(network::interface_descriptor& interface, pci::device_descriptor& pci_device); 20 | void finalize_driver(network::interface_descriptor& interface); 21 | 22 | } //end of namespace rtl8139 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /kernel/include/drivers/mouse.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MOUSE_HPP 9 | #define MOUSE_HPP 10 | 11 | #include 12 | 13 | namespace mouse { 14 | 15 | /*! 16 | * \brief Install the mouse driver 17 | */ 18 | void install(); 19 | 20 | /*! 21 | * \brief Returns the x position of the mouse 22 | */ 23 | uint64_t x(); 24 | 25 | /*! 26 | * \brief Returns the y position of the mouse 27 | */ 28 | uint64_t y(); 29 | 30 | } //end of namespace mouse 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /programs/dctor/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | namespace { 12 | 13 | struct A { 14 | A(){ 15 | tlib::print_line("dctor: Constructor called"); 16 | } 17 | 18 | ~A(){ 19 | tlib::print_line("dctor: Destructor called"); 20 | } 21 | }; 22 | 23 | A a; 24 | 25 | } // end of anonymous namespace 26 | 27 | int main(int, char*[]){ 28 | tlib::print_line("dctor: main function called"); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /programs/longone/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | volatile uint64_t current = 45; 11 | 12 | uint64_t fibonacci_slow(uint64_t s){ 13 | if(s == 1 || s == 2){ 14 | return current; 15 | } 16 | 17 | return fibonacci_slow(s - 1) + fibonacci_slow(s - 2); 18 | } 19 | 20 | auto message = "I'm one"; 21 | 22 | int main(){ 23 | while(true){ 24 | fibonacci_slow(current); 25 | tlib::print_line(message); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /programs/longtwo/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | volatile uint64_t current = 45; 11 | 12 | uint64_t fibonacci_slow(uint64_t s){ 13 | if(s == 1 || s == 2){ 14 | return current; 15 | } 16 | 17 | return fibonacci_slow(s - 1) + fibonacci_slow(s - 2); 18 | } 19 | 20 | auto message = "I'm two"; 21 | 22 | int main(){ 23 | while(true){ 24 | fibonacci_slow(current); 25 | tlib::print_line(message); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tlib/include/tlib/datetime.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DATETIME_H 9 | #define DATETIME_H 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | THOR_NAMESPACE(tlib, rtc) { 16 | 17 | struct datetime { 18 | uint16_t year; 19 | uint8_t month; 20 | uint8_t day; 21 | uint8_t hour; 22 | uint8_t minutes; 23 | uint8_t seconds; 24 | uint8_t unused; 25 | uint64_t precise; 26 | } __attribute__((packed)) ; 27 | 28 | } // end of namespace tlib 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /programs/date/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | int main(int, char*[]){ 12 | auto date = tlib::local_date(); 13 | 14 | tlib::print(date.day); 15 | tlib::print('.'); 16 | tlib::print(date.month); 17 | tlib::print('.'); 18 | tlib::print(date.year); 19 | tlib::print(' '); 20 | 21 | tlib::print(date.hour); 22 | tlib::print(':'); 23 | tlib::print(date.minutes); 24 | tlib::print_line(); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tlib/src/io.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "tlib/io.hpp" 9 | 10 | int64_t tlib::ioctl(size_t device, tlib::ioctl_request request, void* data){ 11 | int64_t code; 12 | asm volatile("mov rax, 0xA00; mov rbx, %[device]; mov rcx, %[request]; mov rdx, %[data]; int 50; mov %[code], rax" 13 | : [code] "=m" (code) 14 | : [device] "g" (device), [request] "g" (static_cast(request)), [data] "g" (reinterpret_cast(data)) 15 | : "rax", "rbx", "rcx", "rdx"); 16 | return code; 17 | } 18 | -------------------------------------------------------------------------------- /ci/Jenkins.groovy: -------------------------------------------------------------------------------- 1 | node { 2 | stage 'git' 3 | checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SubmoduleOption', disableSubmodules: false, recursiveSubmodules: true, reference: '', trackingSubmodules: false]], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/wichtounet/thor-os.git']]]) 4 | 5 | stage 'pre-analysis' 6 | sh 'cppcheck --xml-version=2 --enable=all --std=c++11 kernel/src kernel/include tstl/include tstl/test_suite tlib/include tlib/src printf/include tlib/include tlib/src 2> cppcheck_report.xml' 7 | sh 'sloccount --duplicates --wide --details kernel/src kernel/include tstl/include tstl/test_suite tlib/include tlib/src printf/include tlib/include tlib/src > sloccount.sc' 8 | 9 | stage 'sonar' 10 | sh '/opt/sonar-runner/bin/sonar-runner' 11 | } 12 | -------------------------------------------------------------------------------- /programs/mkdir/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char* argv[]){ 15 | if(argc == 1){ 16 | tlib::print_line("Usage: mkdir file_path"); 17 | return 1; 18 | } 19 | 20 | auto result = tlib::mkdir(argv[1]); 21 | 22 | if(result < 0){ 23 | tlib::printf("mkdir: error: %s\n", std::error_message(-result)); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /kernel/include/kalloc.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MALLOC_H 9 | #define MALLOC_H 10 | 11 | #include 12 | 13 | namespace kalloc { 14 | 15 | void init(); 16 | void finalize(); 17 | 18 | void* k_malloc(uint64_t bytes); 19 | void k_free(void* block); 20 | 21 | template 22 | T* k_malloc(){ 23 | return reinterpret_cast(k_malloc(sizeof(T))); 24 | } 25 | 26 | uint64_t allocated_memory(); 27 | uint64_t used_memory(); 28 | uint64_t allocations(); 29 | uint64_t free_memory(); 30 | 31 | void debug(); 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /programs/long/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | volatile uint64_t current = 45; 11 | 12 | uint64_t fibonacci_slow(uint64_t s){ 13 | if(s == 1 || s == 2){ 14 | return current; 15 | } 16 | 17 | return fibonacci_slow(s - 1) + fibonacci_slow(s - 2); 18 | } 19 | 20 | int main(){ 21 | uint64_t i = 0; 22 | 23 | tlib::print_line("START"); 24 | 25 | while(i < 10){ 26 | tlib::print_line(fibonacci_slow(current)); 27 | ++i; 28 | } 29 | 30 | tlib::print_line("END"); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /kernel/include/thor_acpi.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef THOR_ACPI_HPP 9 | #define THOR_ACPI_HPP 10 | 11 | // This file contains the OS specific layer for ACPICA for thor-os 12 | // It is meant to only be included by thor_acenv 13 | 14 | //thor works in 64 bits 15 | #define ACPI_MACHINE_WIDTH 64 16 | 17 | // Don't use the full debugger, only the features for debugging output 18 | #define ACPI_DEBUG_OUTPUT 19 | 20 | // Let APCICA use its own cache 21 | #define ACPI_USE_LOCAL_CACHE 22 | 23 | // Limit compatibility to ACPI 5.0 24 | #define ACPI_REDUCED_HARDWARE TRUE 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /programs/touch/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int argc, char* argv[]){ 14 | if(argc == 1){ 15 | tlib::print_line("Usage: touch file_path"); 16 | return 1; 17 | } 18 | 19 | auto fd = tlib::open(argv[1], std::OPEN_CREATE); 20 | 21 | if(fd.valid()){ 22 | tlib::close(*fd); 23 | } else { 24 | tlib::printf("touch: error: %s\n", std::error_message(fd.error())); 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tstl/include/literals.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LITERALS_HPP 9 | #define LITERALS_HPP 10 | 11 | #include 12 | 13 | static_assert(sizeof(size_t) == sizeof(unsigned long long), "Unmatching sizes for literals"); 14 | 15 | inline constexpr size_t operator"" _GiB (unsigned long long n){ 16 | return n * 1024 * 1024 * 1024; 17 | } 18 | 19 | inline constexpr size_t operator"" _MiB (unsigned long long n){ 20 | return n * 1024 * 1024; 21 | } 22 | 23 | inline constexpr size_t operator"" _KiB (unsigned long long n){ 24 | return n * 1024; 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /tlib/include/tlib/malloc.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USERLIB_MALLOC_H 9 | #define USERLIB_MALLOC_H 10 | 11 | #include "types.hpp" 12 | #include "tlib/config.hpp" 13 | 14 | ASSERT_ONLY_THOR_PROGRAM 15 | 16 | void* operator new(uint64_t size); 17 | void operator delete(void* p); 18 | 19 | void* operator new[](uint64_t size); 20 | void operator delete[](void* p); 21 | 22 | namespace tlib { 23 | 24 | void* malloc(size_t size); 25 | void free(void* pointer); 26 | 27 | size_t brk_start(); 28 | size_t brk_end(); 29 | size_t sbrk(size_t inc); 30 | 31 | } // end of tlib namespace 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /kernel/include/terminal_driver.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TERMINAL_DRIVER_H 9 | #define TERMINAL_DRIVER_H 10 | 11 | #include 12 | 13 | #include "fs/devfs.hpp" 14 | 15 | namespace stdio { 16 | 17 | struct terminal_driver final : devfs::char_driver { 18 | size_t read(void* data, char* buffer, size_t count, size_t& read) override; 19 | size_t read(void* data, char* buffer, size_t count, size_t& read, size_t ms) override; 20 | size_t write(void* data, const char* buffer, size_t count, size_t& written) override; 21 | }; 22 | 23 | } //end of namespace stdio 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /init/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(rm_main) 2 | 3 | SECTIONS 4 | { 5 | /* This is where the bootloader will load the code */ 6 | . = 0x6000; 7 | 8 | .text_16 BLOCK(512) : ALIGN(512) 9 | { 10 | debug/boot_16_64.o(.text) 11 | } 12 | 13 | .rodata_16 BLOCK(512) : ALIGN(512) 14 | { 15 | debug/boot_16_64.o(.rodata) 16 | } 17 | 18 | .bss_16 BLOCK(512) : ALIGN(512) 19 | { 20 | debug/boot_16_64.o(.bss) 21 | } 22 | 23 | .data_16 BLOCK(512) : ALIGN(512) 24 | { 25 | debug/boot_16_64.o(.data) 26 | } 27 | 28 | .text_32 BLOCK(512) : ALIGN(512) 29 | { 30 | debug/boot_32_64.o(.text) 31 | } 32 | 33 | /* 4K of Read-only data */ 34 | .rodata BLOCK(1K) : ALIGN(1K) 35 | { 36 | *(.rodata) 37 | } 38 | 39 | /* 4K of Read-write initialized data. */ 40 | .data BLOCK(1K) : ALIGN(1K) 41 | { 42 | *(.data) 43 | } 44 | 45 | /* 4K of Read-write uninitialized data. */ 46 | .bss BLOCK(1K) : ALIGN(1K) 47 | { 48 | *(.bss) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tstl/include/nth_type.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TSTL_NTH_TYPE_H 9 | #define TSTL_NTH_TYPE_H 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | template 16 | struct nth_type_impl { 17 | using type = typename nth_type_impl::type; 18 | }; 19 | 20 | template 21 | struct nth_type_impl { 22 | using type = Head; 23 | }; 24 | 25 | template 26 | using nth_type_t = typename nth_type_impl<0, I, Tail...>::type; 27 | 28 | } //end of namespace std 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /programs/keyboard/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | const char* source = "Hello world"; 11 | 12 | int main(){ 13 | char buffer[16]; 14 | 15 | tlib::printf("Read 1 string (max 15)\n"); 16 | 17 | auto c = tlib::read_input(buffer, 15); 18 | buffer[c] = '\0'; 19 | tlib::print(buffer); 20 | 21 | tlib::printf("Read 1 string (max 15) with timeout 5\n"); 22 | c = tlib::read_input(buffer, 15, 5000); 23 | 24 | if(c){ 25 | buffer[c] = '\0'; 26 | tlib::print(buffer); 27 | } else { 28 | tlib::printf("Timeout reached\n"); 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tstl/include/lock_guard.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef LOCK_GUARD_HPP 9 | #define LOCK_GUARD_HPP 10 | 11 | namespace std { 12 | 13 | template 14 | struct lock_guard { 15 | Lock& lock; 16 | 17 | explicit lock_guard(Lock& l) : lock(l) { 18 | lock.lock(); 19 | } 20 | 21 | lock_guard(const lock_guard&) = delete; 22 | lock_guard& operator=(const lock_guard&) = delete; 23 | 24 | lock_guard(lock_guard&&) = delete; 25 | lock_guard& operator=(const lock_guard&&) = delete; 26 | 27 | ~lock_guard(){ 28 | lock.unlock(); 29 | } 30 | }; 31 | 32 | } //End of namespace std 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /kernel/include/thor.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef THOR_H 9 | #define THOR_H 10 | 11 | #include 12 | 13 | void* operator new(uint64_t size); 14 | void operator delete(void* p); 15 | 16 | void* operator new[](uint64_t size); 17 | void operator delete[](void* p); 18 | 19 | #define ATEXIT_MAX_FUNCS 32 20 | 21 | extern "C" { 22 | 23 | typedef int uarch_t; 24 | 25 | struct atexit_func_entry_t { 26 | void (*destructor_func)(void *); 27 | void *obj_ptr; 28 | void *dso_handle; 29 | }; 30 | 31 | int __cxa_atexit(void (*f)(void *), void *objptr, void *dso); 32 | void __cxa_finalize(void *f); 33 | 34 | } // end of extern "C" 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /kernel/src/arch.s: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT_1_0.txt) 6 | //======================================================================= 7 | 8 | .intel_syntax noprefix 9 | 10 | // Define the base ISRs 11 | 12 | .global _arch_enable_sse 13 | 14 | _arch_enable_sse: 15 | // Test if SSE is supported by the processor 16 | mov eax, 0x1 17 | cpuid 18 | test edx, 1<<25 19 | jz .no_sse 20 | 21 | // Enable SSE support 22 | xor rax, rax 23 | mov rax, cr0 24 | and ax, 0xFFFB // clear coprocessor emulation CR0.EM 25 | or ax, 0x2 // set coprocessor monitoring CR0.MP 26 | mov cr0, rax 27 | mov rax, cr4 28 | or ax, 3 << 9 // set CR4.OSFXSR and CR4.OSXMMEXCPT 29 | mov cr4, rax 30 | 31 | .no_sse: 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tstl/include/enable_if.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ENABLE_IF_H 9 | #define ENABLE_IF_H 10 | 11 | namespace std { 12 | 13 | template 14 | struct enable_if {}; 15 | 16 | template 17 | struct enable_if { typedef T type; }; 18 | 19 | template< bool B, class T = void > 20 | using enable_if_t = typename enable_if::type; 21 | 22 | template 23 | struct disable_if {}; 24 | 25 | template 26 | struct disable_if { typedef T type; }; 27 | 28 | template< bool B, class T = void > 29 | using disable_if_t = typename disable_if::type; 30 | 31 | } //end of namespace std 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /tstl/test_suite/expected.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "test.hpp" 14 | 15 | namespace { 16 | 17 | struct kiss { 18 | int* ref; 19 | kiss(){} 20 | kiss(int* ref) : ref(ref) {} 21 | ~kiss(){ 22 | ++(*ref); 23 | } 24 | }; 25 | 26 | void test_destructor() { 27 | int counter = 0; 28 | kiss k(&counter); 29 | 30 | { 31 | auto e = std::make_expected(k); 32 | } 33 | 34 | check_equals(counter, 1, "destruct: Invalid destructors"); 35 | } 36 | 37 | } //end of anonymous namespace 38 | 39 | void expected_tests(){ 40 | test_destructor(); 41 | } 42 | -------------------------------------------------------------------------------- /kernel/include/e820.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | /* 9 | * The implementation of the memory detection is made in boot_16.cpp 10 | * The finalization of the memory detection is made in e820.cpp once in long 11 | * mode. 12 | */ 13 | 14 | #ifndef E820_HPP 15 | #define E820_HPP 16 | 17 | #include "e820_types.hpp" 18 | 19 | namespace e820 { 20 | 21 | //Must be called by the kernel to transform e820 entries into mmap entries 22 | void finalize_memory_detection(); 23 | 24 | bool mmap_failed(); 25 | uint64_t mmap_entry_count(); 26 | const mmapentry& mmap_entry(uint64_t i); 27 | const char* str_e820_type(uint64_t type); 28 | 29 | size_t available_memory(); 30 | 31 | } //end of namespace e820 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /tlib/include/tlib/stat_info.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_STAT_INFO_HPP 9 | #define USER_STAT_INFO_HPP 10 | 11 | #include 12 | 13 | #include "tlib/datetime.hpp" 14 | #include "tlib/config.hpp" 15 | 16 | THOR_NAMESPACE(tlib, vfs) { 17 | 18 | using datetime = THOR_NAMESPACE_NAME(tlib, rtc)::datetime; 19 | 20 | constexpr const size_t STAT_FLAG_DIRECTORY = 1 << 0; 21 | constexpr const size_t STAT_FLAG_HIDDEN = 1 << 1; 22 | constexpr const size_t STAT_FLAG_SYSTEM = 1 << 2; 23 | 24 | struct stat_info { 25 | size_t flags; 26 | size_t size; 27 | datetime created; 28 | datetime modified; 29 | datetime accessed; 30 | }; 31 | 32 | } // end of namespace tlib 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tlib/include/tlib/graphics.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef GRAPHICS_HPP 9 | #define GRAPHICS_HPP 10 | 11 | #include 12 | 13 | #include "tlib/config.hpp" 14 | 15 | ASSERT_ONLY_THOR_PROGRAM 16 | 17 | namespace tlib { 18 | 19 | namespace graphics { 20 | 21 | uint64_t get_width(); 22 | uint64_t get_height(); 23 | 24 | uint64_t get_x_shift(); 25 | uint64_t get_y_shift(); 26 | 27 | uint64_t get_bytes_per_scan_line(); 28 | 29 | uint64_t get_red_shift(); 30 | uint64_t get_green_shift(); 31 | uint64_t get_blue_shift(); 32 | 33 | uint64_t mouse_x(); 34 | uint64_t mouse_y(); 35 | 36 | void redraw(char* buffer); 37 | 38 | } // end of namespace graphics 39 | 40 | } // end of namespace tlib 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /kernel/include/arch.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ARCH_H 9 | #define ARCH_H 10 | 11 | #include 12 | 13 | namespace arch { 14 | 15 | void enable_sse(); 16 | 17 | inline size_t get_rflags(){ 18 | size_t rflags; 19 | asm volatile("pushfq; pop %0;" : "=g" (rflags)); 20 | return rflags; 21 | } 22 | 23 | inline void disable_hwint(size_t& rflags){ 24 | asm volatile("pushfq; pop %0; cli;" : "=g" (rflags)); 25 | } 26 | 27 | inline void enable_hwint(size_t& rflags){ 28 | asm volatile("push %0; popfq; " :: "g" (rflags)); 29 | } 30 | 31 | inline bool interrupts_enabled(){ 32 | auto flags = get_rflags(); 33 | return flags & 0x200; 34 | } 35 | 36 | } //enf of arch namespace 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /kernel/src/ioctl.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | #include "ioctl.hpp" 11 | #include "scheduler.hpp" 12 | #include "logging.hpp" 13 | #include "fs/devfs.hpp" 14 | 15 | std::expected ioctl(size_t device_fd, io::ioctl_request request, void* data){ 16 | if(!scheduler::has_handle(device_fd)){ 17 | return std::make_unexpected(std::ERROR_INVALID_FILE_DESCRIPTOR); 18 | } 19 | 20 | auto& device = scheduler::get_handle(device_fd); 21 | 22 | if(request == io::ioctl_request::GET_BLK_SIZE){ 23 | return devfs::get_device_size(device, *reinterpret_cast(data)); 24 | } 25 | 26 | return std::make_unexpected(std::ERROR_INVALID_REQUEST); 27 | } 28 | -------------------------------------------------------------------------------- /programs/rm/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char* argv[]){ 15 | if(argc == 1){ 16 | tlib::print_line("Usage: rm file_path"); 17 | return 1; 18 | } 19 | 20 | auto fd = tlib::open(argv[1]); 21 | 22 | if(fd.valid()){ 23 | auto result = tlib::rm(argv[1]); 24 | 25 | if(result < 0){ 26 | tlib::printf("rm: error: %s\n", std::error_message(-result)); 27 | } 28 | 29 | tlib::close(*fd); 30 | } else { 31 | tlib::printf("rm: error: %s\n", std::error_message(fd.error())); 32 | } 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /kernel/include/isrs.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ISRS_H 9 | #define ISRS_H 10 | 11 | extern "C" { 12 | 13 | void _isr0(); 14 | void _isr1(); 15 | void _isr2(); 16 | void _isr3(); 17 | void _isr4(); 18 | void _isr5(); 19 | void _isr6(); 20 | void _isr7(); 21 | void _isr8(); 22 | void _isr9(); 23 | void _isr10(); 24 | void _isr11(); 25 | void _isr12(); 26 | void _isr13(); 27 | void _isr14(); 28 | void _isr15(); 29 | void _isr16(); 30 | void _isr17(); 31 | void _isr18(); 32 | void _isr19(); 33 | void _isr20(); 34 | void _isr21(); 35 | void _isr22(); 36 | void _isr23(); 37 | void _isr24(); 38 | void _isr25(); 39 | void _isr26(); 40 | void _isr27(); 41 | void _isr28(); 42 | void _isr29(); 43 | void _isr30(); 44 | void _isr31(); 45 | 46 | } //end of extern "C" 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /kernel/include/e820_types.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | /* 9 | * The implementation of the memory detection is made in boot_16.cpp 10 | * The finalization of the memory detection is made in e820.cpp once in long 11 | * mode. 12 | */ 13 | 14 | #ifndef E820_TYPES_HPP 15 | #define E820_TYPES_HPP 16 | 17 | #include 18 | 19 | namespace e820 { 20 | 21 | constexpr const uint32_t MAX_E820_ENTRIES = 20; 22 | 23 | struct bios_e820_entry { 24 | uint32_t base_low; 25 | uint32_t base_high; 26 | uint32_t length_low; 27 | uint32_t length_high; 28 | uint16_t type; 29 | uint16_t acpi; 30 | } __attribute__((packed)); 31 | 32 | struct mmapentry { 33 | uint64_t base; 34 | uint64_t size; 35 | uint64_t type; 36 | }; 37 | 38 | } //end of namespace e820 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /kernel/include/assert.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ASSERT_HPP 9 | #define ASSERT_HPP 10 | 11 | void __thor_assert(bool condition); 12 | void __thor_assert(bool condition, const char* message); 13 | void __thor_unreachable(const char* message); 14 | 15 | #ifdef NASSERT 16 | inline void thor_assert(bool){} 17 | inline void thor_assert(bool, const char*){} 18 | #else 19 | inline void thor_assert(bool condition){ 20 | __thor_assert(condition); 21 | } 22 | 23 | inline void thor_assert(bool condition, const char* message){ 24 | __thor_assert(condition, message); 25 | } 26 | #endif 27 | 28 | inline void thor_unreachable(const char* message) __attribute__((noreturn)); 29 | inline void thor_unreachable(const char* message){ 30 | __thor_unreachable(message); 31 | __builtin_unreachable(); 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /kernel/include/vfs/file.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VFS_FILE_H 9 | #define VFS_FILE_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace vfs { 17 | 18 | struct file { 19 | std::string file_name; 20 | bool directory; 21 | bool hidden; 22 | bool system; 23 | uint64_t size; 24 | rtc::datetime created; 25 | rtc::datetime modified; 26 | rtc::datetime accessed; 27 | 28 | //File system specific 29 | size_t location; 30 | size_t position; 31 | 32 | file(){}; 33 | file(std::string file_name, bool directory, bool hidden, bool system, uint64_t size) 34 | : file_name(file_name), directory(directory), hidden(hidden), system(system), size(size) {}; 35 | }; 36 | 37 | } //end of namespace vfs 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015 Baptiste Wicht 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /kernel/include/logging.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifndef LOGGING_HPP 13 | #define LOGGING_HPP 14 | 15 | namespace logging { 16 | 17 | enum class log_level : char { 18 | TRACE, 19 | DEBUG, 20 | WARNING, 21 | ERROR, 22 | USER 23 | }; 24 | 25 | bool is_early(); 26 | bool is_file(); 27 | void finalize(); 28 | void to_file(); 29 | 30 | void log(log_level level, const char* s); 31 | void log(log_level level, const std::string& s); 32 | void logf(log_level level, const char* s, va_list va); 33 | void logf(log_level level, const char* s, ...); 34 | 35 | void log(const char* s); 36 | void log(const std::string& s); 37 | void logf(const char* s, va_list va); 38 | void logf(const char* s, ...); 39 | 40 | } //end of namespace logging 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /printf/include/printf_dec.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | //Is made to be included as is in a header file 9 | // 10 | //Implement is provided in printf_def.hpp which must be included in 11 | //source file 12 | 13 | std::string sprintf(const std::string& format, ...); 14 | std::string vsprintf(const std::string& format, va_list va); 15 | 16 | void printf(const std::string& format, ...); 17 | void vprintf(const std::string& format, va_list va); 18 | 19 | void sprintf_raw(char* buffer, size_t n, const char* format, ...); 20 | void vsprintf_raw(char* buffer, size_t n, const char* format, va_list va); 21 | 22 | void printf_raw(const char* format, ...); 23 | void vprintf_raw(const char* format, va_list va); 24 | 25 | //Definition of these functions must be provided 26 | void __printf(const std::string& formatted); 27 | void __printf_raw(const char* formatted); 28 | -------------------------------------------------------------------------------- /tools/font_convert.tmpl: -------------------------------------------------------------------------------- 1 | $(start_block_header) 2 | /******************************************************************************* 3 | * $(doc_data_type) 4 | * filename: $(doc_filename) 5 | * name: $(doc_name) 6 | * family: $(fnt_family) 7 | * size: $(fnt_size) 8 | * style: $(fnt_style) 9 | * antialiasing: $(fnt_antialiasing) 10 | * type: $(fnt_width_type) 11 | * encoding: $(fnt_encoding) 12 | * unicode bom: $(fnt_use_bom) 13 | * 14 | * preset name: $(out_preset_name) 15 | * data block size: $(img_data_block_size) bit(s), uint$(img_data_block_size)_t 16 | * RLE compression enabled: $(img_rle) 17 | * conversion type: $(pre_conv_type), $(pre_mono_type) $(pre_mono_edge) 18 | * bits per pixel: $(out_bpp) 19 | * 20 | * preprocess: 21 | * main scan direction: $(pre_scan_main) 22 | * line scan direction: $(pre_scan_sub) 23 | * inverse: $(pre_inverse) 24 | *******************************************************************************/ 25 | 26 | $(end_block_header) 27 | 28 | static const uint$(img_data_block_size)_t $(doc_name_ws)_data[256 * $(out_images_max_height)] = { 29 | $(start_block_images_table) 30 | $(out_image_data), //'$(out_char_text)' 31 | $(end_block_images_table) 32 | }; -------------------------------------------------------------------------------- /kernel/include/drivers/ramdisk.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef RAMDISK_H 9 | #define RAMDISK_H 10 | 11 | #include 12 | 13 | #include "fs/devfs.hpp" 14 | 15 | namespace ramdisk { 16 | 17 | struct disk_descriptor { 18 | uint64_t id; 19 | uint64_t max_size; 20 | uint64_t pages; 21 | char** allocated; 22 | }; 23 | 24 | disk_descriptor* make_disk(uint64_t max_size); 25 | 26 | struct ramdisk_driver final : devfs::dev_driver { 27 | size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read) override; 28 | size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written) override; 29 | size_t clear(void* data, size_t count, size_t offset, size_t& written) override; 30 | size_t size(void* data) override; 31 | }; 32 | 33 | } // end of namespace ramdisk 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=thor 2 | sonar.projectName=thor 3 | sonar.projectVersion=0.1-beta 4 | 5 | sonar.cxx.suffixes.headers=.hpp,.inl 6 | sonar.sources=programs,tlib,tstl,kernel/include,kernel/src,init,printf 7 | sonar.language=c++ 8 | 9 | # Reports file for sonar-cxx 10 | sonar.cxx.cppcheck.reportPath=cppcheck_report.xml 11 | 12 | # Declare list of ignore filters 13 | sonar.issue.ignore.multicriteria=noapiprograms,noapiprintf,noapikeycode 14 | 15 | # Ignore all undocumented API issues on programs 16 | sonar.issue.ignore.multicriteria.noapiprograms.ruleKey=cxx:UndocumentedApi 17 | sonar.issue.ignore.multicriteria.noapiprograms.resourceKey=programs/**/* 18 | 19 | # Ignore all undocumented API issues on printf_def (for some reasons, Sonar is going crazy) 20 | sonar.issue.ignore.multicriteria.noapiprintf.ruleKey=cxx:UndocumentedApi 21 | sonar.issue.ignore.multicriteria.noapiprintf.resourceKey=printf/include/printf_def.hpp 22 | 23 | # Ignore all undocumented API issues on keycode.hpp (no reason to document that) 24 | sonar.issue.ignore.multicriteria.noapikeycode.ruleKey=cxx:UndocumentedApi 25 | sonar.issue.ignore.multicriteria.noapikeycode.resourceKey=tlib/include/tlib/keycode.hpp 26 | -------------------------------------------------------------------------------- /kernel/src/drivers/serial.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "drivers/serial.hpp" 9 | 10 | #include "kernel_utils.hpp" 11 | 12 | #define COM1_PORT 0x3f8 13 | 14 | void serial::init() { 15 | out_byte(COM1_PORT + 1, 0x00); // Disable all interrupts 16 | out_byte(COM1_PORT + 3, 0x80); // Enable DLAB 17 | out_byte(COM1_PORT + 0, 0x03); // 38400 baud 18 | out_byte(COM1_PORT + 1, 0x00); 19 | out_byte(COM1_PORT + 3, 0x03); // 8 bits, no parity, one stop bit 20 | out_byte(COM1_PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold 21 | out_byte(COM1_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set 22 | } 23 | 24 | bool serial::is_transmit_buffer_empty() { 25 | return in_byte(COM1_PORT + 5) & 0x20; 26 | } 27 | 28 | void serial::transmit(char a) { 29 | while (is_transmit_buffer_empty() == 0){} 30 | 31 | out_byte(COM1_PORT,a); 32 | } 33 | -------------------------------------------------------------------------------- /tstl/include/deleter.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DELETER_H 9 | #define DELETER_H 10 | 11 | namespace std { 12 | 13 | template 14 | struct default_delete { 15 | constexpr default_delete() = default; 16 | 17 | constexpr default_delete(const default_delete&) = default; 18 | 19 | void operator()(T* ptr) const { 20 | static_assert(sizeof(T) > 0, "Type must be complete"); 21 | delete ptr; 22 | } 23 | }; 24 | 25 | //Partial specialization for arrays 26 | template 27 | struct default_delete { 28 | constexpr default_delete() = default; 29 | 30 | constexpr default_delete(const default_delete&) = default; 31 | 32 | void operator()(T* ptr) const { 33 | static_assert(sizeof(T) > 0, "Type must be complete"); 34 | delete[] ptr; 35 | } 36 | }; 37 | 38 | } //end of namespace std 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /init/Makefile: -------------------------------------------------------------------------------- 1 | default: debug/init.bin 2 | 3 | include ../cpp.mk 4 | 5 | # Compile the 16-bit and 32-bit parts of the executable 6 | 7 | INIT_FLAGS=-I../kernel/include 8 | 9 | debug/boot_16.o: src/boot_16.cpp 10 | @ mkdir -p debug/ 11 | $(CXX) $(COMMON_CPP_FLAGS) $(FLAGS_16) $(INIT_FLAGS) $(WARNING_FLAGS) -c src/boot_16.cpp -o debug/boot_16.o 12 | 13 | debug/boot_32.o: src/boot_32.cpp 14 | @ mkdir -p debug/ 15 | $(CXX) $(COMMON_CPP_FLAGS) $(FLAGS_32) $(INIT_FLAGS) $(WARNING_FLAGS) -c src/boot_32.cpp -o debug/boot_32.o 16 | 17 | debug/boot_16_64.o: debug/boot_16.o 18 | $(OC) -I elf32-i386 -O elf64-x86-64 debug/boot_16.o debug/boot_16_64.o 19 | 20 | debug/boot_32_64.o: debug/boot_32.o 21 | $(OC) -I elf32-i386 -O elf64-x86-64 debug/boot_32.o debug/boot_32_64.o 22 | 23 | LINK_O_FILES=debug/boot_16_64.o debug/boot_32_64.o 24 | 25 | debug/init.bin: $(LINK_O_FILES) 26 | @ echo -e "$(MODE_COLOR)[debug]$(NO_COLOR) Link $(FILE_COLOR)$@$(NO_COLOR)" 27 | $(CXX) $(KERNEL_LINK_FLAGS) $(KERNEL_CPP_FLAGS_64) -o $@.o $(LINK_O_FILES) 28 | $(OC) -R .note -R .comment -O binary --set-section-flags .bss=alloc,load,contents $@.o $@ 29 | 30 | clean: 31 | @ echo -e "Remove compiled files (deps/objects)" 32 | @ rm -rf debug 33 | -------------------------------------------------------------------------------- /kernel/include/drivers/keyboard.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef KEYBOARD_H 9 | #define KEYBOARD_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace keyboard { 16 | 17 | const char KEY_ENTER = 0x1C; 18 | const char KEY_BACKSPACE = 0x0E; 19 | const char KEY_UP = 0x48; 20 | const char KEY_DOWN = 0x50; 21 | const char KEY_LEFT_SHIFT = 0x2A; 22 | const char KEY_RIGHT_SHIFT = 0x36; 23 | const char KEY_LEFT_CTRL = 0x1D; 24 | const char KEY_ALT = 56; 25 | const char KEY_F1 = 59; 26 | const char KEY_F2 = 60; 27 | const char KEY_F3 = 61; 28 | 29 | /*! 30 | * \brief Install the keyboard driver 31 | */ 32 | void install_driver(); 33 | 34 | char key_to_ascii(uint8_t key); 35 | char shift_key_to_ascii(uint8_t key); 36 | 37 | std::keycode raw_key_to_keycode(uint8_t key); 38 | 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /programs/which/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int argc, char* argv[]){ 14 | if(argc == 1){ 15 | tlib::print_line("Usage: which executable_path"); 16 | return 1; 17 | } 18 | 19 | std::string path(argv[1]); 20 | 21 | if(path[0] != '/'){ 22 | path = "/bin/" + path; 23 | } 24 | 25 | auto fd = tlib::open(path.c_str()); 26 | 27 | if(fd.valid()){ 28 | tlib::print_line(path); 29 | 30 | tlib::close(*fd); 31 | } else { 32 | if(fd.has_error(std::ERROR_NOT_EXISTS)){ 33 | tlib::printf("%s not found\n", argv[1]); 34 | } else { 35 | tlib::printf("which: error: %s\n", std::error_message(fd.error())); 36 | } 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tstl/include/utility.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef UTILITY_H 9 | #define UTILITY_H 10 | 11 | #include "type_traits.hpp" 12 | 13 | namespace std { 14 | 15 | template 16 | constexpr typename remove_reference::type&& move(T&& t){ 17 | return static_cast::type&&>(t); 18 | } 19 | 20 | template 21 | constexpr T&& forward(typename remove_reference::type& t ){ 22 | return static_cast(t); 23 | } 24 | 25 | template 26 | constexpr T&& forward(typename remove_reference::type&& t ){ 27 | return static_cast(t); 28 | } 29 | 30 | template 31 | void swap (T& a, T& b){ 32 | T c(std::move(a)); 33 | a = std::move(b); 34 | b = std::move(c); 35 | } 36 | 37 | template 38 | typename std::add_rvalue_reference::type declval(); 39 | 40 | } //end of namespace std 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /kernel/src/irqs.s: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT_1_0.txt) 6 | //======================================================================= 7 | 8 | .intel_syntax noprefix 9 | 10 | .include "src/common.s" 11 | 12 | .macro create_irq number 13 | .global _irq\number 14 | _irq\number: 15 | push rax 16 | push \number 17 | 18 | jmp irq_common_handler 19 | .endm 20 | 21 | create_irq 0 22 | create_irq 1 23 | create_irq 2 24 | create_irq 3 25 | create_irq 4 26 | create_irq 5 27 | create_irq 6 28 | create_irq 7 29 | create_irq 8 30 | create_irq 9 31 | create_irq 10 32 | create_irq 11 33 | create_irq 12 34 | create_irq 13 35 | create_irq 14 36 | create_irq 15 37 | 38 | // Common handler 39 | 40 | irq_common_handler: 41 | save_context 42 | 43 | restore_kernel_segments 44 | 45 | mov rdi, rsp 46 | call _irq_handler 47 | 48 | restore_context 49 | 50 | //Was pushed by the base handler code 51 | add rsp, 16 52 | 53 | iretq // iret will clean the other automatically pushed stuff 54 | -------------------------------------------------------------------------------- /tlib/include/tlib/dns.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TLIB_NET_DNS_H 9 | #define TLIB_NET_DNS_H 10 | 11 | #include 12 | 13 | #include "tlib/net_constants.hpp" 14 | #include "tlib/net.hpp" 15 | 16 | ASSERT_ONLY_THOR_PROGRAM 17 | 18 | namespace tlib { 19 | 20 | namespace dns { 21 | 22 | std::string decode_domain(char* payload, size_t& offset); 23 | std::expected send_request(tlib::socket& sock, const std::string& domain, uint16_t rr_type = 0x1, uint16_t rr_class = 0x1); 24 | 25 | std::expected resolve(const std::string& domain, size_t timeout = 1000, size_t retries = 1); 26 | std::expected resolve_str(const std::string& domain, size_t timeout = 1000, size_t retries = 1); 27 | 28 | tlib::ip::address gateway_address(); 29 | 30 | bool is_ip(const std::string& value); 31 | 32 | } // end of namespace dns 33 | 34 | } // end of namespace tlib 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tstl/test_suite/test.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | #define CHECK(cond, message) check(cond, message, __PRETTY_FUNCTION__, __LINE__) 12 | #define CHECK_EQUALS(a, b, message) check_equals(a, b, message, __PRETTY_FUNCTION__, __LINE__) 13 | 14 | #define CHECK_DIRECT(cond) check(cond, __PRETTY_FUNCTION__, __LINE__) 15 | #define CHECK_EQUALS_DIRECT(a, b) check_equals(a, b, __PRETTY_FUNCTION__, __LINE__) 16 | 17 | void check(bool condition); 18 | void check(bool condition, const char* message); 19 | void check_equals(long value, long expected, const char* message); 20 | 21 | void check(bool condition, const char* where, size_t line); 22 | void check(bool condition, const char* message, const char* where, size_t line); 23 | void check_equals(long value, long expected, const char* message, const char* where, size_t line); 24 | void check_equals(long value, long expected, const char* where, size_t line); 25 | -------------------------------------------------------------------------------- /kernel/src/assert.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "assert.hpp" 9 | 10 | #ifndef THOR_NO_ASSERT 11 | #include "print.hpp" 12 | #include "kernel.hpp" 13 | #include "logging.hpp" 14 | #endif 15 | 16 | void __thor_assert(bool condition){ 17 | __thor_assert(condition, "assertion failed"); 18 | } 19 | 20 | void __thor_assert(bool condition, const char* message){ 21 | #ifndef THOR_NO_ASSERT 22 | if(!condition){ 23 | logging::logf(logging::log_level::ERROR, "Assertion failed: %s\n", message); 24 | k_print_line(message); 25 | suspend_kernel(); 26 | } 27 | #else 28 | (void) condition; 29 | (void) message; 30 | #endif 31 | } 32 | 33 | void __thor_unreachable(const char* message){ 34 | #ifndef THOR_NO_ASSERT 35 | logging::logf(logging::log_level::ERROR, "Reached unreachable block: %s\n", message); 36 | k_print_line(message); 37 | suspend_kernel(); 38 | #else 39 | (void) message; 40 | #endif 41 | } 42 | -------------------------------------------------------------------------------- /kernel/include/disks.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DISKS_H 9 | #define DISKS_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "vfs/vfs.hpp" 19 | #include "vfs/file.hpp" 20 | 21 | namespace disks { 22 | 23 | enum class disk_type { 24 | ATA, 25 | ATAPI, 26 | RAM 27 | }; 28 | 29 | struct disk_descriptor { 30 | uint64_t uuid; 31 | disk_type type; 32 | void* descriptor; 33 | }; 34 | 35 | struct partition_descriptor { 36 | uint64_t uuid; 37 | vfs::partition_type type; 38 | uint64_t start; 39 | uint64_t sectors; 40 | disk_descriptor* disk; 41 | }; 42 | 43 | void detect_disks(); 44 | 45 | disk_descriptor& disk_by_index(uint64_t index); 46 | disk_descriptor& disk_by_uuid(uint64_t uuid); 47 | 48 | std::unique_heap_array partitions(disk_descriptor& disk); 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /tlib/include/tlib/system.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_SYSTEM_HPP 9 | #define USER_SYSTEM_HPP 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "tlib/datetime.hpp" 17 | #include "tlib/config.hpp" 18 | 19 | ASSERT_ONLY_THOR_PROGRAM 20 | 21 | namespace tlib { 22 | 23 | void exit(size_t return_code) __attribute__((noreturn)); 24 | 25 | std::expected exec(const char* executable, const std::vector& params = {}); 26 | std::expected exec_and_wait(const char* executable, const std::vector& params = {}); 27 | 28 | void await_termination(size_t pid); 29 | 30 | void sleep_ms(size_t ms); 31 | 32 | datetime local_date(); 33 | 34 | void reboot(unsigned int delay = 0); 35 | void shutdown(unsigned int delay = 0); 36 | 37 | uint64_t s_time(); 38 | uint64_t ms_time(); 39 | 40 | void alpha(); 41 | 42 | } // end of tlib namespace 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /kernel/src/syscalls.s: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT_1_0.txt) 6 | //======================================================================= 7 | 8 | .intel_syntax noprefix 9 | 10 | .include "src/common.s" 11 | 12 | // Define the base ISRs 13 | 14 | .macro create_syscall number 15 | .global _syscall\number 16 | _syscall\number: 17 | //Interrupts are disabled on interrupt gate, 18 | //so they must reenabled again 19 | sti 20 | 21 | push rax 22 | push \number 23 | 24 | jmp syscall_common_handler 25 | .endm 26 | 27 | create_syscall 0 28 | create_syscall 1 29 | create_syscall 2 30 | create_syscall 3 31 | create_syscall 4 32 | create_syscall 5 33 | create_syscall 6 34 | create_syscall 7 35 | create_syscall 8 36 | create_syscall 9 37 | 38 | syscall_common_handler: 39 | save_context 40 | 41 | restore_kernel_segments 42 | 43 | mov rdi, rsp 44 | call _syscall_handler 45 | 46 | restore_context 47 | 48 | //Was pushed by the base handler code 49 | add rsp, 16 50 | 51 | iretq // iret will clean the other automatically pushed stuff 52 | -------------------------------------------------------------------------------- /kernel/include/stdio.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STDIO_H 9 | #define STDIO_H 10 | 11 | #include 12 | 13 | #include "terminal.hpp" 14 | 15 | namespace stdio { 16 | 17 | /*! 18 | * \brief Initialize the terminals 19 | */ 20 | void init_terminals(); 21 | 22 | /*! 23 | * \brief Register the devices into the devfs 24 | */ 25 | void register_devices(); 26 | 27 | /*! 28 | * \brief Finalize the terminals 29 | */ 30 | void finalize(); 31 | 32 | /*! 33 | * \brief Switch the active terminal to the terminal with the given id 34 | * \param id The terminal to activate 35 | */ 36 | void switch_terminal(size_t id); 37 | 38 | /*! 39 | * \brief Returns the number of terminals 40 | */ 41 | size_t terminals_count(); 42 | 43 | /*! 44 | * \brief Returns the active terminal 45 | */ 46 | virtual_terminal& get_active_terminal(); 47 | 48 | /*! 49 | * \brief Returns the terminal with the given id 50 | */ 51 | virtual_terminal& get_terminal(size_t id); 52 | 53 | } //end of namespace stdio 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /kernel/include/text_console.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TEXT_CONSOLE_H 9 | #define TEXT_CONSOLE_H 10 | 11 | #include 12 | 13 | /*! 14 | * \brief A textual console 15 | */ 16 | struct text_console { 17 | /*! 18 | * \brief Initialize the console 19 | */ 20 | void init(); 21 | 22 | /*! 23 | * \brief Returns the number of lines of the console 24 | */ 25 | size_t lines(); 26 | 27 | /*! 28 | * \brief Returns the number of columns of the console 29 | */ 30 | size_t columns(); 31 | 32 | /*! 33 | * \brief Clear the text console 34 | */ 35 | void clear(); 36 | 37 | /*! 38 | * \brief Scroll up one line 39 | */ 40 | void scroll_up(); 41 | 42 | /*! 43 | * \brief Print a char at the given line and column 44 | * \param line The line at which to print the char 45 | * \param column The column at which to print the char 46 | * \param c The char to print 47 | */ 48 | void print_char(size_t line, size_t column, char c); 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /kernel/include/print.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PRINT_H 9 | #define PRINT_H 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | void k_print(char key); 18 | void k_print(const char* string); 19 | void k_print(const char* string, uint64_t end); 20 | 21 | void k_print(const std::string& s); 22 | 23 | void k_print(uint8_t number); 24 | void k_print(uint16_t number); 25 | void k_print(uint32_t number); 26 | void k_print(uint64_t number); 27 | 28 | void k_print(int8_t number); 29 | void k_print(int16_t number); 30 | void k_print(int32_t number); 31 | void k_print(int64_t number); 32 | 33 | template 34 | typename std::enable_if_t<(sizeof...(Arguments) == 0)> k_print_line(const Arguments&... args){ 35 | k_print('\n'); 36 | } 37 | 38 | template 39 | typename std::enable_if_t<(sizeof...(Arguments) > 0)> k_print_line(const Arguments&... args){ 40 | k_print(args...); 41 | k_print('\n'); 42 | } 43 | 44 | #include "printf_dec.hpp" 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /kernel/include/net/checksum.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef NET_CHECKSUM_H 9 | #define NET_CHECKSUM_H 10 | 11 | #include 12 | 13 | namespace network { 14 | 15 | template 16 | uint32_t checksum_add_bytes(T* values, size_t length){ 17 | auto raw_values = reinterpret_cast(values); 18 | 19 | uint32_t sum = 0; 20 | 21 | for(size_t i = 0; i < length; ++i){ 22 | if(i & 1){ 23 | sum += static_cast(raw_values[i]); 24 | } else { 25 | sum += static_cast(raw_values[i]) << 8; 26 | } 27 | } 28 | 29 | return sum; 30 | } 31 | 32 | inline uint16_t checksum_finalize(uint32_t sum){ 33 | while(sum >> 16){ 34 | sum = (sum & 0xFFFF) + (sum >> 16); 35 | } 36 | 37 | return ~sum; 38 | } 39 | 40 | inline uint16_t checksum_finalize_nz(uint32_t sum){ 41 | auto checksum = checksum_finalize(sum); 42 | 43 | if(!checksum){ 44 | return ~checksum; 45 | } else { 46 | return checksum; 47 | } 48 | } 49 | 50 | } // end of network namespace 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /kernel/include/drivers/ata_constants.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ATA_CONSTANTS_HPP 9 | #define ATA_CONSTANTS_HPP 10 | 11 | #include 12 | 13 | //IDE Controllers 14 | #define ATA_PRIMARY 0x1F0 15 | #define ATA_SECONDARY 0x170 16 | 17 | // I/O Controllers ports 18 | #define ATA_DATA 0 19 | #define ATA_ERROR 1 20 | #define ATA_NSECTOR 2 21 | #define ATA_SECTOR 3 22 | #define ATA_LCYL 4 23 | #define ATA_HCYL 5 24 | #define ATA_DRV_HEAD 6 25 | #define ATA_STATUS 7 26 | #define ATA_COMMAND 7 27 | #define ATA_DEV_CTL 0x206 28 | 29 | // Status bits 30 | #define ATA_STATUS_BSY 0x80 31 | #define ATA_STATUS_DRDY 0x40 32 | #define ATA_STATUS_DRQ 0x08 33 | #define ATA_STATUS_ERR 0x01 34 | #define ATA_STATUS_DF 0x20 35 | 36 | // Commands 37 | #define ATA_IDENTIFY 0xEC 38 | #define ATAPI_IDENTIFY 0xA1 39 | #define ATA_READ_BLOCK 0x20 40 | #define ATA_WRITE_BLOCK 0x30 41 | 42 | #define ATA_CTL_SRST 0x04 43 | #define ATA_CTL_nIEN 0x02 44 | 45 | //Master/Slave on devices 46 | #define MASTER_BIT 0 47 | #define SLAVE_BIT 1 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /kernel/include/virtual_debug.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VIRTUAL_DEBUG_H 9 | #define VIRTUAL_DEBUG_H 10 | 11 | //TODO Integrate Bochs Parallel debugging 12 | 13 | #include "kernel_utils.hpp" 14 | 15 | #ifdef THOR_INIT 16 | void serial_transmit(char a); 17 | #else 18 | #include "drivers/serial.hpp" 19 | #endif 20 | 21 | #define BOCHS_E9 0xE9 22 | 23 | inline bool is_bochs_e9(){ 24 | auto e9 = in_byte(0xe9); 25 | return e9 == BOCHS_E9; 26 | } 27 | 28 | inline void bochs_print_char(char c){ 29 | out_byte(BOCHS_E9, c); 30 | } 31 | 32 | inline void bochs_print(const char* s){ 33 | for(uint64_t i = 0; s[i] != '\0'; ++i){ 34 | bochs_print_char(s[i]); 35 | } 36 | } 37 | 38 | inline void serial_print(const char* s){ 39 | for(uint64_t i = 0; s[i] != '\0'; ++i){ 40 | #ifdef THOR_INIT 41 | serial_transmit(s[i]); 42 | #else 43 | serial::transmit(s[i]); 44 | #endif 45 | } 46 | } 47 | 48 | inline void virtual_debug(const char* s){ 49 | if(is_bochs_e9()){ 50 | bochs_print(s); 51 | } else { 52 | serial_print(s); 53 | } 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /programs/uptime/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int, char*[]){ 14 | auto fd = tlib::open("/sys/uptime"); 15 | 16 | if(fd.valid()){ 17 | auto buffer = new char[64]; 18 | 19 | auto content_result = tlib::read(*fd, buffer, 64); 20 | 21 | if(content_result.valid()){ 22 | auto chars = *content_result; 23 | 24 | std::string value_str; 25 | value_str.reserve(chars); 26 | 27 | for(size_t i = 0; i < chars; ++i){ 28 | value_str += buffer[i]; 29 | } 30 | 31 | auto value = std::parse(value_str); 32 | 33 | tlib::printf("Uptime: %u:%u:%u\n", value / 3600, (value % 3600) / 60, value % 60); 34 | } else { 35 | tlib::printf("uptime: error: %s\n", std::error_message(content_result.error())); 36 | } 37 | 38 | delete[] buffer; 39 | 40 | tlib::close(*fd); 41 | } else { 42 | tlib::printf("uptime: error: %s\n", std::error_message(fd.error())); 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /programs/writer/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char* argv[]){ 15 | if(argc == 1){ 16 | tlib::print_line("Usage: writer file_path"); 17 | return 1; 18 | } 19 | 20 | auto fd = tlib::open(argv[1], std::OPEN_CREATE); 21 | 22 | if(fd.valid()){ 23 | auto truncate_result = tlib::truncate(*fd, 12); 24 | 25 | if(truncate_result.valid()){ 26 | auto s = "0123456789AB"; 27 | 28 | auto write_result = tlib::write(*fd, s, 12, 0); 29 | 30 | if(write_result.valid()){ 31 | //TODO 32 | } else { 33 | tlib::printf("writer: error: %s\n", std::error_message(write_result.error())); 34 | } 35 | } else { 36 | tlib::printf("writer: error: %s\n", std::error_message(truncate_result.error())); 37 | } 38 | 39 | tlib::close(*fd); 40 | } else { 41 | tlib::printf("writer: error: %s\n", std::error_message(fd.error())); 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /tstl/include/memory.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef MEMORY_H 9 | #define MEMORY_H 10 | 11 | #include "enable_if.hpp" 12 | #include "utility.hpp" 13 | 14 | namespace std { 15 | 16 | template< class T > 17 | T* addressof(T& arg){ 18 | return reinterpret_cast( 19 | &const_cast( 20 | reinterpret_cast(arg))); 21 | } 22 | 23 | template 24 | struct has_overloaded_addressof { 25 | template 26 | static constexpr bool has_overload(...) { 27 | return false; 28 | } 29 | 30 | template ().operator&()) > 31 | static constexpr bool has_overload(bool) { 32 | return true; 33 | } 34 | 35 | constexpr static bool value = has_overload(true); 36 | }; 37 | 38 | template 39 | constexpr typename std::disable_if_t::value, T*> 40 | static_addressof(T& ref){ 41 | return &ref; 42 | } 43 | 44 | template 45 | constexpr typename std::enable_if_t::value, T*> 46 | static_addressof(T& ref){ 47 | return std::addressof(ref); 48 | } 49 | 50 | } //end of namespace std 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /kernel/include/conc/spinlock.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef SPINLOCK_H 9 | #define SPINLOCK_H 10 | 11 | #include 12 | 13 | /*! 14 | * \brief Implementation of a spinlock 15 | * 16 | * A spinlock simply waits in a loop until the lock is available. 17 | */ 18 | struct spinlock { 19 | /*! 20 | * \brief Acquire the lock. 21 | * 22 | * This will wait indefinitely. 23 | */ 24 | void lock() { 25 | while (!__sync_bool_compare_and_swap(&value, 0, 1)) 26 | ; 27 | __sync_synchronize(); 28 | //TODO The last synchronize is probably not necessary 29 | } 30 | 31 | /*! 32 | * \brief Acquire the lock. 33 | * 34 | * This will wait indefinitely. 35 | */ 36 | bool try_lock() { 37 | if(__sync_bool_compare_and_swap(&value, 0, 1)){ 38 | __sync_synchronize(); 39 | return true; 40 | } 41 | 42 | return false; 43 | } 44 | 45 | /*! 46 | * \brief Release the lock 47 | */ 48 | void unlock() { 49 | __sync_synchronize(); 50 | value = 0; 51 | } 52 | 53 | private: 54 | volatile size_t value = 0; ///< The value of the lock 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | 2 | # This format file is made especially for clang-format-3.7 3 | 4 | --- 5 | BasedOnStyle: Google 6 | IndentWidth: 4 7 | # clang-format is not very good to break long lines, don't let it do it 8 | ColumnLimit: 0 9 | --- 10 | Language: Cpp 11 | Standard: Cpp11 12 | 13 | # Tune some indentations 14 | AccessModifierOffset: -4 15 | ConstructorInitializerIndentWidth: 8 16 | 17 | # Only control statements should have spaces 18 | SpaceBeforeParens: ControlStatements 19 | 20 | # No block and its body should EVER be on a single line 21 | AllowShortFunctionsOnASingleLine: Empty 22 | AllowShortBlocksOnASingleLine: false 23 | AllowShortCaseLabelsOnASingleLine: false 24 | AllowShortIfStatementsOnASingleLine: false 25 | AllowShortLoopsOnASingleLine: false 26 | 27 | # Better C++11 support 28 | Cpp11BracedListStyle: true 29 | 30 | # Avoid too many empty lines 31 | MaxEmptyLinesToKeep: 1 32 | 33 | # Templates should always be on a separate line 34 | AlwaysBreakTemplateDeclarations: true 35 | 36 | # Nice alignement 37 | AlignConsecutiveAssignments: true 38 | 39 | # Improve ternary operators alignement 40 | BreakBeforeTernaryOperators: true 41 | 42 | # Tabs are bad news 43 | UseTab: Never 44 | 45 | # Configure comments 46 | AlignTrailingComments: true 47 | SpacesBeforeTrailingComments: 1 48 | 49 | # Don't mess with my comments 50 | CommentPragmas: '^[^ ]' 51 | 52 | # Avoid empty lines 53 | KeepEmptyLinesAtTheStartOfBlocks: false 54 | MaxEmptyLinesToKeep: 1 55 | 56 | # Force pointers to the type 57 | DerivePointerAlignment: false 58 | PointerAlignment: Left 59 | -------------------------------------------------------------------------------- /tstl/test_suite/function.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "test.hpp" 15 | 16 | namespace { 17 | 18 | int foo(int& ref){ 19 | ++ref; 20 | return ref; 21 | } 22 | 23 | void test_function_ptr(){ 24 | std::function f(foo); 25 | 26 | int a = 4; 27 | auto c = f(a); 28 | 29 | check(c == 5, "function: function_ptr error"); 30 | check(a == 5, "function: function_ptr error"); 31 | } 32 | 33 | void test_lambda(){ 34 | auto l = [](int& ref){ ++ref; return ref; }; 35 | std::function f(l); 36 | 37 | int a = 2; 38 | auto c = f(a); 39 | 40 | check(c == 3, "function: lambda error"); 41 | check(a == 3, "function: lambda error"); 42 | } 43 | 44 | void test_lambda_state(){ 45 | int a = 3; 46 | 47 | auto l = [&a](){ ++a; return a; }; 48 | std::function f(l); 49 | 50 | auto c = f(); 51 | 52 | check(c == 4, "function: lambda error"); 53 | check(a == 4, "function: lambda error"); 54 | } 55 | 56 | } //end of anonymous namespace 57 | 58 | void function_tests(){ 59 | test_function_ptr(); 60 | test_lambda(); 61 | test_lambda_state(); 62 | } 63 | -------------------------------------------------------------------------------- /tlib/include/tlib/print.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef USER_PRINT_HPP 9 | #define USER_PRINT_HPP 10 | 11 | #include "tlib/config.hpp" 12 | 13 | ASSERT_ONLY_THOR_PROGRAM 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace tlib { 23 | 24 | void print(char c); 25 | void print(const char* s); 26 | void print(const std::string& s); 27 | 28 | void print(uint8_t v); 29 | void print(uint16_t v); 30 | void print(uint32_t v); 31 | void print(uint64_t v); 32 | 33 | void print(int8_t v); 34 | void print(int16_t v); 35 | void print(int32_t v); 36 | void print(int64_t v); 37 | 38 | void print_line(); 39 | void print_line(const char* s); 40 | void print_line(size_t v); 41 | void print_line(const std::string& s); 42 | 43 | void set_canonical(bool can); 44 | void set_mouse(bool m); 45 | 46 | size_t read_input(char* buffer, size_t max); 47 | size_t read_input(char* buffer, size_t max, size_t ms); 48 | 49 | std::keycode read_input_raw(); 50 | std::keycode read_input_raw(size_t ms); 51 | 52 | void clear(); 53 | 54 | size_t get_columns(); 55 | size_t get_rows(); 56 | 57 | #include "printf_dec.hpp" 58 | 59 | void user_logf(const char* s, ...); 60 | 61 | } //end of namespace tlib 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /kernel/include/conc/int_lock.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2014. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef INT_LOCK_HPP 9 | #define INT_LOCK_HPP 10 | 11 | #include 12 | 13 | #include "arch.hpp" 14 | 15 | /*! 16 | * \brief An interrupt lock. This lock disable preemption on acquire. 17 | */ 18 | struct int_lock { 19 | /*! 20 | * \brief Acquire the lock. This will disable preemption. 21 | */ 22 | void lock() { 23 | arch::disable_hwint(rflags); 24 | } 25 | 26 | /*! 27 | * \brief Release the lock. This will enable preemption. 28 | */ 29 | void unlock() { 30 | arch::enable_hwint(rflags); 31 | } 32 | 33 | private: 34 | size_t rflags; ///< The CPU flags 35 | }; 36 | 37 | /*! 38 | * \brief A direct interrupt lock (RAII). 39 | * 40 | * This is the equivalent of a std::lock_guard but does not need to 41 | * store a lock. 42 | */ 43 | struct direct_int_lock { 44 | /*! 45 | * \brief Construct a new direct_int_lock and acquire the lock. 46 | */ 47 | direct_int_lock() { 48 | lock.lock(); 49 | } 50 | 51 | /*! 52 | * \brief Destruct a direct_int_lock and release the lock. 53 | */ 54 | ~direct_int_lock() { 55 | lock.unlock(); 56 | } 57 | 58 | private: 59 | int_lock lock; ///< The interrupt lock 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /kernel/include/timer.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TIMER_H 9 | #define TIMER_H 10 | 11 | #include 12 | 13 | namespace timer { 14 | 15 | /*! 16 | * \brief Install the system timer 17 | */ 18 | void install(); 19 | 20 | /*! 21 | * \brief Returns a up-counter in seconds 22 | */ 23 | uint64_t seconds(); 24 | 25 | /*! 26 | * \brief Returns a up-counter in milliseconds 27 | */ 28 | uint64_t milliseconds(); 29 | 30 | /*! 31 | * \brief Let the timer know of a new tick 32 | */ 33 | void tick(); 34 | 35 | /*! 36 | * \brief Return the frequency in Hz of the current timer system. 37 | */ 38 | uint64_t timer_frequency(); 39 | 40 | /*! 41 | * \brief Sets the frequency in Hz of the current timer system. 42 | */ 43 | void timer_frequency(uint64_t freq); 44 | 45 | /*! 46 | * \brief Returns a up-counter based on the counter frequency 47 | */ 48 | uint64_t counter(); 49 | 50 | /*! 51 | * \brief Return the frequency in Hz of the current counter system. 52 | */ 53 | uint64_t counter_frequency(); 54 | 55 | /*! 56 | * \brief Sets the frequency in Hz of the current counter system. 57 | */ 58 | void counter_frequency(uint64_t freq); 59 | 60 | /*! 61 | * \brief Sets the function to use to get the counter value; 62 | */ 63 | void counter_fun(uint64_t (*fun)()); 64 | 65 | } //end of timer namespace 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /kernel/src/terminal_driver.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "terminal_driver.hpp" 9 | #include "terminal.hpp" 10 | 11 | size_t stdio::terminal_driver::read(void* data, char* buffer, size_t count, size_t& read){ 12 | auto* terminal = reinterpret_cast(data); 13 | 14 | if (terminal->is_canonical()) { 15 | read = terminal->read_input_can(reinterpret_cast(buffer), count); 16 | } else { 17 | buffer[0] = terminal->read_input_raw(); 18 | 19 | read = 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | size_t stdio::terminal_driver::read(void* data, char* buffer, size_t count, size_t& read, size_t ms){ 26 | auto* terminal = reinterpret_cast(data); 27 | 28 | if(terminal->is_canonical()){ 29 | read = terminal->read_input_can(reinterpret_cast(buffer), count, ms); 30 | } else { 31 | buffer[0] = terminal->read_input_raw(ms); 32 | 33 | read = 1; 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | size_t stdio::terminal_driver::write(void* data, const char* buffer, size_t count, size_t& written){ 40 | auto* terminal = reinterpret_cast(data); 41 | 42 | for(size_t i = 0; i < count;++i){ 43 | terminal->print(buffer[i]); 44 | } 45 | 46 | written = count; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tstl/test_suite/circular_buffer.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "test.hpp" 14 | 15 | namespace { 16 | 17 | void base_test(){ 18 | circular_buffer buffer; 19 | 20 | check(buffer.empty()); 21 | check(!buffer.full()); 22 | 23 | buffer.push(11); 24 | 25 | check(!buffer.empty()); 26 | check(!buffer.full()); 27 | check(buffer.top() == 11); 28 | 29 | buffer.push(22); 30 | 31 | check(buffer.top() == 11); 32 | 33 | check(buffer.pop() == 11); 34 | check(buffer.pop() == 22); 35 | check(buffer.empty()); 36 | } 37 | 38 | void contains_test(){ 39 | circular_buffer buffer; 40 | 41 | buffer.push(11); 42 | buffer.push(22); 43 | buffer.push(33); 44 | buffer.push(44); 45 | buffer.push(55); 46 | buffer.push(66); 47 | buffer.push(77); 48 | buffer.push(88); 49 | 50 | check(buffer.full()); 51 | check(buffer.contains(88)); 52 | check(buffer.contains(33)); 53 | check(buffer.contains(11)); 54 | check(!buffer.contains(13)); 55 | 56 | buffer.replace(33, 13); 57 | check(!buffer.contains(33)); 58 | check(buffer.contains(13)); 59 | } 60 | 61 | } //end of anonymous namespace 62 | 63 | void circular_buffer_tests(){ 64 | base_test(); 65 | contains_test(); 66 | } 67 | -------------------------------------------------------------------------------- /tstl/include/iostream.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef IOSTREAM_H 9 | #define IOSTREAM_H 10 | 11 | #include 12 | #include 13 | 14 | namespace std { 15 | 16 | template 17 | struct basic_ostream { 18 | using char_type = CharT; 19 | 20 | void put(char_type c){ 21 | buffer[index++] = c; 22 | 23 | if(index == buffer_size){ 24 | flush(); 25 | } 26 | } 27 | 28 | void write(char_type* in, size_t n){ 29 | if(index + n < buffer_size){ 30 | std::copy_n(in, n, buffer + index); 31 | } else { 32 | while(n){ 33 | flush(); 34 | 35 | auto nn = std::min(n, buffer_size); 36 | 37 | std::copy_n(in, nn, buffer); 38 | 39 | n -= nn; 40 | inn += nn; 41 | } 42 | 43 | index += n % buffer_size; 44 | } 45 | } 46 | 47 | basic_ostream& operator<<(char_type c){ 48 | put(c); 49 | } 50 | 51 | void flush(){ 52 | //TODO 53 | 54 | index = 0; 55 | } 56 | 57 | private: 58 | static constexpr const size_t buffer_size = 1024; 59 | 60 | char_type buffer[buffer_size]; 61 | size_t index; 62 | }; 63 | 64 | using ostream = basic_ostream; 65 | 66 | extern ostream cout; 67 | extern ostream cerr; 68 | 69 | } //end of namespace std 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /kernel/include/virtual_allocator.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VIRTUAL_ALLOCATOR_H 9 | #define VIRTUAL_ALLOCATOR_H 10 | 11 | #include 12 | #include 13 | 14 | namespace virtual_allocator { 15 | 16 | //The virtual size allocated to the kernel 17 | constexpr const size_t kernel_virtual_size = 1_GiB; 18 | 19 | /* 20 | * \brief Initialize the vitual allocator. 21 | * 22 | * After this point, the early_allocate function should not be called 23 | */ 24 | void init(); 25 | 26 | /*! 27 | * \brief Finalize the vitual allocator, must be called after sysfs initialization 28 | */ 29 | void finalize(); 30 | 31 | /*! 32 | * \brief Allocate several pages of vitual memory 33 | * \param pages The number of pages 34 | * \return The vitual addres of the allocated pages 35 | */ 36 | size_t allocate(size_t pages); 37 | 38 | /*! 39 | * \brief Free the allocated virtual memory 40 | * \param address The address of the allocated virtual memory 41 | * \param pages The number of pages 42 | */ 43 | void free(size_t address, size_t pages); 44 | 45 | /*! 46 | * \brief Return the amount of virtual memory available 47 | */ 48 | size_t available(); 49 | 50 | /*! 51 | * \brief Return the amount of virtual memory allocated 52 | */ 53 | size_t allocated(); 54 | 55 | /*! 56 | * \brief Return the amount of virtual memory free 57 | */ 58 | size_t free(); 59 | 60 | } //end of virtual_allocator namespace 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /kernel/include/conc/condition_variable.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef CONDITION_VARIABLE_H 9 | #define CONDITION_VARIABLE_H 10 | 11 | #include "conc/wait_list.hpp" 12 | #include "conc/spinlock.hpp" 13 | 14 | #include "process.hpp" 15 | 16 | /*! 17 | * \brief A simple sleep queue 18 | */ 19 | struct condition_variable { 20 | /*! 21 | * \brief Test if the sleep queue is empty 22 | */ 23 | bool empty() const; 24 | 25 | /*! 26 | * \brief Returns the top process in the queue. 27 | * 28 | * If the queue is empty, the behaviour is undefined. 29 | */ 30 | scheduler::pid_t top_process() const; 31 | 32 | /*! 33 | * \brief Wake up the first process from the queue. 34 | */ 35 | scheduler::pid_t notify_one(); 36 | 37 | /*! 38 | * \brief Wake up all the processes from the queue. 39 | */ 40 | void notify_all(); 41 | 42 | /*! 43 | * \brief Wait inside the queue until woken up. 44 | */ 45 | void wait(); 46 | 47 | /*! 48 | * \brief Wait inside the queue until woken up or until the 49 | * timeout is passed. 50 | * 51 | * \return true if the thread was woken up, false if the timeout is passed 52 | */ 53 | bool wait_for(size_t ms); 54 | 55 | private: 56 | mutable spinlock lock; ///< The spin lock used for protecting the queue 57 | wait_list queue; ///< The queue of waiting threads 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /tstl/include/initializer_list.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef INITIALIZER_LIST_H 9 | #define INITIALIZER_LIST_H 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | template 16 | struct initializer_list { 17 | const T* first; 18 | size_t _size; 19 | 20 | constexpr initializer_list(const T* __b, size_t __s) noexcept : first(__b), _size(__s) { 21 | // Nothing else to init 22 | } 23 | 24 | public: 25 | using value_type = T; 26 | using reference = const T&; 27 | using const_reference = const T&; 28 | using size_type = size_t; 29 | using iterator = const T*; 30 | using const_iterator = const T*; 31 | 32 | constexpr initializer_list() noexcept : first(nullptr), _size(0) { 33 | // Nothing else to init 34 | } 35 | 36 | constexpr size_t size() const noexcept { 37 | return _size; 38 | } 39 | 40 | constexpr const T* begin() const noexcept { 41 | return first; 42 | } 43 | 44 | constexpr const T* end() const noexcept { 45 | return first + _size; 46 | } 47 | }; 48 | 49 | template 50 | inline constexpr const T* begin(initializer_list list) noexcept { 51 | return list.begin(); 52 | } 53 | 54 | template 55 | inline constexpr const T* end(initializer_list list) noexcept { 56 | return list.end(); 57 | } 58 | 59 | } //end of namespace std 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /tstl/include/bit_field.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef BITFIELD_HPP 9 | #define BITFIELD_HPP 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | /*! 16 | * \brief Helper to handle a value as a bit field. 17 | * \param S The type of the source value 18 | * \param T The type of the bit value 19 | * \param Position The starting position from the right (LSB) 20 | * \param Size The number of bits 21 | */ 22 | template 23 | struct bit_field { 24 | /*! 25 | * \brief Construct a bit field around the given value 26 | */ 27 | bit_field(S* value) : value(value) {} 28 | 29 | /*! 30 | * \brief Extract the value of the bit field 31 | */ 32 | T get() const { 33 | return (*value >> Position) & ((1ULL << Size) - 1); 34 | } 35 | 36 | /*! 37 | * \brief Extract the value of the bit field 38 | */ 39 | T operator*() const { 40 | return get(); 41 | } 42 | 43 | /*! 44 | * \brief Assign a new value to the bit field 45 | */ 46 | bit_field& operator=(T new_value_real){ 47 | S new_value(new_value_real); 48 | 49 | size_t mask = ((S(1) << Size) - 1) << Position; 50 | *value = (*value & ~mask) | ((new_value << Position) & mask); 51 | return *this; 52 | } 53 | 54 | private: 55 | S* value; ///< Pointer to the source value 56 | }; 57 | 58 | } //end of namespace std 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /kernel/include/vesa.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef VESA_H 9 | #define VESA_H 10 | 11 | #include "vesa_types.hpp" 12 | 13 | namespace vesa { 14 | 15 | bool init(); 16 | bool enabled(); 17 | void disable(); 18 | 19 | uint32_t make_color(uint8_t r, uint8_t g, uint8_t b); 20 | 21 | void draw_hline(size_t x, size_t y, size_t w, uint32_t color); 22 | void draw_hline(void* buffer, size_t x, size_t y, size_t w, uint32_t color); 23 | 24 | void draw_vline(size_t x, size_t y, size_t h, uint32_t color); 25 | void draw_vline(void* buffer, size_t x, size_t y, size_t h, uint32_t color); 26 | 27 | void draw_rect(size_t x, size_t y, size_t w, size_t h, uint32_t color); 28 | void draw_rect(void* buffer, size_t x, size_t y, size_t w, size_t h, uint32_t color); 29 | 30 | void draw_char(size_t x, size_t y, char c, uint32_t color); 31 | void draw_char(void* buffer, size_t x, size_t y, char c, uint32_t color); 32 | 33 | void move_lines_up(size_t y, size_t x, size_t w, size_t lines, size_t n); 34 | void move_lines_up(void* buffer, size_t y, size_t x, size_t w, size_t lines, size_t n); 35 | 36 | uint64_t get_width(); 37 | uint64_t get_height(); 38 | 39 | uint64_t get_x_shift(); 40 | uint64_t get_y_shift(); 41 | 42 | uint64_t get_bytes_per_scan_line(); 43 | 44 | uint64_t get_red_shift(); 45 | uint64_t get_green_shift(); 46 | uint64_t get_blue_shift(); 47 | 48 | void* create_buffer(); 49 | 50 | void redraw(const char* buffer); 51 | void save(char* buffer); 52 | 53 | } //end of vesa namespace 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /kernel/src/drivers/loopback.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "drivers/loopback.hpp" 9 | 10 | #include "net/ethernet_layer.hpp" 11 | 12 | #include "logging.hpp" 13 | #include "kernel_utils.hpp" 14 | #include "physical_allocator.hpp" 15 | #include "virtual_allocator.hpp" 16 | #include "interrupts.hpp" 17 | #include "paging.hpp" 18 | 19 | namespace { 20 | 21 | struct loopback_t { 22 | network::interface_descriptor* interface; 23 | }; 24 | 25 | void send_packet(network::interface_descriptor& interface, network::packet_p& packet){ 26 | logging::logf(logging::log_level::TRACE, "loopback: Transmit packet\n"); 27 | 28 | { 29 | direct_int_lock lock; 30 | 31 | interface.rx_queue.push(packet); 32 | interface.rx_sem.notify(); 33 | } 34 | 35 | logging::logf(logging::log_level::TRACE, "loopback: Packet transmitted correctly\n"); 36 | } 37 | 38 | } //end of anonymous namespace 39 | 40 | void loopback::init_driver(network::interface_descriptor& interface){ 41 | logging::logf(logging::log_level::TRACE, "loopback: Initialize loopback driver\n"); 42 | 43 | interface.driver_data = new loopback_t(); 44 | interface.hw_send = send_packet; 45 | 46 | interface.ip_address = network::ip::make_address(127, 0, 0, 1); 47 | //TODO maybe set a MAC address 48 | } 49 | 50 | void loopback::finalize_driver(network::interface_descriptor& interface){ 51 | auto* desc = static_cast(interface.driver_data); 52 | desc->interface = &interface; 53 | } 54 | -------------------------------------------------------------------------------- /kernel/include/interrupts.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef INTERRUPTS_H 9 | #define INTERRUPTS_H 10 | 11 | #include 12 | 13 | namespace interrupt { 14 | 15 | constexpr const size_t SYSCALL_FIRST = 50; 16 | constexpr const size_t SYSCALL_MAX = 10; 17 | 18 | struct fault_regs { 19 | uint64_t rbp; 20 | uint64_t error_no; 21 | uint64_t error_code; 22 | uint64_t rip; 23 | uint64_t rflags; 24 | uint64_t cs; 25 | uint64_t rsp; 26 | uint64_t ss; 27 | } __attribute__((packed)); 28 | 29 | struct syscall_regs { 30 | sse_128 xmm_registers[16]; 31 | uint64_t rax; 32 | uint64_t rbx; 33 | uint64_t rcx; 34 | uint64_t rdx; 35 | uint64_t rsi; 36 | uint64_t rdi; 37 | uint64_t r8; 38 | uint64_t r9; 39 | uint64_t r10; 40 | uint64_t r11; 41 | uint64_t r12; 42 | uint64_t r13; 43 | uint64_t r14; 44 | uint64_t r15; 45 | uint64_t rbp; 46 | uint64_t code; 47 | uint64_t rip; 48 | uint64_t cs; 49 | uint64_t rflags; 50 | uint64_t rsp; 51 | uint64_t ds; 52 | } __attribute__((packed)); 53 | 54 | void setup_interrupts(); 55 | 56 | bool register_irq_handler(size_t irq, void (*handler)(syscall_regs*, void*), void* data); 57 | bool register_syscall_handler(size_t irq, void (*handler)(syscall_regs*)); 58 | 59 | bool unregister_irq_handler(size_t irq, void (*handler)(syscall_regs*, void*)); 60 | bool unregister_syscall_handler(size_t irq, void (*handler)(syscall_regs*)); 61 | 62 | } //end of interrupt namespace 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /tlib/src/graphics.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "tlib/graphics.hpp" 9 | 10 | namespace { 11 | 12 | uint64_t syscall_get(uint64_t call){ 13 | size_t value; 14 | asm volatile("mov rax, %[call]; int 50; mov %[value], rax" 15 | : [value] "=m" (value) 16 | : [call] "r" (call) 17 | : "rax"); 18 | return value; 19 | } 20 | 21 | } // end of anonymous namespace 22 | 23 | uint64_t tlib::graphics::get_width(){ 24 | return syscall_get(0xC00); 25 | } 26 | 27 | uint64_t tlib::graphics::get_height(){ 28 | return syscall_get(0xC01); 29 | } 30 | 31 | uint64_t tlib::graphics::get_x_shift(){ 32 | return syscall_get(0xC02); 33 | } 34 | 35 | uint64_t tlib::graphics::get_y_shift(){ 36 | return syscall_get(0xC03); 37 | } 38 | 39 | uint64_t tlib::graphics::get_bytes_per_scan_line(){ 40 | return syscall_get(0xC04); 41 | } 42 | 43 | uint64_t tlib::graphics::get_red_shift(){ 44 | return syscall_get(0xC05); 45 | } 46 | 47 | uint64_t tlib::graphics::get_green_shift(){ 48 | return syscall_get(0xC06); 49 | } 50 | 51 | uint64_t tlib::graphics::get_blue_shift(){ 52 | return syscall_get(0xC07); 53 | } 54 | 55 | void tlib::graphics::redraw(char* buffer){ 56 | asm volatile("mov rax, 0xC08; mov rbx, %[buffer]; int 50;" 57 | : 58 | : [buffer] "g" (buffer) 59 | : "rax", "rbx"); 60 | } 61 | 62 | uint64_t tlib::graphics::mouse_x(){ 63 | return syscall_get(0xCA0); 64 | } 65 | 66 | uint64_t tlib::graphics::mouse_y(){ 67 | return syscall_get(0xCA1); 68 | } 69 | -------------------------------------------------------------------------------- /tstl/test_suite/shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "test.hpp" 14 | 15 | namespace { 16 | 17 | void test_base(){ 18 | std::shared_ptr a(new int); 19 | 20 | *a.get() = 99; 21 | 22 | check(*a.get() == 99); 23 | } 24 | 25 | struct foo { 26 | int bar = 0; 27 | 28 | int test(){ 29 | return bar; 30 | } 31 | 32 | void set(int bar){ 33 | this->bar = bar; 34 | } 35 | }; 36 | 37 | void test_struct(){ 38 | std::shared_ptr a(new foo); 39 | 40 | check(a->test() == 0); 41 | 42 | a->set(666); 43 | 44 | check(a->test() == 666); 45 | } 46 | 47 | struct kiss { 48 | int* ref; 49 | kiss(int* ref) : ref(ref) {} 50 | ~kiss(){ 51 | ++(*ref); 52 | } 53 | }; 54 | 55 | void test_destructor() { 56 | int counter = 0; 57 | 58 | { 59 | std::shared_ptr a(new kiss(&counter)); 60 | auto b = a; 61 | auto c = a; 62 | } 63 | 64 | check(counter == 1, "destruct: Invalid destructors"); 65 | } 66 | 67 | void test_make_shared() { 68 | int counter = 0; 69 | 70 | { 71 | auto a = std::make_shared(&counter); 72 | auto b = a; 73 | auto c = a; 74 | } 75 | 76 | check(counter == 1, "make_shared: Invalid destructors"); 77 | } 78 | 79 | } //end of anonymous namespace 80 | 81 | void shared_ptr_tests(){ 82 | test_base(); 83 | test_struct(); 84 | test_destructor(); 85 | test_make_shared(); 86 | } 87 | -------------------------------------------------------------------------------- /tlib/include/tlib/config.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TLIB_CONFIG_HPP 9 | #define TLIB_CONFIG_HPP 10 | 11 | namespace tlib { 12 | 13 | constexpr bool is_thor_program(){ 14 | #ifdef THOR_PROGRAM 15 | return true; 16 | #else 17 | return false; 18 | #endif 19 | } 20 | 21 | constexpr bool is_thor_lib(){ 22 | #ifdef THOR_TLIB 23 | return true; 24 | #else 25 | return false; 26 | #endif 27 | } 28 | 29 | } // end of namespace tlib 30 | 31 | #define ASSERT_ONLY_THOR_PROGRAM static_assert(tlib::is_thor_program() || tlib::is_thor_lib(), __FILE__ " can only be used in Thor programs"); 32 | 33 | // Conditional namespace 34 | 35 | #ifdef THOR_TLIB 36 | #define THOR_NAMESPACE_NAME(LIB_NS,THOR_NS) LIB_NS 37 | #elif defined(THOR_PROGRAM) 38 | #define THOR_NAMESPACE_NAME(LIB_NS,THOR_NS) LIB_NS 39 | #else 40 | #define THOR_NAMESPACE_NAME(LIB_NS,THOR_NS) THOR_NS 41 | #endif 42 | 43 | #define THOR_NAMESPACE(LIB_NS,THOR_NS) namespace THOR_NAMESPACE_NAME(LIB_NS, THOR_NS) 44 | 45 | // Namespaces in kernel 46 | 47 | #ifdef THOR_TLIB 48 | #define KERNEL_NAMESPACE_BEGIN(THOR_NS) 49 | #define KERNEL_NAMESPACE_END 50 | #elif defined(THOR_PROGRAM) 51 | #define KERNEL_NAMESPACE_BEGIN(THOR_NS) 52 | #define KERNEL_NAMESPACE_END 53 | #else 54 | #define KERNEL_NAMESPACE_BEGIN(THOR_NS) namespace THOR_NS { 55 | #define KERNEL_NAMESPACE_END } 56 | #endif 57 | 58 | // Conditional prefixing 59 | 60 | #ifdef THOR_TLIB 61 | #define THOR_PREFIX(prefix) prefix 62 | #elif defined(THOR_PROGRAM) 63 | #define THOR_PREFIX(prefix) prefix 64 | #else 65 | #define THOR_PREFIX(prefix) 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /kernel/src/isrs.s: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT_1_0.txt) 6 | //======================================================================= 7 | 8 | .intel_syntax noprefix 9 | 10 | .include "src/common.s" 11 | 12 | .macro create_irq number 13 | .global _isr\number 14 | _isr\number: 15 | push \number 16 | push rbp 17 | 18 | jmp isr_common_handler 19 | .endm 20 | 21 | .macro create_irq_dummy number 22 | .global _isr\number 23 | _isr\number: 24 | cli 25 | 26 | push 0 // Dummy error code 27 | push \number 28 | push rbp 29 | 30 | jmp isr_common_handler 31 | .endm 32 | 33 | create_irq_dummy 0 34 | create_irq_dummy 1 35 | create_irq_dummy 2 36 | create_irq_dummy 3 37 | create_irq_dummy 4 38 | create_irq_dummy 5 39 | create_irq_dummy 6 40 | create_irq_dummy 7 41 | create_irq 8 42 | create_irq_dummy 9 43 | create_irq 10 44 | create_irq 11 45 | create_irq 12 46 | create_irq 13 47 | create_irq 14 48 | create_irq_dummy 15 49 | create_irq_dummy 16 50 | create_irq_dummy 17 51 | create_irq_dummy 18 52 | create_irq_dummy 19 53 | create_irq_dummy 20 54 | create_irq_dummy 21 55 | create_irq_dummy 22 56 | create_irq_dummy 23 57 | create_irq_dummy 24 58 | create_irq_dummy 25 59 | create_irq_dummy 26 60 | create_irq_dummy 27 61 | create_irq_dummy 28 62 | create_irq_dummy 29 63 | create_irq_dummy 30 64 | create_irq_dummy 31 65 | 66 | isr_common_handler: 67 | //TODO Kernel segments should be restored 68 | 69 | call _fault_handler 70 | 71 | // TODO At this point, it is absolutely not safe to return since most 72 | // registers will get trashed the fault handler must hang 73 | 74 | add rsp, 16 // Cleans the pushed base pointer and error number 75 | 76 | iretq // iret will clean the other automatically pushed stuff 77 | -------------------------------------------------------------------------------- /kernel/src/drivers/pit.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "drivers/pit.hpp" 9 | 10 | #include "timer.hpp" 11 | #include "interrupts.hpp" 12 | #include "scheduler.hpp" 13 | #include "kernel_utils.hpp" 14 | #include "logging.hpp" 15 | 16 | namespace { 17 | 18 | constexpr const uint64_t PIT_FREQUENCY = 1000; 19 | 20 | size_t pit_counter = 0; 21 | 22 | void timer_handler(interrupt::syscall_regs*, void*){ 23 | ++pit_counter; 24 | 25 | timer::tick(); 26 | } 27 | 28 | } //End of anonymous namespace 29 | 30 | bool pit::install(){ 31 | uint64_t divisor = 1193180 / PIT_FREQUENCY; 32 | 33 | out_byte(0x43, 0x36); 34 | out_byte(0x40, static_cast(divisor)); 35 | out_byte(0x40, static_cast(divisor >> 8)); 36 | 37 | // Indicate the timer frequency 38 | timer::timer_frequency(PIT_FREQUENCY); 39 | 40 | if(!interrupt::register_irq_handler(0, timer_handler, nullptr)){ 41 | logging::logf(logging::log_level::ERROR, "Unable to register PIT IRQ handler 0\n"); 42 | 43 | return false; 44 | } 45 | 46 | // Let the timer know about the counter 47 | timer::counter_fun(pit::counter); 48 | timer::counter_frequency(PIT_FREQUENCY); 49 | 50 | logging::logf(logging::log_level::TRACE, "PIT Driver Installed\n"); 51 | 52 | return true; 53 | } 54 | 55 | void pit::remove(){ 56 | if(!interrupt::unregister_irq_handler(0, timer_handler)){ 57 | logging::logf(logging::log_level::ERROR, "Unable to unregister PIT IRQ handler 0\n"); 58 | } 59 | 60 | logging::logf(logging::log_level::TRACE, "PIT Driver Removed\n"); 61 | } 62 | 63 | uint64_t pit::counter(){ 64 | return pit_counter; 65 | } 66 | -------------------------------------------------------------------------------- /bootloader/intel_16.asm: -------------------------------------------------------------------------------- 1 | ;======================================================================= 2 | ; Copyright Baptiste Wicht 2013-2016. 3 | ; Distributed under the terms of the MIT License. 4 | ; (See accompanying file LICENSE or copy at 5 | ; http://www.opensource.org/licenses/MIT_1_0.txt) 6 | ;======================================================================= 7 | 8 | [BITS 16] 9 | 10 | ; Functions 11 | 12 | new_line_16: 13 | mov ah, 0Eh 14 | 15 | mov al, 0Ah 16 | int 10h 17 | 18 | mov al, 0Dh 19 | int 10h 20 | 21 | ret 22 | 23 | print_line_16: 24 | mov ah, 0Eh 25 | 26 | .repeat: 27 | lodsb 28 | test al, al 29 | je .done 30 | int 10h 31 | jmp .repeat 32 | 33 | .done: 34 | call new_line_16 35 | 36 | ret 37 | 38 | print_16: 39 | mov ah, 0Eh 40 | 41 | .repeat: 42 | lodsb 43 | test al, al 44 | je .done 45 | int 10h 46 | jmp .repeat 47 | 48 | .done: 49 | ret 50 | 51 | print_int_16: 52 | push ax 53 | push bx 54 | push dx 55 | push si 56 | 57 | mov ax, di 58 | 59 | xor si, si 60 | 61 | .loop: 62 | xor dx, dx 63 | mov bx, 10 64 | div bx 65 | add dx, 48 66 | 67 | push dx 68 | inc si 69 | 70 | test ax, ax 71 | jne .loop 72 | 73 | .next: 74 | test si, si 75 | je .exit 76 | dec si 77 | 78 | ; write the char 79 | pop ax 80 | 81 | mov ah, 0Eh 82 | int 10h 83 | 84 | jmp .next 85 | 86 | .exit: 87 | pop si 88 | pop dx 89 | pop bx 90 | pop ax 91 | 92 | ret 93 | 94 | key_wait: 95 | mov al, 0xD2 96 | out 64h, al 97 | 98 | mov al, 0x80 99 | out 60h, al 100 | 101 | .keyup: 102 | in al, 0x60 103 | and al, 10000000b 104 | jnz .keyup 105 | 106 | .keydown: 107 | in al, 0x60 108 | 109 | ret 110 | -------------------------------------------------------------------------------- /kernel/include/conc/deferred_unique_mutex.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef DEFERRED_UNIQUE_MUTEX_H 9 | #define DEFERRED_UNIQUE_MUTEX_H 10 | 11 | #include "conc/int_lock.hpp" 12 | 13 | #include "scheduler.hpp" 14 | 15 | /*! 16 | * \brief A deferred unique mutex lock implementation. 17 | * 18 | * This must be used when the notifier is an IRQ handler. 19 | * 20 | * Once the lock is acquired, the critical section is only accessible by the 21 | * thread who acquired the mutex. 22 | */ 23 | struct deferred_unique_mutex { 24 | /*! 25 | * \brief Claim the mutex 26 | */ 27 | void claim() { 28 | this->pid = scheduler::get_pid(); 29 | } 30 | 31 | /*! 32 | * \brief Wait for the lock 33 | */ 34 | void wait() { 35 | int_lock lock; 36 | 37 | lock.lock(); 38 | 39 | if (value > 0) { 40 | value = 0; 41 | 42 | lock.unlock(); 43 | } else { 44 | waiting = true; 45 | 46 | scheduler::block_process_light(pid); 47 | lock.unlock(); 48 | scheduler::reschedule(); 49 | 50 | waiting = false; 51 | } 52 | } 53 | 54 | /*! 55 | * \brief Release the lock, from an IRQ 56 | */ 57 | void notify() { 58 | if (!waiting) { 59 | value = 1; 60 | } else { 61 | scheduler::unblock_process_hint(pid); 62 | } 63 | } 64 | 65 | private: 66 | size_t pid = 0; ///< The claimed pid 67 | volatile size_t value = 0; ///< The value of the mutex 68 | volatile bool waiting = false; ///< Indicates if the process is waiting 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /programs/cat/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int argc, char* argv[]){ 14 | if(argc == 1){ 15 | tlib::print_line("Usage: cat file_path"); 16 | return 1; 17 | } 18 | 19 | auto fd = tlib::open(argv[1]); 20 | 21 | if(fd.valid()){ 22 | auto info = tlib::stat(*fd); 23 | 24 | if(info.valid()){ 25 | if(info->flags & tlib::STAT_FLAG_DIRECTORY){ 26 | tlib::print_line("cat: error: Is a directory"); 27 | } else { 28 | auto size = info->size; 29 | 30 | auto buffer = new char[size]; 31 | 32 | auto content_result = tlib::read(*fd, buffer, size); 33 | 34 | if(content_result.valid()){ 35 | if(*content_result != size){ 36 | //TODO Read more 37 | } else { 38 | for(size_t i = 0; i < size; ++i){ 39 | tlib::print(buffer[i]); 40 | } 41 | 42 | tlib::print_line(); 43 | } 44 | } else { 45 | tlib::printf("cat: error: %s\n", std::error_message(content_result.error())); 46 | } 47 | } 48 | } else { 49 | tlib::printf("cat: error: %s\n", std::error_message(info.error())); 50 | } 51 | 52 | tlib::close(*fd); 53 | } else { 54 | tlib::printf("cat: error: %s\n", std::error_message(fd.error())); 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /kernel/include/conc/wait_list.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef WAIT_LIST_H 9 | #define WAIT_LIST_H 10 | 11 | #include 12 | 13 | struct wait_node { 14 | size_t pid; 15 | wait_node* next; 16 | }; 17 | 18 | /*! 19 | * \brief A list of processes waiting. 20 | * 21 | * It is implemented as an intrusive singly linked list. 22 | */ 23 | struct wait_list { 24 | /*! 25 | * \brief Test if the list is empty. 26 | */ 27 | bool empty() const; 28 | 29 | /*! 30 | * \brief Returns the top process of queue 31 | * \return The pid of the top process 32 | */ 33 | size_t top() const; 34 | 35 | /*! 36 | * \brief Returns true if the process is waiting in this queue, false otherwise 37 | */ 38 | bool waiting() const; 39 | 40 | /*! 41 | * \brief Removes the current process from the list. 42 | * 43 | * The process must be in the list! 44 | */ 45 | void remove(); 46 | 47 | /*! 48 | * \brief Enque the current process in the wait list 49 | */ 50 | void enqueue(); 51 | 52 | /*! 53 | * \brief Enque the current process in the wait list 54 | */ 55 | void enqueue_timeout(size_t ms); 56 | 57 | /*! 58 | * \brief Dequeue the first process from the wait list 59 | * \return The pid of the dequeued process 60 | */ 61 | size_t dequeue(); 62 | 63 | /*! 64 | * \brief Dequeue the first process from the wait list 65 | * \return The pid of the dequeued process 66 | */ 67 | size_t dequeue_hint(); 68 | 69 | private: 70 | wait_node* head = nullptr; ///< The head of the list 71 | wait_node* tail = nullptr; ///< The tail of the list 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /kernel/src/mmap.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "mmap.hpp" 9 | #include "paging.hpp" 10 | #include "virtual_allocator.hpp" 11 | #include "logging.hpp" 12 | 13 | void* mmap_phys(size_t phys, size_t size){ 14 | auto offset = phys % paging::PAGE_SIZE; 15 | auto aligned_phys = phys - offset; 16 | 17 | auto real_length = offset + size; 18 | auto pages = paging::pages(real_length); 19 | 20 | // Allocate pages of virtual memory 21 | 22 | auto virt = virtual_allocator::allocate(pages); 23 | 24 | if(!virt){ 25 | logging::logf(logging::log_level::ERROR, "mmap: Unable to allocate %u virtual pages\n", size_t(pages)); 26 | return nullptr; 27 | } 28 | 29 | // Map to the physical address 30 | 31 | if(!paging::map_pages(virt, aligned_phys, pages)){ 32 | logging::logf(logging::log_level::ERROR, "mmap: Unable to map %u pages %h->%h\n", size_t(pages), size_t(virt), size_t(aligned_phys)); 33 | return nullptr; 34 | } 35 | 36 | return reinterpret_cast(virt); 37 | } 38 | 39 | bool munmap_phys(void* virt_ptr, size_t size){ 40 | auto virt = reinterpret_cast(virt_ptr); 41 | 42 | auto offset = virt % paging::PAGE_SIZE; 43 | auto aligned_virt = virt - offset; 44 | 45 | auto real_length = offset + size; 46 | auto pages = paging::pages(real_length); 47 | 48 | // Release the virtual memory 49 | 50 | virtual_allocator::free(aligned_virt, pages); 51 | 52 | // Unmap the memory 53 | 54 | if(!paging::unmap_pages(aligned_virt, pages)){ 55 | logging::logf(logging::log_level::ERROR, "munmap: Unable to unmap %u pages %h\n", size_t(pages), size_t(aligned_virt)); 56 | return false; 57 | } 58 | 59 | return true; 60 | } 61 | -------------------------------------------------------------------------------- /tlib/include/tlib/elf.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ELF_H 9 | #define ELF_H 10 | 11 | #include 12 | #include 13 | 14 | namespace elf { 15 | 16 | struct elf_header { 17 | char e_ident[16]; 18 | uint16_t e_type; 19 | uint16_t e_machine; 20 | uint32_t e_version; 21 | uint64_t e_entry; 22 | uint64_t e_phoff; 23 | uint64_t e_shoff; 24 | uint32_t e_flags; 25 | uint16_t e_ehsize; 26 | uint16_t e_phentsize; 27 | uint16_t e_phnum; 28 | uint16_t e_shentsize; 29 | uint16_t e_shnum; 30 | uint16_t e_shstrndx; 31 | }__attribute__((packed)); 32 | 33 | struct program_header { 34 | uint32_t p_type; 35 | uint32_t p_flags; 36 | uint64_t p_offset; 37 | uint64_t p_vaddr; 38 | uint64_t p_paddr; 39 | uint64_t p_filesize; 40 | uint64_t p_memsz; 41 | uint64_t p_align; 42 | }__attribute__((packed)); 43 | 44 | struct section_header { 45 | uint32_t sh_name; 46 | uint32_t sh_type; 47 | uint64_t sh_flags; 48 | uint64_t sh_addr; 49 | uint64_t sh_offset; 50 | uint64_t sh_size; 51 | uint32_t sh_link; 52 | uint32_t sh_info; 53 | uint64_t sh_addralign; 54 | uint64_t sh_entsize; 55 | }__attribute__((packed)); 56 | 57 | inline bool is_valid(const char* buffer){ 58 | auto header = reinterpret_cast(buffer); 59 | 60 | //Test if ELF file 61 | if(header->e_ident[0] == 0x7F && header->e_ident[1] == 'E' && 62 | header->e_ident[2] == 'L' && header->e_ident[3] == 'F'){ 63 | 64 | //Test if ELF64 65 | if(header->e_ident[4] == 2){ 66 | return true; 67 | } 68 | } 69 | 70 | return false; 71 | } 72 | 73 | } //end of namespace elf 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /kernel/include/drivers/pci.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PCI_H 9 | #define PCI_H 10 | 11 | #include 12 | 13 | namespace pci { 14 | 15 | enum class device_class_type : uint8_t { 16 | OLD = 0x0, 17 | MASS_STORAGE = 0x1, 18 | NETWORK = 0x2, 19 | DISPLAY = 0x3, 20 | MULTIMEDIA = 0x4, 21 | MEMORY = 0x5, 22 | BRIDGE = 0x6, 23 | SIMPLE_COM = 0x7, 24 | BASE_SYSTEM = 0x8, 25 | INPUT = 0x9, 26 | DOCKING_STATION = 0xA, 27 | PROCESSOR = 0xB, 28 | SERIAL = 0xC, 29 | WIRELESS = 0xD, 30 | SMART_IO = 0xE, 31 | SATELLITE = 0xF, 32 | ENCRYPTION = 0x10, 33 | DATA_ACQUISITION = 0x11, 34 | RESERVED = 0x12, 35 | UNKNOWN = 0x13 36 | }; 37 | 38 | struct device_descriptor { 39 | uint8_t bus; 40 | uint8_t device; 41 | uint8_t function; 42 | 43 | uint16_t vendor_id; 44 | uint16_t device_id; 45 | uint8_t class_code; 46 | uint8_t sub_class; 47 | device_class_type class_type; 48 | }; 49 | 50 | void detect_devices(); 51 | size_t number_of_devices(); 52 | device_descriptor& device(size_t index); 53 | 54 | uint8_t read_config_byte(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); 55 | uint16_t read_config_word(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); 56 | uint32_t read_config_dword(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); 57 | 58 | void write_config_byte(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint8_t value); 59 | void write_config_word(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint16_t value); 60 | void write_config_dword(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value); 61 | 62 | } //end of namespace pci 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /kernel/include/net/packet.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef NET_PACKET_H 9 | #define NET_PACKET_H 10 | 11 | #include 12 | #include 13 | 14 | #include "assert.hpp" 15 | 16 | namespace network { 17 | 18 | /*! 19 | * \brief A network packet. 20 | */ 21 | struct packet { 22 | // Set from the beginning 23 | char* payload; ///< Pointer to the packet payload 24 | size_t payload_size; ///< The size, in bytes, of the payload 25 | size_t index; ///< The current index inside the payload 26 | 27 | // Set for user mode 28 | size_t fd; ///< The file descriptor (in user mode) 29 | bool user; ///< Flag indicating if the packet is a user packet or kernel packet 30 | 31 | uint64_t tags; ///< Tags of the layer indices 32 | uint64_t interface; ///< Id of the interface 33 | 34 | packet() : fd(0), user(false), tags(0) {} 35 | packet(char* payload, size_t payload_size) : payload(payload), payload_size(payload_size), index(0), fd(0), user(false), tags(0) {} 36 | 37 | packet(const packet& rhs) = delete; 38 | packet& operator=(const packet& rhs) = delete; 39 | 40 | packet(const packet&& rhs) = delete; 41 | packet& operator=(const packet&& rhs) = delete; 42 | 43 | ~packet(){ 44 | if(!user && payload){ 45 | delete[] payload; 46 | } 47 | } 48 | 49 | void tag(size_t layer, size_t index){ 50 | tags |= (index << (layer * 16)); 51 | } 52 | 53 | size_t tag(size_t layer) const { 54 | thor_assert(layer < 4, "Invalid tag access"); 55 | return (tags >> (layer * 16)) & 0xFFFF; 56 | } 57 | }; 58 | 59 | using packet_p = std::shared_ptr; 60 | 61 | } // end of network namespace 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /kernel/test_suite/test.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | 11 | #include "test.hpp" 12 | 13 | void path_tests(); 14 | 15 | int main(){ 16 | path_tests(); 17 | 18 | printf("All tests finished\n"); 19 | 20 | return 0; 21 | } 22 | 23 | // TODO Avoid that duplication 24 | 25 | void check(bool condition){ 26 | if(!condition){ 27 | printf("Check failed\n"); 28 | } 29 | } 30 | 31 | void check(bool condition, const char* message){ 32 | if(!condition){ 33 | printf("Check failed: \"%s\"\n", message); 34 | } 35 | } 36 | 37 | void check_equals(long value, long expected, const char* message){ 38 | if(value != expected){ 39 | printf("Check failed: \"%s\"\n", message); 40 | printf("\t expected: %ld was: %ld\n", expected, value); 41 | } 42 | } 43 | 44 | void check(bool condition, const char* where, size_t line){ 45 | if(!condition){ 46 | printf("%s:%lu Check failed\n", where, line); 47 | } 48 | } 49 | 50 | void check(bool condition, const char* message, const char* where, size_t line){ 51 | if(!condition){ 52 | printf("%s:%lu Check failed: \"%s\"\n", where, line, message); 53 | } 54 | } 55 | 56 | void check_equals(long value, long expected, const char* message, const char* where, size_t line){ 57 | if(value != expected){ 58 | printf("%s:%lu Check failed: \"%s\"\n", where, line, message); 59 | printf("\t expected: %ld was: %ld\n", expected, value); 60 | } 61 | } 62 | 63 | void check_equals(long value, long expected, const char* where, size_t line){ 64 | if(value != expected){ 65 | printf("%s:%lu Check failed", where, line); 66 | printf("\t expected: %ld was: %ld\n", expected, value); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /kernel/include/drivers/ata.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ATA_H 9 | #define ATA_H 10 | 11 | #include 12 | #include 13 | 14 | #include "fs/devfs.hpp" 15 | 16 | namespace ata { 17 | 18 | struct drive_descriptor { 19 | uint16_t controller; 20 | uint8_t drive; 21 | bool present; 22 | uint8_t slave; 23 | bool atapi; 24 | std::string model; 25 | std::string serial; 26 | std::string firmware; 27 | size_t size; 28 | }; 29 | 30 | void detect_disks(); 31 | uint8_t number_of_disks(); 32 | drive_descriptor& drive(uint8_t disk); 33 | 34 | size_t read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination, size_t& read); 35 | size_t write_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, const void* source, size_t& written); 36 | size_t clear_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, size_t& written); 37 | 38 | struct ata_driver final : devfs::dev_driver { 39 | size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read) override; 40 | size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written) override; 41 | size_t clear(void* data, size_t count, size_t offset, size_t& written) override; 42 | size_t size(void* data) override; 43 | }; 44 | 45 | struct ata_part_driver final : devfs::dev_driver { 46 | size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read) override; 47 | size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written) override; 48 | size_t clear(void* data, size_t count, size_t offset, size_t& written) override; 49 | size_t size(void* data) override; 50 | }; 51 | 52 | } // end of namespace ata 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tstl/include/function.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STD_FUNCTION_HPP 9 | #define STD_FUNCTION_HPP 10 | 11 | #include 12 | #include 13 | 14 | namespace std { 15 | 16 | template 17 | struct function; 18 | 19 | template 20 | struct function { 21 | public: 22 | template 23 | function(T&& t){ 24 | typedef model::type> impl; 25 | 26 | static_assert(sizeof(impl) <= sizeof(storage), "Limited size in function"); 27 | static_assert(std::is_trivially_destructible::value, "Limited support of function"); 28 | 29 | auto* s = static_cast(&storage[0]); 30 | new (s) impl(std::forward(t)); 31 | } 32 | 33 | function(const function& rhs) = delete; 34 | function& operator=(const function& rhs) = delete; 35 | 36 | function(function&& rhs) = delete; 37 | function& operator=(function&& rhs) = delete; 38 | 39 | R operator()(Args... args) const { 40 | auto* s = static_cast(&storage[0]); 41 | auto* c = static_cast(s); 42 | return (*c)(std::forward(args)...); 43 | } 44 | 45 | private: 46 | size_t storage[2]; 47 | 48 | struct concept { 49 | virtual R operator()(Args...) const = 0; 50 | }; 51 | 52 | template 53 | struct model : concept { 54 | template 55 | model(U&& u) : t(std::forward(u)){ 56 | //Nothing to init 57 | } 58 | 59 | R operator()(Args... args) const override { 60 | return t(std::forward(args)...); 61 | } 62 | 63 | T t; 64 | }; 65 | }; 66 | 67 | } //end of namespace std 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /kernel/include/console.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef CONSOLE_H 9 | #define CONSOLE_H 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace stdio { 18 | 19 | /*! 20 | * \brief Init the console 21 | */ 22 | void init_console(); 23 | 24 | /*! 25 | * \brief A console 26 | */ 27 | struct console { 28 | /*! 29 | * \brief Init the console 30 | */ 31 | void init(); 32 | 33 | /*! 34 | * \brief Returns the number of columns of the console 35 | */ 36 | size_t get_columns() const; 37 | 38 | /*! 39 | * \brief Returns the number of rows of the console 40 | */ 41 | size_t get_rows() const; 42 | 43 | /*! 44 | * \brief Print the given char to the console 45 | * \param c The character to print 46 | */ 47 | void print(char c); 48 | 49 | /*! 50 | * \brief Clear the console 51 | */ 52 | void wipeout(); 53 | 54 | /*! 55 | * \brief Set the active status of the console 56 | * \param active The active status of the console 57 | */ 58 | void set_active(bool active); 59 | 60 | /*! 61 | * \brief Save the state of the console 62 | */ 63 | void save(); 64 | 65 | /*! 66 | * \brief Restore the state of the console 67 | */ 68 | void restore(); 69 | 70 | private: 71 | /*! 72 | * \brief Move to the next line 73 | */ 74 | void next_line(); 75 | 76 | size_t current_line = 0; ///< The current line of the console 77 | size_t current_column = 0; ///< The current column of the console 78 | 79 | void* buffer = nullptr; ///< The buffer to save the state 80 | bool active = false; ///< The active status of the console 81 | }; 82 | 83 | } // end of namespace stdio 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /tstl/include/atomic.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef ATOMIC_HPP 9 | #define ATOMIC_HPP 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | template 16 | struct atomic; 17 | 18 | template<> 19 | struct atomic { 20 | using value_type = uint64_t; 21 | 22 | atomic() = default; 23 | 24 | atomic(const atomic& rhs) = delete; 25 | atomic& operator=(const atomic& rhs) = delete; 26 | 27 | explicit atomic(value_type value) : value(value) {} 28 | 29 | value_type load() const { 30 | return __atomic_load_n(&value, __ATOMIC_CONSUME); 31 | } 32 | 33 | value_type operator=(bool new_value){ 34 | __atomic_store_n(&value, new_value, __ATOMIC_RELEASE); 35 | 36 | return new_value; 37 | } 38 | 39 | private: 40 | volatile bool value; 41 | }; 42 | 43 | template<> 44 | struct atomic { 45 | using value_type = uint64_t; 46 | 47 | atomic() = default; 48 | 49 | atomic(const atomic& rhs) = delete; 50 | atomic& operator=(const atomic& rhs) = delete; 51 | 52 | explicit atomic(value_type value) : value(value) {} 53 | 54 | value_type load() const { 55 | return __atomic_load_n(&value, __ATOMIC_CONSUME); 56 | } 57 | 58 | value_type operator=(uint64_t new_value){ 59 | __atomic_store_n(&value, new_value, __ATOMIC_RELEASE); 60 | 61 | return new_value; 62 | } 63 | 64 | value_type operator++(){ 65 | auto new_value = __atomic_add_fetch(&value, 1, __ATOMIC_RELEASE); 66 | return new_value; 67 | } 68 | 69 | value_type operator++(int){ 70 | auto new_value = __atomic_fetch_add(&value, 1, __ATOMIC_RELEASE); 71 | return new_value; 72 | } 73 | 74 | private: 75 | volatile uint64_t value; 76 | }; 77 | 78 | } //end of namespace std 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /kernel/src/task_switch.s: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2016. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT_1_0.txt) 6 | //======================================================================= 7 | 8 | .intel_syntax noprefix 9 | 10 | #include "include/scheduler_asm.hpp" 11 | .include "src/common.s" 12 | 13 | .global init_task_switch 14 | .global task_switch 15 | 16 | // extern void init_task_switch(size_t next); 17 | 18 | init_task_switch: 19 | // Switch to the new CR3 20 | push rdi 21 | call get_process_cr3 22 | pop rdi 23 | mov cr3, rax 24 | 25 | push rdi 26 | call get_context_address 27 | pop rdi 28 | mov rsp, [rax] 29 | 30 | restore_context_light 31 | 32 | //Was pushed by the base handler code 33 | add rsp, 8 34 | 35 | iretq // iret will clean the other automatically pushed stuff 36 | 37 | // extern void task_switch(size_t current, size_t next); 38 | 39 | task_switch: 40 | push rax 41 | 42 | // Those are perhaps not necessary 43 | mov rax, ss 44 | push rax 45 | mov rax, rsp 46 | push rax 47 | 48 | pushfq 49 | mov rax, cs 50 | push rax 51 | lea rax, [resume_rip] 52 | push rax 53 | 54 | // Fake error code 55 | push 0 56 | 57 | // Push the current context on the stack 58 | save_context 59 | 60 | // Save the new context pointer 61 | push rdi 62 | push rsi 63 | call get_context_address 64 | pop rsi 65 | pop rdi 66 | mov [rax], rsp 67 | 68 | // Switch to the new CR3 69 | push rdi 70 | push rsi 71 | mov rdi, rsi 72 | call get_process_cr3 73 | pop rsi 74 | pop rdi 75 | mov cr3, rax 76 | 77 | //Switch to the new task's stack 78 | push rdi 79 | push rsi 80 | mov rdi, rsi 81 | call get_context_address 82 | pop rsi 83 | pop rdi 84 | mov rsp, [rax] 85 | 86 | restore_context 87 | 88 | //Was pushed by the base handler code 89 | add rsp, 8 90 | 91 | iretq // iret will clean the other automatically pushed stuff 92 | 93 | resume_rip: 94 | pop rax 95 | pop rax 96 | retq 97 | -------------------------------------------------------------------------------- /programs/df/src/main.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static constexpr const size_t BUFFER_SIZE = 4096; 16 | 17 | int main(int argc, char* argv[]){ 18 | bool human = false; 19 | 20 | for(size_t i = 1; i < size_t(argc); ++i){ 21 | std::string param(argv[i]); 22 | 23 | if(param == "-h"){ 24 | human = true; 25 | } 26 | } 27 | 28 | auto buffer = new char[BUFFER_SIZE]; 29 | 30 | auto mp_result = tlib::mounts(buffer, BUFFER_SIZE); 31 | 32 | if(mp_result.valid()){ 33 | size_t position = 0; 34 | 35 | tlib::print_line("File system Size Used Available"); 36 | 37 | while(true){ 38 | auto entry = reinterpret_cast(buffer + position); 39 | 40 | auto mount_point = &entry->name; 41 | 42 | auto statfs_result = tlib::statfs(mount_point); 43 | 44 | if(statfs_result.valid()){ 45 | auto& statfs = *statfs_result; 46 | 47 | if(human){ 48 | tlib::printf("%s %m %m %m\n", mount_point, statfs.total_size, statfs.total_size - statfs.free_size, statfs.free_size); 49 | } else { 50 | tlib::printf("%s %u %u %u\n", mount_point, statfs.total_size, statfs.total_size - statfs.free_size, statfs.free_size); 51 | } 52 | } else { 53 | tlib::printf("df: error: %s\n", std::error_message(statfs_result.error())); 54 | } 55 | 56 | if(!entry->offset_next){ 57 | break; 58 | } 59 | 60 | position += entry->offset_next; 61 | } 62 | } else { 63 | tlib::printf("df: error: %s\n", std::error_message(mp_result.error())); 64 | } 65 | 66 | delete[] buffer; 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /tstl/include/queue.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STL_QUEUE_H 9 | #define STL_QUEUE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace std { 15 | 16 | /*! 17 | * \brief Container adapter to provide a queue (FIFO) 18 | */ 19 | template> 20 | struct queue { 21 | using reference_type = typename C::reference_type; 22 | using const_reference_type = typename C::const_reference_type; 23 | 24 | /*! 25 | * \brief Indicates if the queue is empty 26 | */ 27 | bool empty() const { 28 | return size() == 0; 29 | } 30 | 31 | /*! 32 | * \brief Returns the size of the queue 33 | */ 34 | size_t size() const { 35 | return container.size(); 36 | } 37 | 38 | /*! 39 | * \brief Push a new element onto the queue 40 | */ 41 | void push(T&& value){ 42 | container.push_back(std::move(value)); 43 | } 44 | 45 | /*! 46 | * \brief Push a new element onto the queue 47 | */ 48 | void push(const T& value){ 49 | container.push_back(value); 50 | } 51 | 52 | /*! 53 | * \brief Create a new element inplace onto the queue 54 | */ 55 | template 56 | reference_type emplace(Args&&... args){ 57 | return container.emplace_back(std::forward(args)...); 58 | } 59 | 60 | /*! 61 | * \brief Pop the top element from the queue 62 | */ 63 | void pop(){ 64 | container.pop_front(); 65 | } 66 | 67 | /*! 68 | * \brief Returns a reference to the top element 69 | */ 70 | reference_type top(){ 71 | return container.front(); 72 | } 73 | 74 | /*! 75 | * \brief Returns a const reference to the top element 76 | */ 77 | const_reference_type top() const { 78 | return container.front(); 79 | } 80 | 81 | private: 82 | C container; ///< The underlying container 83 | }; 84 | 85 | } //end of namespace std 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /kernel/include/kernel_utils.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef KERNEL_UTILS_H 9 | #define KERNEL_UTILS_H 10 | 11 | #ifndef THOR_INIT 12 | #include 13 | #endif 14 | 15 | inline uint8_t in_byte(uint16_t _port){ 16 | uint8_t rv; 17 | 18 | asm volatile ("in %[data], %[port]" 19 | : [data] "=a" (rv) 20 | : [port] "dN" (_port)); 21 | 22 | return rv; 23 | } 24 | 25 | inline void out_byte (uint16_t _port, uint8_t _data){ 26 | asm volatile ("out %[port], %[data]" 27 | : /* No outputs */ 28 | : [port] "dN" (_port), [data] "a" (_data)); 29 | } 30 | 31 | inline uint16_t in_word(uint16_t _port){ 32 | uint16_t rv; 33 | 34 | asm volatile ("in %[data], %[port]" 35 | : [data] "=a" (rv) 36 | : [port] "dN" (_port)); 37 | 38 | return rv; 39 | } 40 | 41 | inline void out_word(uint16_t _port, uint16_t _data){ 42 | asm volatile ("out %[port], %[data]" 43 | : /* No outputs */ 44 | : [port] "dN" (_port), [data] "a" (_data)); 45 | } 46 | 47 | #ifndef THOR_INIT 48 | 49 | inline uint32_t in_dword(uint16_t _port){ 50 | uint32_t rv; 51 | 52 | asm volatile ("in %[data], %[port]" 53 | : [data] "=a" (rv) 54 | : [port] "dN" (_port)); 55 | 56 | return rv; 57 | } 58 | 59 | inline void out_dword(uint16_t _port, uint32_t _data){ 60 | asm volatile ("out %[port], %[data]" 61 | : /* No outputs */ 62 | : [port] "dN" (_port), [data] "a" (_data)); 63 | } 64 | 65 | inline uint16_t switch_endian_16(uint16_t nb) { 66 | return (nb>>8) | (nb<<8); 67 | } 68 | 69 | inline uint32_t switch_endian_32(uint32_t nb) { 70 | return ((nb>>24)&0xff) | 71 | ((nb<<8)&0xff0000) | 72 | ((nb>>8)&0xff00) | 73 | ((nb<<24)&0xff000000); 74 | } 75 | 76 | void print_stack(const char* msg, size_t check); 77 | #define SHOW_STACK(M) { size_t check = 0; asm volatile("mov %0, rsp;" : "=r" (check)); print_stack(((M)), check); } 78 | 79 | #endif //THOR_INIT 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /tstl/include/types.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TYPES_H 9 | #define TYPES_H 10 | 11 | typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); ///< An unsigned 8-bit number 12 | typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); ///< An unsigned 16-bit number 13 | typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); ///< An unsigned 32-bit number 14 | typedef unsigned int uint64_t __attribute__ ((__mode__ (__DI__))); ///< An unsigned 64-bit number 15 | 16 | typedef int int8_t __attribute__((__mode__(__QI__))); ///< A signed 8-bit number 17 | typedef int int16_t __attribute__ ((__mode__ (__HI__))); ///< A signed 16-bit number 18 | typedef int int32_t __attribute__ ((__mode__ (__SI__))); ///< A signed 32-bit number 19 | typedef int int64_t __attribute__ ((__mode__ (__DI__))); ///< A signed 64-bit number 20 | 21 | typedef uint64_t uintptr_t; ///< Type that can be used to store a pointer value 22 | typedef uint64_t size_t; ///< Type that can be used to store the size of a collectiotn 23 | 24 | typedef double sse_128 __attribute__((vector_size(16))); ///< SSE 128-bit value 25 | 26 | static_assert(sizeof(uint8_t) == 1, "uint8_t must be 1 byte long"); 27 | static_assert(sizeof(uint16_t) == 2, "uint16_t must be 2 bytes long"); 28 | static_assert(sizeof(uint32_t) == 4, "uint32_t must be 4 bytes long"); 29 | static_assert(sizeof(uint64_t) == 8, "uint64_t must be 8 bytes long"); 30 | 31 | static_assert(sizeof(int8_t) == 1, "int8_t must be 1 byte long"); 32 | static_assert(sizeof(int16_t) == 2, "int16_t must be 2 bytes long"); 33 | static_assert(sizeof(int32_t) == 4, "int32_t must be 4 bytes long"); 34 | static_assert(sizeof(int64_t) == 8, "int64_t must be 8 bytes long"); 35 | 36 | static_assert(sizeof(size_t) == 8, "size_t must be 8 bytes long"); 37 | 38 | static_assert(sizeof(sse_128) == 16, "xmm registers are 16 bytes long"); 39 | 40 | #ifndef CODE_32 41 | #ifndef CODE_16 42 | static_assert(sizeof(uintptr_t) == sizeof(uint64_t*), "uintptr_t must have the same size as a pointer"); 43 | #endif 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /tstl/include/optional.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef OPTIONAL_H 9 | #define OPTIONAL_H 10 | 11 | #include "algorithms.hpp" 12 | 13 | namespace std { 14 | 15 | struct dummy_t {}; 16 | 17 | template 18 | union optional_storage { 19 | dummy_t dummy; 20 | T value; 21 | 22 | constexpr optional_storage() : dummy() {} 23 | constexpr optional_storage(const T& v) : value(v) {} 24 | constexpr optional_storage(T&& v) : value(std::forward(v)) {} 25 | 26 | optional_storage& operator=(const T& v){ 27 | value = v; 28 | } 29 | 30 | optional_storage& operator=(T&& v){ 31 | value = v; 32 | } 33 | 34 | ~optional_storage(){} 35 | }; 36 | 37 | template 38 | class optional { 39 | bool initialized; 40 | optional_storage storage; 41 | 42 | public: 43 | constexpr optional() : initialized(false), storage() {} 44 | constexpr optional(const T& value) : initialized(true), storage(value) {} 45 | constexpr optional(T&& value) : initialized(true), storage(std::forward(value)) {} 46 | 47 | optional(const optional& rhs) : initialized(rhs.initialized) { 48 | if(rhs.initialized){ 49 | storage.value = rhs.storage.value; 50 | } 51 | } 52 | 53 | optional(optional&& rhs) : initialized(rhs.initialized) { 54 | if(rhs.initialized){ 55 | storage.value = std::move(rhs.storage.value); 56 | } 57 | } 58 | 59 | constexpr T const& operator*(){ 60 | return storage.value; 61 | } 62 | 63 | ~optional(){ 64 | if(initialized){ 65 | storage.value.~T(); 66 | } 67 | } 68 | 69 | constexpr const T* operator->() const { 70 | return &storage.value; 71 | } 72 | 73 | T* operator->() { 74 | return &storage.value; 75 | } 76 | 77 | T& operator*(){ 78 | return storage.value; 79 | } 80 | 81 | constexpr operator bool() const { 82 | return initialized; 83 | } 84 | }; 85 | 86 | } //end of namespace std 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /kernel/include/physical_allocator.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PHYSICAL_ALLOCATOR_H 9 | #define PHYSICAL_ALLOCATOR_H 10 | 11 | #include 12 | 13 | namespace physical_allocator { 14 | 15 | /*! 16 | * \brief Early initialization of the physical allocator. 17 | * 18 | * This finalizes the e820 memory detection and start preparing memory from one of the blocks 19 | */ 20 | void early_init(); 21 | 22 | /*! 23 | * \brief Early allocation of physical memory pages 24 | * \param pages The number of pages to allocate 25 | */ 26 | size_t early_allocate(size_t pages); 27 | 28 | /* 29 | * \brief Initialize the real physical allocator. 30 | * 31 | * After this point, the early_allocate function should not be called 32 | */ 33 | void init(); 34 | 35 | /*! 36 | * \brief Finalize the physical allocator, must be called after sysfs initialization 37 | */ 38 | void finalize(); 39 | 40 | /*! 41 | * \brief Allocate several pages of physical memory 42 | * \param pages The number of pages 43 | * \return The physical addres of the allocated pages 44 | */ 45 | size_t allocate(size_t pages); 46 | 47 | /*! 48 | * \brief Free the allocated physical memory 49 | * \param address The address of the allocated physical memory 50 | * \param pages The number of pages 51 | */ 52 | void free(size_t address, size_t pages); 53 | 54 | /*! 55 | * \brief Return the amount of physical memory available 56 | */ 57 | size_t total_available(); 58 | 59 | /*! 60 | * \brief Return the amount of physical memory currently available 61 | */ 62 | size_t available(); 63 | 64 | /*! 65 | * \brief Return the amount of physical memory allocated 66 | */ 67 | size_t total_allocated(); 68 | 69 | /*! 70 | * \brief Return the amount of physical memory currently allocated 71 | */ 72 | size_t allocated(); 73 | 74 | /*! 75 | * \brief Return the amount of physical memory currently free 76 | */ 77 | size_t free(); 78 | 79 | /*! 80 | * \brief Return the amount of physical memory free 81 | */ 82 | size_t total_free(); 83 | 84 | } //end of physical_allocator namespace 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /kernel/src/text_console.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include 9 | 10 | #include "text_console.hpp" 11 | 12 | namespace { 13 | 14 | enum vga_color { 15 | BLACK = 0, 16 | BLUE = 1, 17 | GREEN = 2, 18 | CYAN = 3, 19 | RED = 4, 20 | MAGENTA = 5, 21 | BROWN = 6, 22 | LIGHT_GREY = 7, 23 | DARK_GREY = 8, 24 | LIGHT_BLUE = 9, 25 | LIGHT_GREEN = 10, 26 | LIGHT_CYAN = 11, 27 | LIGHT_RED = 12, 28 | LIGHT_MAGENTA = 13, 29 | LIGHT_BROWN = 14, 30 | WHITE = 15, 31 | }; 32 | 33 | uint8_t make_color(vga_color fg, vga_color bg) { 34 | return fg | bg << 4; 35 | } 36 | 37 | uint16_t make_vga_entry(char c, uint8_t color) { 38 | uint16_t c16 = c; 39 | uint16_t color16 = color; 40 | return c16 | color16 << 8; 41 | } 42 | 43 | } //end of anonymous namespace 44 | 45 | void text_console::init() { 46 | //Nothing special to init 47 | } 48 | 49 | size_t text_console::lines() { 50 | return 25; 51 | } 52 | 53 | size_t text_console::columns() { 54 | return 80; 55 | } 56 | 57 | void text_console::clear() { 58 | for (int line = 0; line < 25; ++line) { 59 | for (uint64_t column = 0; column < 80; ++column) { 60 | print_char(line, column, ' '); 61 | } 62 | } 63 | } 64 | 65 | void text_console::scroll_up() { 66 | auto vga_buffer_fast = reinterpret_cast(0x0B8000); 67 | auto destination = vga_buffer_fast; 68 | auto source = &vga_buffer_fast[20]; 69 | 70 | std::copy_n(source, 24 * 20, destination); 71 | 72 | auto vga_buffer = reinterpret_cast(0x0B8000); 73 | for (uint64_t i = 0; i < 80; ++i) { 74 | vga_buffer[24 * 80 + i] = make_vga_entry(' ', make_color(WHITE, BLACK)); 75 | } 76 | } 77 | 78 | void text_console::print_char(size_t line, size_t column, char c) { 79 | uint16_t* vga_buffer = reinterpret_cast(0x0B8000); 80 | 81 | vga_buffer[line * 80 + column] = make_vga_entry(c, make_color(WHITE, BLACK)); 82 | } 83 | -------------------------------------------------------------------------------- /tstl/include/pair.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef PAIR_H 9 | #define PAIR_H 10 | 11 | namespace std { 12 | 13 | /*! 14 | * \brief Simply container to hold a pair of element 15 | */ 16 | template 17 | class pair { 18 | public: 19 | using first_type = T1; ///< The type of the first element 20 | using second_type = T2; ///< The type of the second element 21 | 22 | first_type first; ///< The first element 23 | second_type second; ///< The second element 24 | 25 | //Constructor 26 | 27 | constexpr pair(const first_type& a, const second_type& b) : first(a), second(b){ 28 | //Nothing to init 29 | } 30 | 31 | template 32 | constexpr pair(U1&& x, U2&& y) : first(std::forward(x)), second(std::forward(y)){ 33 | //Nothing to init 34 | } 35 | 36 | //Copy constructors 37 | 38 | constexpr pair(const pair&) = default; 39 | 40 | template 41 | constexpr pair(const pair& p) : first(p.first), second(p.second) { 42 | //Nothing to init 43 | } 44 | 45 | template 46 | pair& operator=(const pair& p){ 47 | first = p.first; 48 | second = p.second; 49 | return *this; 50 | } 51 | 52 | //Move constructors 53 | 54 | constexpr pair(pair&&) = default; 55 | 56 | template 57 | constexpr pair(pair&& p) : first(std::move(p.first)), second(std::move(p.second)) { 58 | //Nothing to init 59 | } 60 | 61 | template 62 | pair& operator=(pair&& p){ 63 | first = std::forward(p.first); 64 | second = std::forward(p.second); 65 | return *this; 66 | } 67 | }; 68 | 69 | /*! 70 | * \brief Helper to construct a pair 71 | */ 72 | template 73 | inline constexpr pair make_pair(T1&& x, T2&& y){ 74 | return pair(std::forward(x), std::forward(y)); 75 | } 76 | 77 | } //end of namespace std 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /tstl/include/random.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef RANDOM_HPP 9 | #define RANDOM_HPP 10 | 11 | #include 12 | 13 | namespace std { 14 | 15 | template 16 | struct linear_congruential_engine { 17 | using result_type = UIntType; 18 | 19 | static constexpr const result_type multiplier = a; 20 | static constexpr const result_type increment = c; 21 | static constexpr const result_type modulus = m; 22 | static constexpr const result_type default_seed = 1; 23 | 24 | linear_congruential_engine(result_type seed = default_seed) : seed(seed){ 25 | // Generate the second result directly 26 | (*this)(); 27 | } 28 | 29 | result_type operator()(){ 30 | return seed = (multiplier * seed + increment) % modulus; 31 | } 32 | 33 | static constexpr result_type min(){ 34 | return 0; 35 | } 36 | 37 | static constexpr result_type max(){ 38 | return modulus - 1; 39 | } 40 | 41 | private: 42 | result_type seed; 43 | }; 44 | 45 | using mnist_rand0 = linear_congruential_engine; 46 | using mnist_rand = linear_congruential_engine; 47 | 48 | using default_random_engine = mnist_rand; 49 | 50 | template 51 | struct uniform_int_distribution { 52 | using result_type = IntType; 53 | 54 | uniform_int_distribution(result_type a, result_type b) : a(a), b(b) { 55 | //Nothing else to init 56 | } 57 | 58 | template 59 | result_type operator()(Generator& g) const { 60 | static constexpr const auto input_range = Generator::max() - Generator::min(); 61 | 62 | const auto output_range = b - a; 63 | const auto ratio = input_range / output_range; 64 | const auto offset = a - Generator::min(); 65 | 66 | return (g() / ratio) + offset; 67 | } 68 | 69 | private: 70 | const result_type a; 71 | const result_type b; 72 | }; 73 | 74 | } //end of namespace std 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /tstl/include/integer_sequence.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef TSTL_INTEGER_SEQUENCE_H 9 | #define TSTL_INTEGER_SEQUENCE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace std { 15 | 16 | template 17 | struct integer_sequence { 18 | static constexpr size_t size() noexcept { 19 | return sizeof...(Values); 20 | } 21 | }; 22 | 23 | template 24 | using index_sequence = integer_sequence; 25 | 26 | template 27 | struct sequence_concat_impl; 28 | 29 | template 30 | struct sequence_concat_impl, N, false> { 31 | using type = integer_sequence; 32 | }; 33 | 34 | template 35 | struct sequence_concat_impl, N, true> { 36 | using type = integer_sequence; 37 | }; 38 | 39 | // The 0 and 1 cannot be deduced directly, must use SFINAE 40 | 41 | // Base type for generating a sequence 42 | template 43 | struct make_integer_sequence_impl; 44 | 45 | // The general case construct a list by concatenating 46 | template 47 | struct make_integer_sequence_impl { 48 | using type = typename sequence_concat_impl::type, N / 2, N % 2 == 1>::type; 49 | }; 50 | 51 | // Specialization for empty sequence 52 | template 53 | struct make_integer_sequence_impl> { 54 | using type = integer_sequence; 55 | }; 56 | 57 | // Specialization for sequence of length one 58 | template 59 | struct make_integer_sequence_impl> { 60 | using type = integer_sequence; 61 | }; 62 | 63 | template 64 | using make_integer_sequence = typename make_integer_sequence_impl::type; 65 | 66 | template 67 | using make_index_sequence = make_integer_sequence; 68 | 69 | } //end of namespace std 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /tstl/include/stack.hpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #ifndef STL_STACK_H 9 | #define STL_STACK_H 10 | 11 | #include 12 | #include 13 | 14 | namespace std { 15 | 16 | /*! 17 | * \brief Container adapter to provide a stack (LIFO) 18 | */ 19 | template> 20 | struct stack { 21 | using reference_type = typename C::reference_type; 22 | using const_reference_type = typename C::const_reference_type; 23 | 24 | /*! 25 | * \brief Indicates if the stack is empty 26 | */ 27 | bool empty() const { 28 | return size() == 0; 29 | } 30 | 31 | /*! 32 | * \brief Returns the size of the stack 33 | */ 34 | size_t size() const { 35 | return container.size(); 36 | } 37 | 38 | /*! 39 | * \brief Adds the element at the top of the stack 40 | * \param value The element to add on the stack 41 | */ 42 | void push(T&& value){ 43 | container.push_back(std::move(value)); 44 | } 45 | 46 | /*! 47 | * \brief Adds the element at the top of the stack 48 | * \param value The element to add on the stack 49 | */ 50 | void push(const T& value){ 51 | container.push_back(value); 52 | } 53 | 54 | /*! 55 | * \brief Create a new element inplace onto the stack 56 | */ 57 | template 58 | reference_type emplace(Args&&... args){ 59 | return container.emplace_back(std::forward(args)...); 60 | } 61 | 62 | /*! 63 | * \brief Removes the element at the top of the stack 64 | */ 65 | void pop(){ 66 | container.pop_back(); 67 | } 68 | 69 | /*! 70 | * \brief Returns a reference to the element at the top of the stack 71 | */ 72 | reference_type top(){ 73 | return container.back(); 74 | } 75 | 76 | /*! 77 | * \brief Returns a const reference to the element at the top of the stack 78 | */ 79 | const_reference_type top() const { 80 | return container.back(); 81 | } 82 | 83 | private: 84 | C container; ///< The underlying container 85 | }; 86 | 87 | } //end of namespace std 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /kernel/src/e820.cpp: -------------------------------------------------------------------------------- 1 | //======================================================================= 2 | // Copyright Baptiste Wicht 2013-2018. 3 | // Distributed under the terms of the MIT License. 4 | // (See accompanying file LICENSE or copy at 5 | // http://www.opensource.org/licenses/MIT) 6 | //======================================================================= 7 | 8 | #include "e820.hpp" 9 | #include "early_memory.hpp" 10 | #include "logging.hpp" 11 | 12 | namespace { 13 | 14 | e820::mmapentry e820_mmap[e820::MAX_E820_ENTRIES]; 15 | size_t _available_memory; 16 | size_t e820_entries = 0; 17 | 18 | } //end of namespace anonymous 19 | 20 | void e820::finalize_memory_detection(){ 21 | e820_entries = early::e820_entry_count(); 22 | 23 | auto t = mmap_entry_count(); 24 | 25 | auto* smap = reinterpret_cast(early::e820_entry_address); 26 | 27 | if(t > 0){ 28 | for(size_t i = 0; i < t; ++i){ 29 | auto& bios_entry = smap[i]; 30 | auto& os_entry = e820_mmap[i]; 31 | 32 | uint64_t base = bios_entry.base_low + (static_cast(bios_entry.base_high) << 32); 33 | uint64_t length = bios_entry.length_low + (static_cast(bios_entry.length_high) << 32); 34 | 35 | os_entry.base = base; 36 | os_entry.size = length; 37 | os_entry.type = bios_entry.type; 38 | 39 | if(os_entry.base == 0 && os_entry.type == 1){ 40 | os_entry.type = 7; 41 | } 42 | 43 | if(os_entry.type == 1){ 44 | _available_memory += os_entry.size; 45 | } 46 | } 47 | } 48 | } 49 | 50 | uint64_t e820::mmap_entry_count(){ 51 | return e820_entries; 52 | } 53 | 54 | bool e820::mmap_failed(){ 55 | return mmap_entry_count() <= 0; 56 | } 57 | 58 | const e820::mmapentry& e820::mmap_entry(uint64_t i){ 59 | return e820_mmap[i]; 60 | } 61 | 62 | const char* e820::str_e820_type(uint64_t type){ 63 | switch(type){ 64 | case 1: 65 | return "Free"; 66 | case 2: 67 | return "Reserved"; 68 | case 3: 69 | case 4: 70 | return "ACPI"; 71 | case 5: 72 | return "Unusable"; 73 | case 6: 74 | return "Disabled"; 75 | case 7: 76 | return "Kernel"; 77 | default: 78 | return "Unknown"; 79 | } 80 | } 81 | 82 | size_t e820::available_memory(){ 83 | return _available_memory; 84 | } 85 | --------------------------------------------------------------------------------