8 Commits

Author SHA1 Message Date
karina b7a4a90e63 fix: fix hot loader page reuse for overlapping init segments 2026-04-21 00:30:41 +04:00
karina 41578c29d6 build: fixed building on macOS 2026-04-21 00:09:30 +04:00
Karina d42fc79c25 WIP: Rust std for termos's userspace 2026-04-15 14:44:10 +04:00
Karina b44e1924ed wip: experimental rust support in runtime 2026-04-13 23:40:41 +04:00
Karina 4909e40cb1 docs: readme update again 2026-04-04 19:47:30 +04:00
Karina 7102edfa5a docs: readme update 2026-04-04 19:47:18 +04:00
Karina 47735bb1bd REF: Renamed kernel -> System; userspace -> Runtime; bootloader -> Boot
del: KSH
2026-04-04 19:44:39 +04:00
Karina 2f58f64175 feat(libkern): strrchr (StringFindLastOccurenceOfCharacter)
fix(OSServiceProcessSpawn): now it uses strrchr to get process name
2026-02-01 21:02:54 +04:00
136 changed files with 522 additions and 335 deletions
+2
View File
@@ -1,7 +1,9 @@
.cache .cache
.vscode
build* build*
.venv .venv
initrd/image.cpio initrd/image.cpio
initramfs/* initramfs/*
target target
Cargo.lock
@@ -1,5 +1,9 @@
project(termOS_Bootloader LANGUAGES C ASM) project(termOS_Bootloader LANGUAGES C ASM)
if(APPLE)
set(CMAKE_C_LINK_FLAGS "")
endif()
set(UEFI_COMPILE_OPTIONS set(UEFI_COMPILE_OPTIONS
-std=c23 -std=c23
-target x86_64-unknown-windows-msvc -target x86_64-unknown-windows-msvc
@@ -20,14 +24,15 @@ set(POSIX_UEFI_SOURCES
src/uefi/unistd.c src/uefi/unistd.c
) )
add_library(posix_uefi_lib STATIC ${POSIX_UEFI_SOURCES}) add_library(posix_uefi_lib OBJECT ${POSIX_UEFI_SOURCES})
target_compile_options(posix_uefi_lib PRIVATE ${UEFI_COMPILE_OPTIONS}) target_compile_options(posix_uefi_lib PRIVATE ${UEFI_COMPILE_OPTIONS})
target_include_directories(posix_uefi_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/uefi) target_include_directories(posix_uefi_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/uefi)
add_executable(BOOTX64 src/main.c) add_executable(BOOTX64 src/main.c)
target_compile_options(BOOTX64 PRIVATE ${UEFI_COMPILE_OPTIONS}) target_compile_options(BOOTX64 PRIVATE ${UEFI_COMPILE_OPTIONS})
target_sources(BOOTX64 PRIVATE $<TARGET_OBJECTS:posix_uefi_lib>)
target_link_libraries(BOOTX64 PRIVATE posix_uefi_lib) target_include_directories(BOOTX64 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/uefi)
target_link_options(BOOTX64 PRIVATE target_link_options(BOOTX64 PRIVATE
-fuse-ld=lld -fuse-ld=lld
+15 -20
View File
@@ -10,7 +10,7 @@ find_program(MCOPY_EXE mcopy)
find_program(MKFS_EXE mkfs.fat) find_program(MKFS_EXE mkfs.fat)
find_program(CPIO_EXE cpio) find_program(CPIO_EXE cpio)
find_program(QEMU_EXE qemu-system-x86_64) find_program(QEMU_EXE qemu-system-x86_64)
set(OVMF_PATH "/usr/share/edk2/ovmf/OVMF_CODE.fd" CACHE FILEPATH "Path to OVMF bios") set(OVMF_PATH "/usr/share/edk2/x64/OVMF.4m.fd" CACHE FILEPATH "Path to OVMF bios")
execute_process( execute_process(
COMMAND git describe --tags --always --dirty COMMAND git describe --tags --always --dirty
@@ -26,14 +26,15 @@ endif()
message(STATUS "Building termOS version: ${KERNEL_VERSION}") message(STATUS "Building termOS version: ${KERNEL_VERSION}")
add_compile_definitions(TERMOS_VERSION=\"${KERNEL_VERSION}\") add_compile_definitions(TERMOS_VERSION=\"${KERNEL_VERSION}\")
add_subdirectory(bootloader) add_subdirectory(Boot)
add_subdirectory(kernel) add_subdirectory(System)
add_subdirectory(userspace) add_subdirectory(Runtime)
set(SYSTEM_SERVICES set(SYSTEM_SERVICES
init init
debug debug
termosh termosh
rtest
) )
set(VOLUME_ROOT "${CMAKE_BINARY_DIR}/StartupVolume") set(VOLUME_ROOT "${CMAKE_BINARY_DIR}/StartupVolume")
@@ -41,37 +42,31 @@ set(INITRAMFS_CPIO_FILE "${CMAKE_BINARY_DIR}/StartupVolume.cpio")
set(IMG_FILE "${CMAKE_BINARY_DIR}/termOS.img") set(IMG_FILE "${CMAKE_BINARY_DIR}/termOS.img")
if(MCOPY_EXE AND MKFS_EXE AND CPIO_EXE) if(MCOPY_EXE AND MKFS_EXE AND CPIO_EXE)
add_custom_command( add_custom_target(image ALL
OUTPUT ${INITRAMFS_CPIO_FILE}
COMMAND ${CMAKE_COMMAND} -E make_directory ${VOLUME_ROOT} COMMAND ${CMAKE_COMMAND} -E make_directory ${VOLUME_ROOT}
COMMAND sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\"" COMMAND sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\""
WORKING_DIRECTORY ${VOLUME_ROOT}
DEPENDS ${SYSTEM_SERVICES}
VERBATIM
COMMENT "Packing StartupVolume to cpio..."
)
add_custom_command(
OUTPUT ${IMG_FILE}
COMMAND dd if=/dev/zero of=${IMG_FILE} bs=1M count=64 status=none COMMAND dd if=/dev/zero of=${IMG_FILE} bs=1M count=64 status=none
COMMAND ${MKFS_EXE} -F 32 ${IMG_FILE} COMMAND ${MKFS_EXE} -F 32 ${IMG_FILE}
COMMAND mmd -i ${IMG_FILE} ::/EFI ::/EFI/BOOT COMMAND mmd -i ${IMG_FILE} ::/EFI ::/EFI/BOOT
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} $<TARGET_FILE:BOOTX64> ::/EFI/BOOT/BOOTX64.EFI COMMAND ${MCOPY_EXE} -i ${IMG_FILE} $<TARGET_FILE:BOOTX64> ::/EFI/BOOT/BOOTX64.EFI
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${CMAKE_BINARY_DIR}/bin/kernel.bin ::/kernel.bin COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${CMAKE_BINARY_DIR}/bin/kernel.bin ::/kernel.bin
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${INITRAMFS_CPIO_FILE} ::/StartupVolume.cpio COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${INITRAMFS_CPIO_FILE} ::/StartupVolume.cpio
DEPENDS BOOTX64 kernel ${INITRAMFS_CPIO_FILE}
VERBATIM
COMMENT "Generating bootable image: ${IMG_FILE}"
)
add_custom_target(image ALL DEPENDS ${IMG_FILE}) WORKING_DIRECTORY ${VOLUME_ROOT}
DEPENDS BOOTX64 kernel ${SYSTEM_SERVICES}
VERBATIM
COMMENT "Packing initramfs and generating bootable image: ${IMG_FILE}"
)
endif() endif()
if(QEMU_EXE) if(QEMU_EXE)
add_custom_target(run add_custom_target(run
COMMAND ${QEMU_EXE} COMMAND ${QEMU_EXE}
-enable-kvm #-enable-kvm
-bios ${OVMF_PATH} $<$<BOOL:${APPLE}>:-machine> $<$<BOOL:${APPLE}>:q35>
$<$<BOOL:${APPLE}>:-drive> $<$<BOOL:${APPLE}>:if=pflash,format=raw,readonly=on,file=${OVMF_PATH}>
$<$<NOT:$<BOOL:${APPLE}>>:-bios> $<$<NOT:$<BOOL:${APPLE}>>:${OVMF_PATH}>
-drive file=${IMG_FILE},format=raw -drive file=${IMG_FILE},format=raw
-vga std -vga std
-net none -net none
+5 -5
View File
@@ -9,14 +9,14 @@
**termOS** is a 64-bit, UNIX-hating, bespoke operating system written from scratch in C. **termOS** is a 64-bit, UNIX-hating, bespoke operating system written from scratch in C.
Current Kernel: **Dewar** (v0.5.x) Current Kernel: **Dewar** (v0.6.x)
## Philosophy ## Philosophy
- **Zero Bloat:** We don't port libraries; we write them. - **Zero Bloat:** We don't port libraries; we write them.
- **Custom Everything:** Why use ELF when you can invent **HOT!**? Why use GRUB when you can write your own bootloader (soon)? - **Custom Everything:** Why use ELF when you can invent **HOT!**? Why use GRUB when you can write your own bootloader?
## Features (v0.5.2) ## Features (v0.6.*)
- **Architecture:** x86_64 / UEFI. - **Architecture:** x86_64 / UEFI.
- **Memory Management:** PMM (Bitmap), VMM (PML4 + Higher Half Direct Map), Kernel Heap. - **Memory Management:** PMM (Bitmap), VMM (PML4 + Higher Half Direct Map), Kernel Heap.
@@ -24,8 +24,8 @@ Current Kernel: **Dewar** (v0.5.x)
- **Isolation:** Ring 0 (Kernel) / Ring 3 (Userspace) protection. - **Isolation:** Ring 0 (Kernel) / Ring 3 (Userspace) protection.
- **Binaries:** Custom **HOT!** executable format (parsed via custom `elf2hot` toolchain). - **Binaries:** Custom **HOT!** executable format (parsed via custom `elf2hot` toolchain).
- **Filesystem:** VFS abstraction with CPIO Initramfs support. - **Filesystem:** VFS abstraction with CPIO Initramfs support.
- **Graphics:** `ShitGUI` (yes, really) linear framebuffer driver. - **Graphics:** linear framebuffer driver.
- **Shell:** `ksh` (Kernel Shell) -> transitioning to userspace `ush` - **Shell:** `termosh`
## 🔥 The HOT! Format ## 🔥 The HOT! Format
+25
View File
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.20)
project(termOSuserspace LANGUAGES C ASM_NASM)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
message(STATUS "Building termOS's userspace")
set(TERMOS_OBJCOPY objcopy)
if(APPLE)
find_program(TERMOS_LD_LLD NAMES ld.lld HINTS /usr/local/bin /opt/homebrew/bin REQUIRED)
find_program(TERMOS_OBJCOPY NAMES llvm-objcopy objcopy HINTS /usr/local/opt/llvm/bin /opt/homebrew/opt/llvm/bin REQUIRED)
set(CMAKE_C_LINK_FLAGS "")
set(CMAKE_ASM_NASM_COMPILE_OBJECT
"<CMAKE_ASM_NASM_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -MD <DEP_FILE> -MT <DEP_TARGET> -f elf64 -o <OBJECT> <SOURCE>")
set(CMAKE_C_LINK_EXECUTABLE
"${TERMOS_LD_LLD} <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
add_subdirectory(libterm)
add_subdirectory(init)
add_subdirectory(rust)
add_subdirectory(debug)
add_subdirectory(termosh)
+6
View File
@@ -0,0 +1,6 @@
#include <termOS.h>
int main() {
ConsolePrint("Test test test \n Meow meow meow \n");
return 0;
}
@@ -19,7 +19,13 @@ set(USER_C_FLAGS
-O2 -O2
) )
set(CMAKE_ASM_NASM_FLAGS "-f elf64") if(APPLE)
list(APPEND USER_C_FLAGS --target=x86_64-none-elf)
endif()
set(USER_C_FLAGS "${USER_C_FLAGS}" PARENT_SCOPE)
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
set(LIBTERM_SOURCES set(LIBTERM_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/OSServices.asm ${CMAKE_CURRENT_SOURCE_DIR}/src/OSServices.asm
@@ -31,12 +37,14 @@ set(LIBTERM_SOURCES
) )
add_library(term STATIC ${LIBTERM_SOURCES}) add_library(term STATIC ${LIBTERM_SOURCES})
set_target_properties(term PROPERTIES NASM_OBJ_FORMAT elf64)
target_compile_options(term PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>) target_compile_options(term PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
target_include_directories(term PUBLIC inc) target_include_directories(term PUBLIC inc)
add_library(RuntimeEntryObject OBJECT src/RuntimeEntry.asm) add_library(RuntimeEntryObject OBJECT src/RuntimeEntry.asm)
set_target_properties(RuntimeEntryObject PROPERTIES NASM_OBJ_FORMAT elf64)
target_compile_options(RuntimeEntryObject PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>) target_compile_options(RuntimeEntryObject PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>)
function(add_termos_executable NAME SOURCES) function(add_termos_executable NAME SOURCES)
@@ -44,7 +52,8 @@ function(add_termos_executable NAME SOURCES)
target_sources(${NAME} PRIVATE $<TARGET_OBJECTS:RuntimeEntryObject>) target_sources(${NAME} PRIVATE $<TARGET_OBJECTS:RuntimeEntryObject>)
target_compile_options(${NAME} PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>) target_compile_options(${NAME} PRIVATE $<$<COMPILE_LANGUAGE:C>:${USER_C_FLAGS}>
-fno-stack-protector) # fixme: what the fuck. ugly this works user_c_flags apparently not
target_link_libraries(${NAME} PRIVATE term) target_link_libraries(${NAME} PRIVATE term)
target_link_options(${NAME} PRIVATE target_link_options(${NAME} PRIVATE
@@ -5,10 +5,13 @@
#include <Types.h> #include <Types.h>
enum { enum {
kConsoleInput = 0,
kConsoleOutput = 1,
kConsoleEOF = -1, kConsoleEOF = -1,
kConsoleDefaultBufferSize = 1024 kConsoleDefaultBufferSize = 1024
}; };
Int32 ConsolePrintString(const char* string);
Int32 ConsolePrint(const char* format, ...); Int32 ConsolePrint(const char* format, ...);
Int32 StringFormat(char* destination, UInt64 size, const char* format, ...); Int32 StringFormat(char* destination, UInt64 size, const char* format, ...);
Int32 ConsoleGetCharacter(); Int32 ConsoleGetCharacter();
@@ -9,7 +9,7 @@ extern UInt64 OSServiceIORead(UInt64 fileDescriptor, void* buffer, UInt64 length
extern UInt64 OSServiceIOWrite(UInt64 fileDescriptor, const void* buffer, UInt64 length); extern UInt64 OSServiceIOWrite(UInt64 fileDescriptor, const void* buffer, UInt64 length);
static void sConsoleWriteCharacter(char character) { static void sConsoleWriteCharacter(char character) {
OSServiceIOWrite(1, &character, 1); OSServiceIOWrite(kConsoleOutput, &character, 1);
} }
static inline void sConsoleBufferAdd(char* string, UInt64 size, UInt64* written, char character) { static inline void sConsoleBufferAdd(char* string, UInt64 size, UInt64* written, char character) {
@@ -105,6 +105,10 @@ Int32 StringFormat(char* destination, usize size, const char* format, ...) {
return returnValue; return returnValue;
} }
Int32 ConsolePrintString(const char* string) {
return OSServiceIOWrite(kConsoleOutput, string, StringGetLength(string));
}
Int32 ConsolePrint(const char *format, ...) { Int32 ConsolePrint(const char *format, ...) {
char buffer[kConsoleDefaultBufferSize]; char buffer[kConsoleDefaultBufferSize];
va_list args; va_list args;
@@ -114,14 +118,14 @@ Int32 ConsolePrint(const char *format, ...) {
va_end(args); va_end(args);
UInt64 writeLength = ((UInt64)length < sizeof(buffer)) ? length : (sizeof(buffer) - 1); UInt64 writeLength = ((UInt64)length < sizeof(buffer)) ? length : (sizeof(buffer) - 1);
OSServiceIOWrite(1, buffer, writeLength); OSServiceIOWrite(kConsoleOutput, buffer, writeLength);
return (int)writeLength; return (int)writeLength;
} }
Int32 ConsoleGetCharacter() { Int32 ConsoleGetCharacter() {
char character; char character;
UInt64 serviceCallResult = OSServiceIORead(0, &character, 1); UInt64 serviceCallResult = OSServiceIORead(kConsoleInput, &character, 1);
if (serviceCallResult <= 0) return kConsoleEOF; if (serviceCallResult <= 0) return kConsoleEOF;
return (int)(unsigned char)character; return (int)(unsigned char)character;
} }
+15
View File
@@ -0,0 +1,15 @@
[env]
RUST_TARGET_PATH = { value = ".", relative = true }
[build]
target = "x86_64-termos"
[unstable]
build-std =["core", "alloc", "compiler_builtins"]
build-std-features = ["compiler-builtins-mem"]
[target.x86_64-termos]
rustflags =[
"-Z", "unstable-options",
"-C", "link-arg=-Tlinker.ld"
]
+33
View File
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.16)
project(rustApps NONE)
function(add_rust_app NAME)
set(RUST_TARGET "x86_64-termos")
set(RUST_TARGET_DIR "${CMAKE_CURRENT_SOURCE_DIR}/target")
set(RUST_ELF_FILE "${RUST_TARGET_DIR}/${RUST_TARGET}/release/${NAME}")
set(STARTUP_VOLUME_DIR "${CMAKE_BINARY_DIR}/StartupVolume/System/CoreServices")
set(FINAL_HOT_PATH "${STARTUP_VOLUME_DIR}/${NAME}")
set(STRIPPED_ELF "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.stripped")
set(ELF2HOT_DIR "${CMAKE_SOURCE_DIR}/tools/elf2hot")
file(MAKE_DIRECTORY "${STARTUP_VOLUME_DIR}")
add_custom_target(${NAME} ALL
COMMAND ${CMAKE_COMMAND} -E env
"CARGO_TARGET_DIR=${RUST_TARGET_DIR}"
cargo build --package ${NAME} --release --target ${RUST_TARGET}
COMMAND ${CMAKE_COMMAND} -E env
"PATH=/usr/local/opt/llvm/bin:/opt/homebrew/opt/llvm/bin:$ENV{PATH}"
llvm-objcopy --strip-all ${RUST_ELF_FILE} ${STRIPPED_ELF}
COMMAND ${CMAKE_COMMAND} -E chdir ${ELF2HOT_DIR} cargo run --release --quiet -- ${STRIPPED_ELF} ${FINAL_HOT_PATH}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Building, stripping and packing ${NAME} to initramfs..."
VERBATIM
)
endfunction()
add_rust_app(rtest)
+50
View File
@@ -0,0 +1,50 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "linked_list_allocator"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b23ac50abb8261cb38c6e2a7192d3302e0836dac1628f6a93b82b4fad185897"
dependencies = [
"spinning_top",
]
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "rtest"
version = "0.1.0"
dependencies = [
"std",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spinning_top"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [
"lock_api",
]
[[package]]
name = "std"
version = "0.1.0"
dependencies = [
"linked_list_allocator",
]
+5
View File
@@ -0,0 +1,5 @@
[workspace]
members = ["std", "apps/rtest"]
[profile.release]
strip = true
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "rtest"
version = "0.1.0"
edition = "2024"
[dependencies]
std = { path = "../../std" }
+4
View File
@@ -0,0 +1,4 @@
fn main() {
let anus = "jopa";
println!("meow");
}
+35
View File
@@ -0,0 +1,35 @@
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
*(COMMON)
}
/DISCARD/ : {
*(.note.gnu.build-id)
*(.note.GNU-stack)
*(.note.gnu.property)
*(.comment)
*(.interp)
*(.dynsym)
*(.dynstr)
*(.hash)
*(.gnu.hash)
}
}
+2
View File
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "std"
version = "0.1.0"
edition = "2024"
[dependencies]
linked_list_allocator = "0.10.6"
+14
View File
@@ -0,0 +1,14 @@
extern crate alloc;
use core::alloc::{GlobalAlloc, Layout};
use linked_list_allocator::LockedHeap;
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub unsafe fn init_heap() {
let heap_size = 1024 * 1024;
let heap_start = crate::syscall::memory_allocate(heap_size);
ALLOCATOR.lock().init(heap_start as *mut u8, heap_size);
}
+30
View File
@@ -0,0 +1,30 @@
use core::fmt::{self, Write};
pub struct Stdout;
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
crate::syscall::io_write(1, s.as_ptr(), s.len());
Ok(())
}
}
#[doc(hidden)]
pub fn _print(args: core::fmt::Arguments) {
let mut stdout = crate::io::Stdout;
let _ = core::fmt::Write::write_fmt(&mut stdout, args);
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::io::_print(core::format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => {
$crate::print!($($arg)*);
$crate::print!("\n");
};
}
+49
View File
@@ -0,0 +1,49 @@
#![no_std]
#![feature(lang_items)]
pub use core::*;
extern crate alloc;
pub use alloc::*;
pub mod allocator;
pub mod io;
pub mod panic;
pub mod syscall;
pub mod prelude {
pub mod rust_2024 {
pub use core::prelude::rust_2024::*;
pub use alloc::string::{String, ToString};
pub use alloc::vec::Vec;
pub use alloc::vec;
pub use alloc::format;
pub use crate::{print, println};
}
}
core::arch::global_asm!(
".global _start",
"_start:",
"and rsp, ~0xF",
"xor rdi, rdi",
"xor rsi, rsi",
"call main",
"mov rdi, rax",
"mov rax, 0",
"syscall"
);
#[lang = "start"]
fn lang_start<T>(
user_main: fn() -> T,
_argc: isize,
_argv: *const *const u8,
_sigpipe: u8,
) -> isize {
unsafe { crate::allocator::init_heap() };
user_main();
crate::syscall::process_exit(0);
}
+9
View File
@@ -0,0 +1,9 @@
use core::panic::PanicInfo;
use crate::println;
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
println!("{}", info);
crate::syscall::process_exit(1);
}
+66
View File
@@ -0,0 +1,66 @@
use core::arch::asm;
pub const SYS_EXIT: usize = 0;
pub const SYS_SPAWN: usize = 1;
pub const SYS_ALLOC: usize = 2;
pub const SYS_WRITE: usize = 3;
pub const SYS_READ: usize = 4;
pub const SYS_WAIT: usize = 5;
#[inline(always)]
unsafe fn syscall1(num: usize, arg1: usize) -> usize {
let ret: usize;
unsafe {
asm!(
"syscall",
inout("rax") num => ret,
in("rdi") arg1,
out("rcx") _,
out("r11") _,
options(nostack, preserves_flags)
);
}
ret
}
#[inline(always)]
unsafe fn syscall3(num: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
let ret: usize;
core::arch::asm!(
"syscall",
in("rax") num,
in("rdi") arg1,
in("rsi") arg2,
in("rdx") arg3,
lateout("rax") ret,
out("rcx") _,
out("r11") _,
options(nostack)
);
ret
}
pub fn process_exit(code: usize) -> ! {
unsafe { syscall1(SYS_EXIT, code) };
loop {}
}
pub fn process_spawn(path: usize) -> usize {
unsafe { syscall1(SYS_SPAWN, path) }
}
pub fn process_wait(pid: usize) -> usize {
unsafe { syscall1(SYS_WAIT, pid) }
}
pub fn memory_allocate(size: usize) -> usize {
unsafe { syscall1(SYS_ALLOC, size) }
}
pub fn io_write(fd: usize, buf: *const u8, len: usize) -> usize {
unsafe { syscall3(SYS_WRITE, fd, buf as usize, len) }
}
pub fn io_read(fd: usize, buf: *const u8, len: usize) -> usize {
unsafe { syscall3(SYS_READ, fd, buf as usize, len) }
}
+15
View File
@@ -0,0 +1,15 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": 64,
"target-c-int-width": 32,
"os": "termos",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"position-independent-executables": true,
"relocation-model": "pic"
}
@@ -11,6 +11,17 @@ endif()
message(STATUS "Dewar kernel: Building for architecture '${ARCH}'") message(STATUS "Dewar kernel: Building for architecture '${ARCH}'")
set(TERMOS_OBJCOPY objcopy)
if(APPLE)
find_program(TERMOS_LD_LLD NAMES ld.lld HINTS /usr/local/bin /opt/homebrew/bin REQUIRED)
find_program(TERMOS_OBJCOPY NAMES llvm-objcopy objcopy HINTS /usr/local/opt/llvm/bin /opt/homebrew/opt/llvm/bin REQUIRED)
set(CMAKE_C_LINK_FLAGS "")
set(CMAKE_ASM_NASM_COMPILE_OBJECT
"<CMAKE_ASM_NASM_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -MD <DEP_FILE> -MT <DEP_TARGET> -f elf64 -o <OBJECT> <SOURCE>")
set(CMAKE_C_LINK_EXECUTABLE
"${TERMOS_LD_LLD} <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS
"src/kmain.c" "src/kmain.c"
@@ -24,13 +35,13 @@ file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS
"src/lib/*.c" "src/lib/*.c"
"src/IO/*.c" "src/IO/*.c"
"src/VM/*.c" "src/VM/*.c"
"src/KSH/*.c"
"src/FS/*.c" "src/FS/*.c"
"Data/*.c" "Data/*.c"
) )
add_executable(kernel ${KERNEL_SOURCES}) add_executable(kernel ${KERNEL_SOURCES})
set_target_properties(kernel PROPERTIES NASM_OBJ_FORMAT elf64)
target_include_directories(kernel PRIVATE target_include_directories(kernel PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../common" "${CMAKE_CURRENT_SOURCE_DIR}/../common"
@@ -41,6 +52,7 @@ target_include_directories(kernel PRIVATE
target_compile_options(kernel PRIVATE target_compile_options(kernel PRIVATE
$<$<COMPILE_LANGUAGE:C>: $<$<COMPILE_LANGUAGE:C>:
$<$<BOOL:${APPLE}>:--target=x86_64-none-elf>
-ffreestanding -ffreestanding
-mno-red-zone -mno-red-zone
-fno-stack-protector -fno-stack-protector
@@ -48,7 +60,9 @@ target_compile_options(kernel PRIVATE
-Wall -Wextra -Wall -Wextra
-mcmodel=kernel -mcmodel=kernel
-g -g
-mno-sse -mno-sse2 -msoft-float
> >
$<$<AND:$<BOOL:${APPLE}>,$<COMPILE_LANGUAGE:ASM>>:--target=x86_64-none-elf>
) )
target_link_options(kernel PRIVATE target_link_options(kernel PRIVATE
@@ -65,6 +79,8 @@ set_target_properties(kernel PROPERTIES
) )
add_custom_command(TARGET kernel POST_BUILD add_custom_command(TARGET kernel POST_BUILD
COMMAND objcopy -O binary $<TARGET_FILE:kernel> $<TARGET_FILE_DIR:kernel>/kernel.bin COMMAND ${CMAKE_COMMAND} -E env
"PATH=/usr/local/opt/llvm/bin:/opt/homebrew/opt/llvm/bin:$ENV{PATH}"
llvm-objcopy -O binary $<TARGET_FILE:kernel> $<TARGET_FILE_DIR:kernel>/kernel.bin
COMMENT "Generating raw binary kernel.bin..." COMMENT "Generating raw binary kernel.bin..."
) )
@@ -6,4 +6,4 @@
#include <types.h> #include <types.h>
Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName); Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName);
void init_task_entry(); void initTask();
@@ -37,6 +37,7 @@
void VMVirtualMemoryInitialize(Bootinfo* info); void VMVirtualMemoryInitialize(Bootinfo* info);
UInt64* VMVirtualMemoryMapPage(UInt64* PML4, UInt64 physical, UInt64 virtual, UInt64 flags); UInt64* VMVirtualMemoryMapPage(UInt64* PML4, UInt64 physical, UInt64 virtual, UInt64 flags);
void* VMVirtualMemoryGetOrAllocatePage(UInt64* PML4, UInt64 virtual, UInt64 flags);
UInt64 VMVirtualMemoryCreateAddressSpace(); UInt64 VMVirtualMemoryCreateAddressSpace();
UInt64 VMGetCurrentCR3(); UInt64 VMGetCurrentCR3();
void VMLoadCR3(UInt64 PML4Address); void VMLoadCR3(UInt64 PML4Address);
@@ -11,3 +11,4 @@ Int32 StringCompareWithLimit(const char* firstString, const char* secondString,
char* StringCopy(char* destination, const char* source); char* StringCopy(char* destination, const char* source);
char* StringCopyWithLimit(char* destination, const char* source, UInt64 limit); char* StringCopyWithLimit(char* destination, const char* source, UInt64 limit);
UInt64 StringGetLength(const char* string); UInt64 StringGetLength(const char* string);
const char* StringFindLastOccurrenceOfCharacter(const char* string, char separator);

Some files were not shown because too many files have changed in this diff Show More