# kush
This is yet another hobby OS, but this one doesn't try to be yet another UNIX clone. In fact, I really have no idea what it's trying to be. It just kind of… is.

Current features include:

- A relatively compact microkernel-ish kernel; it's mostly preemptive and has a multi-level feedback queue scheduler and supports routing interrupts to userspace.
- Fully featured C library (including support for C11 multithreading), as well as a port of [libc++](https://libcxx.llvm.org) for full C++ support in userspace.
- Painless remote procedure calls via autogenerated RPC stubs
- Dynamic loader with support for shared libraries
- Support for parsing ACPI tables on amd64 via [ACPICA](https://www.acpica.org)
- In memory device tree type representation of hardware, used for automatic driver loading
- Drivers in userspace for a variety of hardware, including PCI Express, AHCI, filesystems, legacy PS/2 keyboard and mouse

## Building
We use CMake to build everything. The single `CMakeLists.txt` in this directory can build the kernel, all userspace components, and tools automatically. You will have to select one of the toolchains to use and pass it to CMake in the `CMAKE_TOOLCHAIN_FILE` flag.

### Directory structure
- kernel: Kernel source files, including architecture/platform specific stuff
    - arch: Architecture initialization, exceptions, interrupts, syscalls
    - platform: Booting and entry point, timers
- user: All userspace code
    - libs: Libraries that get put in the userspace image
        - external: Third party libraries (most go in /usr/lib)
        - libsystem: System call wrapper
        - libc: C library
- tools: Host side utilities
- sysroot: Base directory of the OS root directory. Automatically built up as kernel/userspace is built.
- toolchain: Created by the `build_toolchain.sh` script.

The `toolchain.diff` file contains a patch that should be applied against the checked-out LLVM source to build the toolchain required to build the kernel and userland.

### Build Dependencies
Besides cmake and the custom LLVM toolchain, the host machine needs to have the [Cap'n Proto](http://capnproto.org) library and tools installed such that the protocol files for RPC services can be built correctly if they're updated. However, the current versions of generated sources are included in the repository.

## LLVM Toolchain
You can use the `build_toolchain.sh` script to build a toolchain to use for compiling the system. This sets up most of the libraries required: you'll also have to build a few supporting libraries.

Before compiling the libraries below, you will likely need to compile and install the C library into the sysroot; these libraries expect to find certain headers there. Replace the compiler target string as necessary for the current target/platform.

### compiler-rt
This contains helper functions and other stuff the compiler will rely on being present in all non-freestanding libraries. By default, the script doesn't seem to compile the compiler-rt for our platform. 

To build it, execute the following from inside the toolchain's sources folder:

```
cd llvm-project
mkdir build-compiler-rt
cd build-compiler-rt
cmake ../compiler-rt -DLLVM_CONFIG_PATH=../../../llvm/bin/llvm-config -DCMAKE_C_COMPILER_TARGET="i386-pc-kush-elf" -DCMAKE_ASM_COMPILER_TARGET="i386-pc-kush-elf" -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DCMAKE_TOOLCHAIN_FILE=~/kush/cmake/toolchain-i386-clang.cmake -Wno-dev -DCMAKE_SIZEOF_VOID_P=4 -DCOMPILER_RT_BAREMETAL_BUILD=ON
make -j40
mkdir -p ../../../llvm/lib/clang/12.0.0/lib/kush 
cp lib/i386-kush/libclang_rt.builtins-i386.a ../../../llvm/lib/clang/12.0.0/lib/kush
```

### libcxxabi and libcxx
libcxxabi provides the lower level portable layer for the C++ runtime library. Build it like so:

```
cd llvm-project
mkdir build-libcxxabi
cd build-libcxxabi
cmake ../libcxxabi -DCMAKE_TOOLCHAIN_FILE=~/kush/cmake/toolchain-i386-clang.cmake -DLIBCXX_TARGET_TRIPLE="i386-pc-kush-elf"  -DLIBCXXABI_INSTALL_PREFIX=/Users/tristan/kush/sysroot/ -Wno-dev -DLIBCXXABI_ENABLE_THREADS=OFF
make install -j40
```

Once built, you have to build the libcxx, the actual C++ runtime:

```
cd llvm-project
mkdir build-libcxx
cd build-libcxx
cmake ../libcxx -DCMAKE_TOOLCHAIN_FILE=~/kush/cmake/toolchain-i386-clang.cmake -DLLVM_CONFIG_PATH=../../../llvm/bin/llvm-config -DLIBCXX_TARGET_TRIPLE="i386-pc-kush-elf" -DLIBCXX_INSTALL_PREFIX=/Users/tristan/kush/sysroot/ -DLIBCXX_INSTALL_HEADER_PREFIX=/Users/tristan/kush/sysroot/usr/ -DLIBCXX_CXX_ABI=libcxxabi -DLIBCXX_ENABLE_STDIN=OFF -DLIBCXX_ENABLE_RANDOM_DEVICE=OFF -DLIBCXX_ENABLE_FILESYSTEM=OFF  -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF -D_LIBCPP_HAS_THREAD_API_EXTERNAL=ON
make install -j40
```

Most of the flags set to OFF will eventually be removed, when the C libraries and the system itself implements the requisite features.

### libunwind
Required for stack backtraces and C++ exception support. 


```
cd llvm-project
mkdir build-libunwind
cd build-libunwind
cmake ../libunwind -DCMAKE_TOOLCHAIN_FILE=~/kush/cmake/toolchain-i386-clang.cmake -DLLVM_CONFIG_PATH=../../../llvm/bin/llvm-config -DLIBUNWIND_TARGET_TRIPLE="i386-pc-kush-elf" -DLIBUNWIND_INSTALL_PREFIX=/Users/tristan/kush/sysroot/ -DLIBUNWIND_USE_COMPILER_RT=ON -DLIBUNWIND_ENABLE_THREADS=OFF
make install -j40
```

We can enable `LIBUNWIND_ENABLE_THREADS` when we've got a pthreads compatibility layer.

## Documentation
There's not a whole lot of documentation about the project as of yet.

Some blog posts describing the OS design and motivations are [available here.](https://blraaz.me/archive.html?tag=kush-os)
