From f0ec001801e01e75885e6d0677440e2816b05385 Mon Sep 17 00:00:00 2001
From: xwashere <xwashere0@protonmail.com>
Date: Sat, 16 Mar 2024 20:14:21 -0400
Subject: [PATCH] add a lot of stuff uh i got a bit to excited

---
 CMakeLists.txt                                |  13 +-
 README                                        |   6 +
 executive/CMakeLists.txt                      |  11 +
 executive/src/bugcheck.cxx                    |  21 ++
 executive/src/bugcheck.hxx                    |   3 +
 executive/src/logging.cxx                     |   4 +
 executive/src/logging.hxx                     | 132 ++++++++++++
 executive/src/main.cxx                        |  16 ++
 executive/src/metaprogramming.hxx             |  51 +++++
 executive/src/syscall.cxx                     |   2 +
 executive/src/syscall.hxx                     |  90 +++++++++
 lcrash/CMakeLists.txt                         |  17 ++
 lcrash/lcrash.c                               | 129 ++++++++++++
 lcrash/lcrash.ld                              |  26 +++
 lcrash/lnxboot.h                              | 156 +++++++++++++++
 lrss/CMakeLists.txt                           |   4 +-
 .../include/lindows/lrss.h                    |   0
 lrss/{lib => liblrssclient/src}/library.cxx   |   0
 scripts/hivex/system.hivex                    |  24 +++
 scripts/mkhive                                | 188 ++++++++++++++++++
 src/grub/grub.cfg                             |   2 +-
 src/linux/config                              |  14 +-
 22 files changed, 900 insertions(+), 9 deletions(-)
 create mode 100644 executive/CMakeLists.txt
 create mode 100644 executive/src/bugcheck.cxx
 create mode 100644 executive/src/bugcheck.hxx
 create mode 100644 executive/src/logging.cxx
 create mode 100644 executive/src/logging.hxx
 create mode 100644 executive/src/main.cxx
 create mode 100644 executive/src/metaprogramming.hxx
 create mode 100644 executive/src/syscall.cxx
 create mode 100644 executive/src/syscall.hxx
 create mode 100644 lcrash/CMakeLists.txt
 create mode 100644 lcrash/lcrash.c
 create mode 100644 lcrash/lcrash.ld
 create mode 100644 lcrash/lnxboot.h
 rename lrss/{ => liblrssclient}/include/lindows/lrss.h (100%)
 rename lrss/{lib => liblrssclient/src}/library.cxx (100%)
 create mode 100644 scripts/hivex/system.hivex
 create mode 100755 scripts/mkhive

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 586381b..227bd4b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -323,6 +323,7 @@ add_custom_command(OUTPUT lindows_c.img
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/LNXConfig
+	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/Config
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB/x86_64-efi
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS 'lindows_c/Windows/Temporary Files'
@@ -351,7 +352,13 @@ add_custom_command(OUTPUT lindows_c.img
 	COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lsmss>      lindows_c/Windows/System32/lsmss.exe
 	COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lrss>       lindows_c/Windows/System32/lrss.exe
 	COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lrssclient> lindows_c/Windows/System32/liblrssclient.so
-	
+	COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lexecutive> lindows_c/Windows/System32/lexecutive.exe
+	COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $<TARGET_FILE:lcrash>     lindows_c/Windows/System32/lcrash.exe
+
+	# create registry hives
+	COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mkhive lindows_c/Windows/System32/Config/System
+	COMMAND hivexsh lindows_c/Windows/System32/Config/System -w -f ${CMAKE_CURRENT_SOURCE_DIR}/scripts/hivex/system.hivex
+
 	# create users folder
 	COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
 
@@ -359,6 +366,7 @@ add_custom_command(OUTPUT lindows_c.img
 	COMMAND "umount" ARGS lindows_c
 
 	DEPENDS 
+		lexecutive lcrash
 		lsmss lrss lrssclient
 		Linux-install
 		GLibC-install
@@ -368,6 +376,7 @@ add_custom_command(OUTPUT lindows_c.img
 		src/grub/grub.cfg
 		src/glibc/ld.so.conf
 		scripts/copylib
+		scripts/mkhive scripts/hivex/system.hivex
 )
 
 # this makes the efi system partition
@@ -426,5 +435,7 @@ add_custom_command(OUTPUT lindows.img
 
 add_custom_target(lindows ALL DEPENDS lindows.img)
 
+add_subdirectory(executive)
 add_subdirectory(lsmss)
 add_subdirectory(lrss)
+add_subdirectory(lcrash)
diff --git a/README b/README
index e35a797..0300269 100644
--- a/README
+++ b/README
@@ -1,7 +1,13 @@
 == NAMING ==
 
+Mph: Metaprogramming helpers
+Lnx: Linux interaction
 Pii: Preinit internal core routines
 Lrc: Lindows Registry client
 
 == SUBSYSTEM IPC ==
 When a subsystem starts, LSMSS will wait for it to send a SIGSTOP to itself, afterwards, it will send a continue signal then keep going.
+
+== TODO ==
+[ ] we need a program that mimics the tasks preformed by the nt executive to manage the object tree, lindows subsystems and core applications will use the object tree directly, linux applications will be chrooted into the drive they're running on, unaware of the objtree and windows applications will use the appropriate win32 apis and for the most part will not interact with the objtree directly. various subsystems will manage their parts of the object tree, think sysfs but in userspace
+[ ] driver that causes random kernel panics when an xbox controller is connected
diff --git a/executive/CMakeLists.txt b/executive/CMakeLists.txt
new file mode 100644
index 0000000..652cfec
--- /dev/null
+++ b/executive/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.28)
+
+lw_project(executive
+	DESCRIPTION "Lindows Userspace Executive"
+	TARGET      LINDOWS
+)
+
+lw_add_executable(lexecutive
+	SOURCES src/main.cxx src/syscall.cxx src/logging.cxx src/bugcheck.cxx
+)
+target_link_options(lexecutive PRIVATE -static -nostdlib)
diff --git a/executive/src/bugcheck.cxx b/executive/src/bugcheck.cxx
new file mode 100644
index 0000000..e835c2f
--- /dev/null
+++ b/executive/src/bugcheck.cxx
@@ -0,0 +1,21 @@
+#include "bugcheck.hxx"
+#include "syscall.hxx"
+#include "logging.hxx"
+
+void InitializeBugCheckHandler() {
+	int LnxError = 0;
+	
+	// Get file descriptor for crashkernel
+	int CrashKernel = LnxSystemCall(LnxSystemOp::OPEN, "/Windows/System32/lcrash.exe", 0, 4);
+	ExecutiveLog("Crashkernel fd: {}", CrashKernel);
+
+	if ((LnxError = LnxSystemCall(
+		LnxSystemOp::KEXEC_FILE_LOAD,
+		CrashKernel, 0,
+	       	0, "", // no cmdline
+		6 // crash + no initramfs
+	)) < 0) {
+		ExecutiveLog("Failed to load bugcheck kernel, bad things might happen! (errno {})", -LnxError);
+		return;
+	}
+}
diff --git a/executive/src/bugcheck.hxx b/executive/src/bugcheck.hxx
new file mode 100644
index 0000000..46e1e4f
--- /dev/null
+++ b/executive/src/bugcheck.hxx
@@ -0,0 +1,3 @@
+#pragma once
+
+void InitializeBugCheckHandler();
diff --git a/executive/src/logging.cxx b/executive/src/logging.cxx
new file mode 100644
index 0000000..cf382fe
--- /dev/null
+++ b/executive/src/logging.cxx
@@ -0,0 +1,4 @@
+#include "logging.hxx"
+
+char ExecutiveLogStringBuffer[4096] = {};
+char ExecutiveLogFormatOptions[128] = {};
diff --git a/executive/src/logging.hxx b/executive/src/logging.hxx
new file mode 100644
index 0000000..ef7fac2
--- /dev/null
+++ b/executive/src/logging.hxx
@@ -0,0 +1,132 @@
+#pragma once
+
+#include "syscall.hxx"
+
+extern char ExecutiveLogStringBuffer[4096];
+
+/**
+ * Write formatted data to the executive log buffer with ExecutiveLogFormatOptions
+ *
+ * \param Value     Value to format
+ * \param BufferPos Position in ExecutiveLogStringBuffer
+ * \param Args      Specification
+ */
+template<class _Type>
+inline void ExecutiveLogFormatValue(const _Type* Value, int& BufferPos, const char* Args) = delete;
+
+/**
+ * Type has a format function
+ */
+template<class _Type>
+concept ExecutiveLogCanFormat = requires(const _Type* Value, int& BufferPos, const char* Args) {
+	ExecutiveLogFormatValue(Value, BufferPos, Args);
+};
+
+
+/**
+ * Log something.
+ *
+ * Format strings use \{\} for substitutions, substitutions can contain a number that
+ * updates the substitution index and a 127 byte format specification for formatters
+ */
+template<ExecutiveLogCanFormat... _Type>
+inline void ExecutiveLog(const char* Format, const _Type&... Items) {
+	// Format items and other goodies
+	const void* FormatItems[sizeof...(_Type)] = { &Items... };
+	void (*FormatFunctions[sizeof...(_Type)])(const void*, int&, const char*) = {
+		// !!! VERY UNSAFE STUPID DUMB PIECE OF SHIT HACK !!!
+		reinterpret_cast<void (*)(const void*, int&, const char*)>(static_cast<void (*)(const _Type*, int&, const char*)>(ExecutiveLogFormatValue))...
+	};
+	
+	// Buffer for format spec
+	char FormatOptions[128] = {};
+	
+	// Indicies
+	int bpos = 0;
+	int fpos = 0;
+	int apos = 0;
+	
+	// Fill out the log buffer
+	while (Format[fpos] != 0 && bpos < 4095) {
+		// Handle replacements
+		if (Format[fpos] == '{') {
+			// Clear format options
+			FormatOptions[0] = 0;
+
+			// Pattern matching cant come soon enough
+			switch (Format[++fpos]) {
+				case 0: { // Me when the uh i uh
+					LnxWrite(1, "BAD FORMAT STRING: ", 19);
+					LnxWrite(1, Format, fpos);
+					LnxWrite(1, "\n", 1);
+					return;
+				}
+				case '{': { // Escape
+					ExecutiveLogStringBuffer[bpos++] = '{';
+					fpos += 1;
+					break;
+				}
+				case '0':
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9': {
+					volatile auto a = *(char*)(nullptr);
+				}
+				case ':':
+				default: {
+					volatile auto a = *(char*)(nullptr);
+				}
+				case '}': { // Finish the thing
+					fpos += 1;
+					// TODO: unsafe
+					FormatFunctions[apos](FormatItems[apos], bpos, FormatOptions);
+					apos += 1;
+				}
+			}
+		} else {
+			ExecutiveLogStringBuffer[bpos++] = Format[fpos++];
+		}
+	}
+
+	// Add our newline.
+	ExecutiveLogStringBuffer[bpos++] = '\n';
+
+	// Write to stdout.
+	LnxWrite(1, ExecutiveLogStringBuffer, bpos);
+}
+
+// Formatters for builtin types
+template<>
+inline void ExecutiveLogFormatValue<long>(const long* Value, int& BufferPos, const char* Args) {
+	// We only work with absolutes here.
+	long Absolute = *Value < 0 ? -*Value : *Value;
+	
+	// Find the biggest thing i dont fucking know i hate code comments
+	long TheBiggest = 1;
+	while (TheBiggest <= Absolute) TheBiggest *= 10;
+
+	// Sign
+	if (*Value < 0 && BufferPos < 4095) ExecutiveLogStringBuffer[BufferPos++] = '-';
+
+	// The number
+	while (Absolute != 0 && BufferPos < 4095) {
+		ExecutiveLogStringBuffer[BufferPos++] = '0' + static_cast<char>(Absolute * 10 / TheBiggest);
+		Absolute %= TheBiggest / 10;
+		TheBiggest /= 10;
+	}
+
+	return;
+}
+
+template<>
+inline void ExecutiveLogFormatValue<int>(const int* Value, int& BufferPos, const char* Args) {
+	long LongValue = *Value;
+	ExecutiveLogFormatValue(&LongValue, BufferPos, Args);
+	return;
+}
diff --git a/executive/src/main.cxx b/executive/src/main.cxx
new file mode 100644
index 0000000..0d73457
--- /dev/null
+++ b/executive/src/main.cxx
@@ -0,0 +1,16 @@
+#include "./syscall.hxx"
+#include "./logging.hxx"
+#include "./bugcheck.hxx"
+
+/**
+ * We don't have libc as we're running below the rest of the userspace, we can't use the dynamic linker to load it as we run outside of the SystemRoot chroot.
+ * If we need something, we will need to implement it ourselves.
+ */
+extern "C" void _start() {
+	ExecutiveLog("Lindows OS Executive started");
+
+	ExecutiveLog("Loading bugcheck kernel");
+	InitializeBugCheckHandler();
+
+	LnxExitProcess(42);
+}
diff --git a/executive/src/metaprogramming.hxx b/executive/src/metaprogramming.hxx
new file mode 100644
index 0000000..90a4cb2
--- /dev/null
+++ b/executive/src/metaprogramming.hxx
@@ -0,0 +1,51 @@
+#pragma once
+
+// reimplementation of std::integral_constant
+template<class _Type, _Type _Value>
+struct MphIntegralConstant {
+	using value_type = _Type;
+	using type = MphIntegralConstant;
+	
+	static constexpr _Type value = _Value;
+
+	constexpr operator value_type() const noexcept { return value; }
+	constexpr value_type operator()() const noexcept { return value; }
+};
+
+// reimplementation of std::true_type and std::false_type
+using MphTrueType  = MphIntegralConstant<bool, true>;
+using MphFalseType = MphIntegralConstant<bool, false>;
+
+// reimplementation of std::is_same
+template<class _Type1, class _Type2>
+struct MphIsSame : MphFalseType {};
+
+template<class _Type>
+struct MphIsSame<_Type, _Type> : MphTrueType {};
+
+// reimplementation of std::same_as
+template<class _Type1, class _Type2>
+concept MphSameAs = MphIsSame<_Type1, _Type2>::value
+                 && MphIsSame<_Type2, _Type1>::value;
+
+// reimplementation of std::is_pointer
+template<class _Type>
+struct MphIsPointer : MphFalseType {};
+
+template<class _Type>
+struct MphIsPointer<_Type*> : MphTrueType {};
+
+template<class _Type>
+struct MphIsPointer<_Type* const> : MphTrueType {};
+
+template<class _Type>
+struct MphIsPointer<_Type* volatile> : MphTrueType {};
+
+template<class _Type>
+struct MphIsPointer<_Type* const volatile> : MphTrueType {};
+
+// checks if something can be static casted to something else
+template<class _From, class _To>
+concept MphStaticCastableTo = requires(_From&& val) {
+	static_cast<_To>(val);
+};
diff --git a/executive/src/syscall.cxx b/executive/src/syscall.cxx
new file mode 100644
index 0000000..ebaf26b
--- /dev/null
+++ b/executive/src/syscall.cxx
@@ -0,0 +1,2 @@
+#include "./syscall.hxx"
+
diff --git a/executive/src/syscall.hxx b/executive/src/syscall.hxx
new file mode 100644
index 0000000..75ab551
--- /dev/null
+++ b/executive/src/syscall.hxx
@@ -0,0 +1,90 @@
+/**
+ * Wrappers for various syscalls.
+ *
+ * WARNING: This file contains code that is known to the State of California to cause birth defects or reproductive harm
+ */
+
+#pragma once
+
+#include "./metaprogramming.hxx"
+
+enum class LnxSystemOp : long {
+	READ  = 0,
+	WRITE = 1,
+	OPEN  = 2,
+	CLOSE = 3,
+	
+	EXIT = 60,
+
+	KEXEC_FILE_LOAD = 320
+};
+
+template<class _Type>
+concept LnxSystemCallArgumentType = MphStaticCastableTo<_Type, long> || MphIsPointer<_Type>::value;
+
+/**
+ * Cast something to a long for a syscall
+ *
+ * \internal
+ */
+template<class _Type>
+inline long LnxSystemCallCast(_Type arg) {
+	if constexpr (MphIsPointer<decltype(arg)>::value) {
+		return reinterpret_cast<long>(arg);
+	} else {
+		return static_cast<long>(arg);
+	}
+}
+
+/**
+ * Do a system call with only long arguments. This probably isn't memory safe.
+ *
+ * \internal
+ */
+template<MphSameAs<long>... _ArgTypes>
+[[using gnu: naked]]
+inline int LnxSystemCallInternal(long op, _ArgTypes... args) noexcept {
+	// Move arguments to where they belong
+	                                    asm volatile ("mov %%rdi, %%rax" : : : "rax");
+	if constexpr (sizeof...(args) >= 1) asm volatile ("mov %%rsi, %%rdi" : : : "rdi");
+	if constexpr (sizeof...(args) >= 2) asm volatile ("mov %%rdx, %%rsi" : : : "rsi");
+	if constexpr (sizeof...(args) >= 3) asm volatile ("mov %%rcx, %%rdx" : : : "rdx");
+	if constexpr (sizeof...(args) >= 4) asm volatile ("mov %%r8,  %%r10" : : : "r10");
+	if constexpr (sizeof...(args) >= 5) asm volatile ("mov %%r9,  %%r8"  : : : "r8" );
+	if constexpr (sizeof...(args) >= 6) asm volatile ("pop %%r9       "  : : : "r9" );
+
+	// Call the system
+	asm volatile ("syscall");
+
+	// Return.
+	asm volatile ("ret");
+}
+
+/**
+ * Do a system call, heavily optimized
+ *
+ * \param  op   operation
+ * \param  args the arguments
+ * \return system call return value
+ */
+template<LnxSystemCallArgumentType... _ArgTypes>
+inline int LnxSystemCall(LnxSystemOp op, _ArgTypes... args) noexcept {
+	return LnxSystemCallInternal(static_cast<long>(op), LnxSystemCallCast(args)...);
+}
+
+/**
+ * Write to a file descriptor
+ */
+inline int LnxWrite(int fileno, const char* path, long count) noexcept {
+	return LnxSystemCall(LnxSystemOp::WRITE, fileno, path, count);
+}
+
+/**
+ * Exit.
+ */
+[[noreturn]]
+inline int LnxExitProcess(int status) noexcept {
+	LnxSystemCall(LnxSystemOp::EXIT, status);
+
+	__builtin_unreachable();
+}
diff --git a/lcrash/CMakeLists.txt b/lcrash/CMakeLists.txt
new file mode 100644
index 0000000..01ae86d
--- /dev/null
+++ b/lcrash/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.28)
+
+lw_project(lcrash
+	DESCRIPTION "Lindows BSOD"
+	TARGET      LINDOWS
+)
+
+lw_add_executable(lcrash
+	SOURCES lcrash.c
+)
+add_executable(lcrashld IMPORTED)
+set_property(TARGET lcrashld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
+set_property(TARGET lcrash PROPERTY LINK_DEPENDS
+	$<TARGET_FILE:lcrashld>
+	$<TARGET_FILE:LindowsCompilerSpec>
+)
+set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
diff --git a/lcrash/lcrash.c b/lcrash/lcrash.c
new file mode 100644
index 0000000..dc816e6
--- /dev/null
+++ b/lcrash/lcrash.c
@@ -0,0 +1,129 @@
+#include "lnxboot.h"
+
+extern void _start();
+
+[[gnu::section(".lnxhead")]]
+[[gnu::used]]
+[[gnu::aligned(1)]]
+[[gnu::unavailable("not present at runtime. use setup_info instead")]]
+struct setup_info bzhead = {
+	.setup_sects = 1, // 1 512-byte sector
+	.boot_flag = 0xAA55,
+	.syssize = 16,
+	.jump_instruction = 0xEB,
+	.jump_offset = sizeof(struct setup_info) - __builtin_offsetof(struct setup_info, signature),
+	.signature = 0x53726448,
+	.version = 0x020F,
+	.loadflags = 0x01, // LOADED_HIGH,
+	.kernel_alignment = 1,
+	.relocatable_kernel = 1,
+	.xloadflags = 0x13, // XLF_KERNEL_64 | XLF_CAN_BE_LOADED_ABOVE_4G | XLF_5LEVEL
+	.cmdline_size = 255, // max command line size
+	.init_size = 0x10000 // we dont need THAT much memory
+};
+
+struct setup_info*  setup_info;
+struct boot_params* boot_params;
+
+unsigned short serial_port;
+
+void outb(unsigned short port, unsigned char value) {
+	asm volatile (
+		  "outb %b0, %1"
+		::"a" (value)
+		 ,"d" (port)
+	);
+}
+
+void serial_putc(char c) {
+	outb(serial_port, c);
+}
+
+void serial_puts(const char* s) {
+	while (*s) serial_putc(*(s++));
+}
+
+void serial_put_formatted_u64(u64 v) {
+	if (v == 0) {
+		serial_putc('0');
+	} else {
+		u64 max = 1;
+
+		while (v > max) max *= 10;
+
+		while (v) {
+			serial_putc('0' + (u8)(v / max));
+
+			v   %= max;
+			max /= 10;
+		}
+	}
+}
+
+[[gnu::section(".text._start"), gnu::naked]]
+extern void _start() {
+	asm ( // grab the setup_info and boot_params locations
+	      	  "mov  %%rsi,  %1\n"
+		  "mov  %%rsi,  %0\n"
+		  "addq $0x1f1, %0"
+		: "=m" (setup_info),
+		  "=m" (boot_params)
+	);
+	asm ("jmp entry");
+}
+
+[[gnu::section(".text._start")]]
+void entry() {
+	// get the zero page
+	//boot_params = (struct boot_params*)(
+	//		  0x202 - 0x1f1
+	//		+ setup_info->jump_offset
+	//		+ (u64)setup_info);
+
+	// orignally we would try to import the serial port from the kernel (see kexec tools)
+	// as you can see, we gave up!
+	// serial_port = (unsigned short)*(long*)&serial_base;
+	serial_port = 0x3f8;
+
+	// construct pointers
+	u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32));
+
+	// check out command line
+	serial_puts(cmdline_ptr);
+	serial_putc('\r');
+	serial_putc('\n');
+
+	// we dont have the privilege of getting a rodata segment. any reads off our stack cause a triple fault
+	// for some fucking reason. allocate our strings and shit on the stack.
+	//char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n";
+	//char s_vga_you_fucked_up[] = "YOU FUCKED UP.\n";
+	//char s_description[] = "A SERIOUS ERROR HAS OCCURED AND LINDOWS HAS STOPPED TO PREVENT FURTHER DAMAGE.";
+	//char s_registers[] = "REGISTERS:";
+	//char s_call_trace[] = "CALL TRACE:";
+	//char s_dumpcore[] = "[(D)UMP CORE]";
+	//char s_poweroff[] = "[(P)OWER OFF]";
+	//char s_reboot[]   = "[(R)EBOOT   ]";
+
+	// You fucked up.
+	//serial_puts(s_you_fucked_up);
+	//serial_puts(s_description);
+	//serial_putc('\n');
+
+	// register dump
+	//serial_puts(s_registers);
+	//serial_putc('\n');
+	//serial_putc('\n');
+
+	// call trace
+	//serial_puts(s_call_trace);
+	//serial_putc('\n');
+	//serial_putc('\n');
+
+	// thing
+	// serial_puts("test\n");
+	// serial_puts(bzhead.cmd_line_ptr);
+	
+	// Die.
+	asm ("cli");
+	asm ("hlt");
+}
diff --git a/lcrash/lcrash.ld b/lcrash/lcrash.ld
new file mode 100644
index 0000000..b95e18f
--- /dev/null
+++ b/lcrash/lcrash.ld
@@ -0,0 +1,26 @@
+OUTPUT_FORMAT(elf64-x86-64)
+
+SECTIONS {
+	.lnxhead 0x01f1 : ALIGN(1) {
+		*(.lnxhead);
+	}
+
+	.rodata 0x900000 : ALIGN(1) {
+		*(.rodata);
+	}
+
+	.text._start 0x80000000 : ALIGN(1) {
+		*(.text._start);
+	}
+
+	.text : ALIGN(512) { *(.text); }
+	.bss : { *(.bss); }
+
+	.kernel_imports 0xFFFFFFFF : {
+		*(.kernel_imports);
+	}
+
+	/DISCARD/ : {
+		*(*);
+	}
+}
diff --git a/lcrash/lnxboot.h b/lcrash/lnxboot.h
new file mode 100644
index 0000000..a745c50
--- /dev/null
+++ b/lcrash/lnxboot.h
@@ -0,0 +1,156 @@
+#pragma once
+
+typedef unsigned char      u8;
+typedef unsigned short     u16;
+typedef unsigned int       u32;
+typedef unsigned long long u64;
+
+struct [[gnu::packed]] setup_info {
+	u8  setup_sects;
+	u16 root_flags;
+	u32 syssize;
+	u16 ram_size;
+	u16 vid_mode;
+	u16 root_dev;
+	u16 boot_flag;
+	u8  jump_instruction;
+	u8  jump_offset;
+	u32 signature;
+	u16 version;
+	u32 realmode_switch;
+	u16 start_sys_seg;
+	u16 kernel_version;
+	u8  type_of_loader;
+	u8  loadflags;
+	u16 setup_move_size;
+	u64 code32_start;
+	// FUCK THE RAMDISK 
+	u32 ramdisk_size;
+	u32 bootsect_kludge;
+	u16 heap_end_ptr;
+	u8  ext_loader_ver;
+	u8  ext_loader_type;
+	u32 cmd_line_ptr;
+	u32 initrd_addr_max;
+	u32 kernel_alignment;
+	u8  relocatable_kernel;
+	u8  min_alignment;
+	u16 xloadflags;
+	u32 cmdline_size;
+	u32 hardware_subarch;
+	u64 hardware_subarch_data;
+	u32 payload_offset;
+	u32 payload_length;
+	u64 setup_data;
+	u64 pref_address;
+	u32 init_size;
+	u32 handover_offset;
+	u32 kernel_info_offset;
+};
+
+struct [[gnu::packed]] screen_info {
+	u8  orig_x;
+	u8  orig_y;
+	u16 ext_mem_k;
+	u16 orig_video_page;
+	u8  orig_video_mode;
+	u8  orig_video_cols;
+	u8  flags;
+	u8  reserved;
+	u16 orig_video_ega_bx;
+	u16 reserved2;
+	u8  orig_video_lines;
+	u8  orig_video_isVGA;
+	u8  orig_video_points;
+
+	// linear frame buffer
+	u16 lfb_width;
+	u16 lfb_height;
+	u16 lfb_depth;
+	u32 lfb_base;
+	u16 cl_magic;
+	u16 cl_offset;
+	u16 lfb_linelength;
+	u8  red_size;
+	u8  red_pos;
+	u8  green_size;
+	u8  green_pos;
+	u8  blue_size;
+	u8  blue_pos;
+	u8  reserved_size;
+	u8  reserved_pos;
+	u8  vesapm_seg;
+	u8  vesapm_off;
+	u16 pages;
+	u16 vesa_attributes;
+	u32 capabilities;
+	u32 ext_lfb_base;
+	u8  reserved3[0x2];
+};
+
+struct [[gnu::packed]] apm_bios_info {
+	u8 pad[0x14];
+};
+
+struct [[gnu::packed]] ist_info {
+	u8 pad[0x10];
+};
+
+/// \deprecated
+struct [[gnu::packed]] sys_desc_table {
+	u8 pad[0x10];
+};
+
+struct [[gnu::packed]] edid_info {
+	u8 pad[0x80];
+};
+
+struct [[gnu::packed]] efi_info {
+	u8 pad[0x20];
+};
+
+struct [[gnu::packed]] e820_entry {
+	u8 pad;
+};
+
+struct [[gnu::packed]] edd_info {
+	u8 pad;
+};
+
+struct [[gnu::packed]] boot_params {
+	struct screen_info    screen_info;
+	struct apm_bios_info  apm_bios_info;
+	u8                    reserved0[0x4];
+	void*                 tboot_addr;
+	struct ist_info       ist_info;
+	void*                 acpi_rsdp_addr;
+	u8                    reserved1[0x2];
+	u8                    hd0_info[0x10];
+	u8                    hd1_info[0x10];
+	struct sys_desc_table sys_desc_table;
+	u8                    olpc_ofw_header[0x10];
+	/// ramdisk_image high 32 bits
+	u32                   ext_ramdisk_image;
+	/// ramdisk_size high 32 bits
+	u32                   ext_ramdisk_size;
+	/// cmd_line_ptr high 32 bits
+	u32                   ext_cmd_line_ptr;
+	u8                    reserved2[0x70];
+	void*                 cc_blob_address;
+	struct edid_info      edid_info;
+	struct efi_info       efi_info;
+	u32                   alt_mem_k;
+	u32                   scratch;
+	u8                    e820_entries;
+	u8                    eddbuf_entries;
+	u8                    edd_mbr_sig_buf_entries;
+	u8                    kbd_status;
+	u8                    secure_boot;
+	u8                    reserved3[0x2];
+	u8                    sentinel;
+	u8                    reserved4[0xa0]; // setup_info lives here!
+	u8                    edd_mbr_sig_buffer[0x40];
+	u8                    e20_table[0xa00];
+	u8                    reserved5[0x30];
+	u8                    eddbuf[0x1ec];
+};
diff --git a/lrss/CMakeLists.txt b/lrss/CMakeLists.txt
index ef46f95..896c3c2 100644
--- a/lrss/CMakeLists.txt
+++ b/lrss/CMakeLists.txt
@@ -11,6 +11,6 @@ lw_add_executable(lrss
 target_link_libraries(lrss PRIVATE lrssclient)
 
 lw_add_library(lrssclient SHARED
-	SOURCES lib/library.cxx
+	SOURCES liblrssclient/src/library.cxx
 )
-target_include_directories(lrssclient PUBLIC include)
+target_include_directories(lrssclient PUBLIC liblrssclient/include)
diff --git a/lrss/include/lindows/lrss.h b/lrss/liblrssclient/include/lindows/lrss.h
similarity index 100%
rename from lrss/include/lindows/lrss.h
rename to lrss/liblrssclient/include/lindows/lrss.h
diff --git a/lrss/lib/library.cxx b/lrss/liblrssclient/src/library.cxx
similarity index 100%
rename from lrss/lib/library.cxx
rename to lrss/liblrssclient/src/library.cxx
diff --git a/scripts/hivex/system.hivex b/scripts/hivex/system.hivex
new file mode 100644
index 0000000..6585d9b
--- /dev/null
+++ b/scripts/hivex/system.hivex
@@ -0,0 +1,24 @@
+add Select
+cd  Select
+setval 1
+Default
+string:001
+cd  ..
+
+add ControlSet001
+cd  ControlSet001
+add Control
+cd  Control
+add Session Manager
+cd  Session Manager
+add Environment
+cd  Environment
+setval 1
+PATH
+expandstring:C:\Windows\System32\
+cd  ..
+cd  ..
+cd  ..
+cd  ..
+
+commit
diff --git a/scripts/mkhive b/scripts/mkhive
new file mode 100755
index 0000000..07bf6b6
--- /dev/null
+++ b/scripts/mkhive
@@ -0,0 +1,188 @@
+#!/bin/bash
+# PARAM 1: PATH
+
+SHITFILE="$(mktemp)"
+HIVEPATH="$1";
+
+# chararr length, format, args...
+function chararr() {
+	printf "$2" "${@:3}" > "$SHITFILE";
+	truncate "$SHITFILE" -s "$1";
+	cat "$SHITFILE" >> "$HIVEPATH";
+}
+
+# wchararrle length, format, args
+function wchararrle() {
+	printf "$2" "${@:3}" | iconv -t utf-16le > "$SHITFILE";
+	truncate "$SHITFILE" -s "$1";
+	cat "$SHITFILE" >> "$HIVEPATH";
+}
+
+# i1le value
+function i1le() {
+	printf "\\$(printf "%o" $(( $1 & 255 )))" >> "$HIVEPATH";
+}
+
+# i2le value
+function i2le() {
+	I1=$(printf "%o" $((($1 >> 8) & 255 )));
+	I0=$(printf "%o" $((($1     ) & 255 )));
+
+	printf "\\$I0\\$I1" >> "$HIVEPATH";
+}
+
+# i4le value
+function i4le() {
+	I3=$(printf "%o" $((($1 >> 24 ) & 255 )) );
+	I2=$(printf "%o" $((($1 >> 16 ) & 255 )) );
+	I1=$(printf "%o" $((($1 >>  8 ) & 255 )) );
+	I0=$(printf "%o" $((($1       ) & 255 )) );
+
+	printf "\\$I0\\$I1\\$I2\\$I3" >> "$HIVEPATH";
+}
+
+# i8le value
+function i8le() {
+	C1=$(( $1 >> 32 ));
+	C0=$(( $1 & 4294967295 ));
+
+	i4le $C0;
+	i4le $C1;
+}
+
+# i1lea values...
+function i1lea() {
+	while [ -v 1 ]; do
+		i1le $1;
+		shift;
+	done;
+}
+
+# i2lea values...
+function i2lea() {
+	while [ -v 1 ]; do
+		i2le $1;
+		shift;
+	done;
+}
+
+# i4lea values...
+function i4lea() {
+	while [ -v 1 ]; do
+		i4le $1;
+		shift;
+	done
+}
+
+# i8lea values...
+function i8lea() {
+	while [ -v 1 ]; do
+		i8le $1;
+		shift;
+	done
+}
+
+# pad count
+function pad() {
+	>"$SHITFILE";
+	truncate -s "$1" "$SHITFILE";
+	cat "$SHITFILE" >> "$HIVEPATH";
+}
+
+if [ -n "$HIVEPATH" ]; then
+	echo "MAKE HIVE AT $1";
+	
+	# clear file
+	>test.dat
+
+	# base block
+	chararr    4 "regf"
+	i4lea      0 0
+	i8le       0
+	i4lea      1 6 0 1 352 4096 0
+	wchararrle 64 "%s" "$(basename "$HIVEPATH")"
+	pad        396
+
+	for w in $(hexdump "$HIVEPATH" -v -e '"%i\n"'); do
+		if [ ! -v CHKSUM ]; then
+			CHKSUM=$w;
+		else
+			CHKSUM=$(( $CHKSUM ^ $w ));
+		fi
+	done
+	i4le       $CHKSUM # checksum but fuck you we dont check the sum
+	
+	pad        3576
+	i4lea      0 0
+
+	# hive bin
+	chararr 4 "hbin"
+	i4lea   0 4096
+	i8lea   0 0
+	i4le    0
+
+	# LRSS hive bin data block 
+	i4le    -16
+	chararr 2 "Ld" # (!) non standard 
+	i1le    1  # The tree alloc list be invalid
+	i1le    0  # reserved
+	i4le    1  # number of 4096 byte chunks (alloc list byte length is this * 128 + 24)
+	i4le    48 # offset from bin start to alloc list
+
+	# LRSS hive bin alloc list
+	i4le    -152
+	chararr 2 "La" # (!) non standard
+	pad     2
+	i2lea   70 71 73 77 85 101 133 # alloc list offsets
+	pad     130
+
+	for (( i=0; i < 19 ; i++ )); do
+		i8le 4294967288;
+	done
+
+	# root key
+	i4le    -80
+	chararr 2 "nk"
+	i2le    0
+	i8le    0
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    432
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    440
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    0
+	i4le    0
+	i2le    0
+	i2le    0
+
+	# root key subkeys
+	i4le    -8
+	chararr 2 "li"
+	i2le    0
+
+	# root key security info B)
+	i4le    -24
+	chararr 2 "sk"
+	i2le    0
+	i4le    440 # fuck the header just link to ourself, this will surely have no consequences in the future 
+	i4le    440 
+	i4le    1 # referenced by root key
+	i4le    0 # descriptor length 
+
+	# fill with empty cells
+	for (( i=$(( (8192 - $(wc -c "$HIVEPATH" | cut -f 1 "-d ")) / 8 )); i > 0; i-- )); do
+		i4lea 8 0;
+	done
+else
+	echo "ERR: Hive path not specified";
+fi
+
+rm "$SHITFILE"
diff --git a/src/grub/grub.cfg b/src/grub/grub.cfg
index 7dcf1cc..1f53518 100644
--- a/src/grub/grub.cfg
+++ b/src/grub/grub.cfg
@@ -2,5 +2,5 @@
 clear
 
 # boot  
-linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lsmss.exe
+linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lexecutive.exe loglevel=8 crashkernel=16M 
 boot
diff --git a/src/linux/config b/src/linux/config
index 0e1c894..c002073 100644
--- a/src/linux/config
+++ b/src/linux/config
@@ -18,7 +18,7 @@ CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
 CONFIG_TOOLS_SUPPORT_RELR=y
 CONFIG_CC_HAS_ASM_INLINE=y
 CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
-CONFIG_PAHOLE_VERSION=125
+CONFIG_PAHOLE_VERSION=126
 CONFIG_IRQ_WORK=y
 CONFIG_BUILDTIME_TABLE_SORT=y
 CONFIG_THREAD_INFO_IN_TASK=y
@@ -280,8 +280,9 @@ CONFIG_TRACEPOINTS=y
 CONFIG_CRASH_CORE=y
 CONFIG_KEXEC_CORE=y
 CONFIG_KEXEC=y
-# CONFIG_KEXEC_FILE is not set
-# CONFIG_KEXEC_JUMP is not set
+CONFIG_KEXEC_FILE=y
+# CONFIG_KEXEC_SIG is not set
+CONFIG_KEXEC_JUMP=y
 CONFIG_CRASH_DUMP=y
 CONFIG_CRASH_HOTPLUG=y
 CONFIG_CRASH_MAX_MEMORY_RANGES=8192
@@ -452,6 +453,7 @@ CONFIG_HZ=1000
 CONFIG_SCHED_HRTICK=y
 CONFIG_ARCH_SUPPORTS_KEXEC=y
 CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y
+CONFIG_ARCH_SELECTS_KEXEC_FILE=y
 CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y
 CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y
 CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y
@@ -1492,6 +1494,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Firmware loader
 #
 CONFIG_FW_LOADER=y
+CONFIG_FW_LOADER_DEBUG=y
 CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_FW_LOADER_USER_HELPER is not set
 # CONFIG_FW_LOADER_COMPRESS is not set
@@ -5059,8 +5062,8 @@ CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
 CONFIG_CONSOLE_LOGLEVEL_QUIET=4
 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
 # CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DYNAMIC_DEBUG_CORE is not set
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DYNAMIC_DEBUG_CORE=y
 CONFIG_SYMBOLIC_ERRNAME=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # end of printk and dmesg options
@@ -5377,6 +5380,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
 # CONFIG_TEST_SYSCTL is not set
 # CONFIG_TEST_UDELAY is not set
 # CONFIG_TEST_STATIC_KEYS is not set
+# CONFIG_TEST_DYNAMIC_DEBUG is not set
 # CONFIG_TEST_KMOD is not set
 # CONFIG_TEST_MEMCAT_P is not set
 # CONFIG_TEST_MEMINIT is not set