Giter Club home page Giter Club logo

templeos-loader's Introduction

TempleOS user-space loader

How is this useful?

templeos-loader allows you to use your Linux system for some tasks that previously required running full TempleOS on hardware or in a VM:

  • compiling the kernel, compiler, or a whole distribution ISO
  • running non-interactive HolyC programs (file processing, network services)

However, the primary goal is not "to bring HolyC to Linux". The TempleOS programming environment is heavily graphics-based, and too unique to blend in with anything else. Therefore, in the long run, we would like to reproduce the complete, authentic TempleOS experience, in Linux user-space, without a clunky VM.

Building prerequisites

glibc definitely does not appreciate the way we handle memory. For this reason, to avoid crashing, you must use a libc that is more "accomodating", such as musl. CMake 3.13 and the Python3 dataclasses module are also required.

Build musl libc

git clone git://git.musl-libc.org/musl musl-src
cd musl-src
./configure --prefix=$PWD/../build/musl --disable-shared
make install
cd ..
export PATH=$PWD/build/musl/bin:$PATH

Build PhysFS

git submodule update --init --recursive
cd physfslt-3.0.2
env CC=musl-gcc cmake -DCMAKE_INSTALL_PREFIX:PATH=$PWD/../build/physfs -DPHYSFS_BUILD_SHARED=OFF -DPHYSFS_BUILD_TEST=OFF . && make install
cd ..

Build TempleOS On Linux ("static mode", recommended)

mkdir cmake-build-debug
cd cmake-build-debug
env CC=musl-gcc PHYSFSDIR=$PWD/../build/physfs/ cmake ..
cmake --build . --target templeoskernel
cd ..

Run

# Example: compile the HolyC runtime
mkdir -p CmpOutput

env STARTOS=D:/HolyCRT/CmpHolyCRT.HC \
    ./cmake-build-debug/templeoskernel \
    --drive=C,MiniSystem \
    --drive=D,.,CmpOutput

Building a TempleOS ISO from source

# check out the TempleOS source tree
git clone https://github.com/cia-foundation/TempleOS.git
cd TempleOS

# bootstrap the necessary programs
mkdir -p User/Kernel
cp $LOADER_DIR/examples/StartDoDistro.HC User/

# build it!
env STARTOS=StartDoDistro $LOADER_DIR/cmake-build-debug/templeos --drive=C,.,User

# look at the result
ls -l User/Tmp/MyDistro.ISO.C

Build TempleOS Loader For Linux ("dynamic mode")

mkdir cmake-build-debug
cd cmake-build-debug
env CC=musl-gcc PHYSFSDIR=$PWD/../build/physfs/ cmake ..
cmake --build . --target templeos-loader
cd ..

Environment variables

loader is actually agnostic to these, but for now we document them here:

  • COMPILER (default Compiler) - compiler binary path relative to /Compiler/ (relevant only in dynamic mode)
  • STARTOS (default StartOS) - StartOS.HC path relative to /

Note that these files must be accessible through one of the virtualized drives!

Other tips

  • To not break into GDB every time a SEGV is trapped (e.g. when encountering an unpatched CLI instruction), use the GDB command handle SIGSEGV nostop

TODO

  • bug: PhysFS will not create necessary directories that exist in RO but not in RW overlay!!
  • implement fopen, fread, fwrite as syscalls
  • basedir() call is questionable
  • Clean up syscalls

Design details

To be covered in a series of blog posts.

Calling conventions

See https://www.jwhitham.org/2015/07/redirecting-system-calls-from-c-library.html

TempleOS calling convention: RAX function()

SysV ABI: EAX function(RDI, RSI, RDX, RCX, R8, R9)

Goal: keep VKernel Host ABI-agnostic

templeos-loader's People

Contributors

minexew avatar tos11 avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

templeos-loader's Issues

Investigate possibility to run directly in host kernel

The loader could then provide a sane interface for TOS to access hardware (input, block devices, video, network, USB). You would still have the full TempleOS environment with a high degree of compatibility, except you don't need to care about x86 quirks anymore, and you get hardware support "for free".

Best of both worlds?

Note: host kernel doesn't necessarily have to be Linux, could probably be also BSD. However Linux is, in my understanding, more self-contained, so it should be easier to do.

Linking VKernel into the loader

I don't know why I hadn't realized this sooner. The kernel BIN file can be quite easily converted to an ELF object and appropriate thunks automatically generated to translate between calling conventions!

Since in the TOS calling convention arguments go on the stack, but the callee has to clean them up, the converter will need to be aware of function prototypes, or at least the number of arguments. Slightly annoying, but solvable (pycparser + .h file ?)

In the other direction, well, we really only care about KMain, so we can even hard-code the number of arguments there (at least for now; maybe simulating interrupts by host->guest calls will be useful for interactive mode).

With all of this done, you take the resultant object + thunks and statically link it with the rest of the loader. Another advantage? VKernel can directly import host native functions like time and socket. (Though this doesn't translate so easily to JIT programs.)

In rare occasions, the kernel imports symbols that it itself exports -- the GNU linker might or might not appreciate this. Easy, the converter can just pre-link these. A bit more inconvenient is the fact that the kernel's imports are only fully resolved after the compiler is loaded quite late in the boot process. At that point, the kernel would scan its own binary header and apply the necessary patching. In our case the binary header would be gone, so this would require some adjustments in KLoad.HC / LoadKernel. Alternatively, โ€“ call me crazy โ€“ we convert the compiler in the exact same way, and link it statically as well.

The VKernel hardcodes its load address in a few places right now, but in general, it's supposed to be fully relocatable.

Opinions?

Changing COMPILER env var can leave compiler in a broken state due to incorrect header files.

This issue will only effect people trying to modify the TOS compiler API.

Setting the COMPILER env variable only effects the AOT compiled BIN file loaded in HolyCRT/InitRuntime.HC, but does not currently change the header files loaded in MiniSystem/AdamInit.HC. If changes are made to the compiler's API which changes CompilerA.HH or CompilerB.HH, then the new header files need to be loaded instead of those included with the initial default MiniSystem.

Maybe instead of having the COMPILER env variable point to a BIN file, it should point to a directory in which we expect to find Compiler.BIN, CompilerA.HH, and CompilerB.HH as well as any other files the compiler requires (ex: OpCodes.DD)?

Segmentation fault when I try to build Shrine

Hi I try to build templeos-loader by Readme.md. It's ok, but when i start to build ShrineOS program has segmentation fault. I done strace that see attach

Ubuntu 22.04
gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)

out.txt

COMPILER and STARTOS paths should be with respect to *host* file system

Currently these paths are specified with respect to VFS. This is quite confusing (since on the command line, kernel path is specified with regards to the host file system)

The compiler binary and StartOS are loaded through FileRead, and without modifying the compiler we cannot change this (at least for StartOS). Therefore we might have to generate some sort of magical path (e.g. "$COMPILER.BIN") that will be returned to VKernel from HostGetEnv("COMPILER") and later recognized by vsyscall_handler(VSYSCALL_FGET) invoked from HostFsFileRead, which will bypass VFS entirely and use native fopen() to read the file.

Fortunately, this hack does not need to include CFile functions.

Command-line parsing

Should look something like:
templeos-loader --drive=C,.,Writable --drive=D,SomethingElse -m 512 MyKernel.BIN

COMPILER and STARTOS can be still passed through env vars, since the loader is mostly agnostic to them (except for the issue outlined in #6)

UEFI application to run bare metal on modern hardware.

This would be a very long term goal. If this thing evolves far enough to provide a reasonable "TempleOS like experience" it would be good if someone with appropriate experience would try to turn this into a UEFI application so we can run something like TempleOS bare metal on pretty much any modern system.

Capturing output in DolDoc context

Running DoDistro requires being in a DolDoc context with Raw(OFF). The consequence of this is that when building a distro, after ERROR: Timer Cal Error we get no further output.

Investigate, how to capture, filter, and display Print-ed output in a DolDoc context.

Video output

Plan:

  • 3 modes:
    • Non-interactive / Batch / Stream
    • Interactive Text Mode (curses)
    • Interactive Graphical Mode
      • probably can't use SDL directly in-process
      • built-in VNC server like qemu?

Implementing date & time calls

  • Determine datetime format to use in host-guest interface (probably whatever TOS uses internally)
  • Add HostGetLocalTime call
  • Implement stubbed NowDateTimeStruct() in kernel
  • Add timestamp to CHostFsStat, propagate through HostFs* functions to CDirEntry

File + I/O APIs

Long-term plan:

VSYSCALL_STAT -> HostStat
VSYSCALL_STATCLUS -> HostStatByClus (this is a stupid API that adds a lot of pain, but the assumption of having physical clusters is rooted too deep in the kernel)
VSYSCALL_MKDIR, OPENDIR, READDIR, CLOSEDIR -> HostMkdir, Opendir, Readdir, Closedir

add HostFopen
add HostFread
add HostFwrite
add HostFclose

VSYSCALL_FGET -> HostGetFileContents or remove altogether (reimplement through Fread)
VSYSCALL_FPUT -> HostPutFileContents or remove altogether (reimplement through Fwrite)

DirNew on HostFs drive

DirNew, not to be confused with DirMk, initializes a directory entry for a file to be written (such as when opening a CFile)

In HolyCRT, the code is patched out for HostFS case, but DirNew is also being called by TouchFile in Adam. For now, we can stub it out, but some investigation should be done how to best implement or emulate its semantics.

Slimming down StartOS scripts

See examples/StartDoDistro.HC and determine how much of the cruft can be removed.
Document the purpose of everything that needs to remain, and if there is a lot of it, look for ways to make it unnecessary through changes in VKernel or the loader.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.