XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
10.17 KB
Readme.md

Independent C# bootstrap kernel

This x86_64 bare-metal kernel has no Cosmos SDK, runtime, HAL, driver, scheduler, patcher or source dependency. The C# files contain the boot policy, bounded UART, memory-map validation, physical-page allocator, GDT/TSS/IDT construction, exception diagnostics and 32-bit framebuffer access. native.c contains only Limine request/storage declarations and instruction wrappers; entry.S contains the entry, descriptor reload and exception trampolines C# cannot express. Their paths are Native/native.c and Native/entry.S.

The Limine request identifiers and the x86_64 descriptor design were checked against this project's own historical Rust implementation at commit 1139821 (kernel/src/boot.rs, kernel/src/arch/x86_64.rs). They have been reimplemented in C#/C/assembly without copying or renaming Cosmos code. Limine remains an external BSD-2-Clause bootloader; its public boot protocol is 0BSD. The bflat Zero standard library and compiler remain external MIT tooling.

Build C# with pinned bflat 8.0.2, --os:linux --arch:x64 --stdlib:zero --target:Shared -c, and -i:xfe_native so P/Invoke resolves to the local xfe_* symbols directly. Compile native.c and entry.S for x86_64 ELF with Clang, -mno-red-zone, -ffreestanding, -fno-stack-protector, and link with the independent runtime object and a linker script retaining all .limine_requests* sections. The ELF entry is _start; no libc, dynamic loader or managed host process is used.

Exports: XfeKernelMain(NativeBootInfo*), XfeHandleInterrupt(InterruptFrame*). The kernel calls the optional partial method Kernel.OnKernelReady() after real boot self-tests pass. An application implementation in the same namespace and partial class can provide that method. No existing Kernel project is edited.

Bootstrap limits are explicit: one BSP, inherited bootloader page tables, physical allocation below 8 GiB, 4 KiB contiguous pages, no managed allocation, 32 single-BSP kernel threads, no SMP execution, no user-mode isolation, no storage or network. Memory above the allocator cap is counted as ignored. Only usable memory entries are allocated; bootloader-reclaimable, firmware and executable regions remain reserved. Runtime memory bridges mask IRQs around mutation, which provides single-BSP exclusion rather than an SMP lock. Release checks page ownership and rejects a duplicate release; it does not protect callers from unmapping a still-used allocation.

Serial success markers are emitted after actual C# checks, including zero/reuse/ ownership/contiguous page checks, SGDT/SIDT readback, returning INT3 through our IDT and SSE-preserving trampoline, and a framebuffer pixel readback. Presence of this source or an ELF object alone is not an accepted boot result.

Thread scheduling is single-BSP, with 32 slots and a calibrated periodic LAPIC timer. Context switches preserve System V nonvolatile registers, the real stack, FS base and complete enabled x87/SSE state. OSXSAVE is disabled; AVX/YMM/ZMM are not enabled or promised. New stacks have unmapped guards at both ends. Every thread also owns a separate guarded 64 KiB IRQ stack; the scheduler changes TSS IST3 with interrupts masked before changing context. Asynchronous IRQs preserve the System V 128-byte red zone used by the unchanged Microsoft native runtime archives, and suspended IRQ frames belong to their outgoing thread. The native preemption probe never yields or calls a helper: two threads' independent FS, XMM15 and all sixteen red-zone qwords must survive at least three actual LAPIC ticks and real context switches. Events use generation-tagged handles and real park/wake with manual/auto reset, timeout and close rejection. Full .NET GC hijacking uses the Microsoft runtime's real helper on captured contexts; a missing or inconvenient helper does not count as GC safety.

The 8042 driver initializes keyboard/mouse only after actual ACKs and polls real device bytes on LAPIC ticks. PS/2 set-1 translation and three-byte mouse packets enter a 256-report queue. Overflow or parity/timeout clears stale reports and emits an explicit loss report. USB HID, IME and wheel negotiation are not enabled. The same pure decoder source is linked into host regressions; those regressions are separate from actual guest device acceptance.

xfe_runtime_utc_filetime() double-samples the live CMOS RTC, bounds UIP polling, validates power/data fields and date ranges, handles BCD/binary and 12/24-hour modes, and uses century register 0x32 when valid. With an absent century it uses the explicit 1970/2069 pivot. Read failure returns zero. This is not a fixed build date or host callback. QEMU must use RTC base=utc; physical RTC timezone conventions remain to be verified before claiming that physical machine's UTC accuracy.

The virtual-memory arena uses two empty PML4 slots at low canonical address 0x0000200000000000, covering 1 TiB and up to 256 live reservations. Reserve records an address range without allocating RAM; commit creates zeroed 4 KiB supervisor RW/NX PTEs. Decommit clears PTEs, invalidates the local TLB and returns data pages and empty kernel-owned page-table pages. Release requires the original whole reservation. Protection accepts read=1, write=2, execute=4 and rejects W+X; CR0.WP and EFER.NXE enforce the policy. The boot self-test intentionally triggers two unmapped guard reads, a read-only write and an NX instruction fetch, returning only when the expected CR2, RIP and page-fault error bits match. It also checks zeroed commits and complete page reclamation. Existing and mixed-range commits preserve old pages; failed commits roll back only newly added pages. Physical release validates both ownership and exact allocation block boundaries, rejecting partial or cross-block frees. Only four-level paging and single-BSP edits are supported. No AP TLB shootdown or user-process memory domain is claimed.

The C ABI for the separate .NET module is xfe_runtime_alloc_pages(ulong) returning a zeroed 4 KiB-aligned HHDM pointer, xfe_runtime_free_pages(void*,ulong) returning 1 on success, xfe_runtime_write(byte*,ulong), xfe_runtime_mono_ns(), xfe_runtime_clock_ready(), xfe_runtime_framebuffer_info(NativeFrameSurface*) and xfe_runtime_halt(byte*). Counts for allocation/release are pages, not bytes. The surface structure is a 56-byte sequential value (two ulong fields followed by ten uint fields). Logs accept at most 1 MiB; fatal reasons read at most 256 bytes. These exports exchange no managed references. The TSC clock uses an explicit CPUID crystal/ratio or bounded PIT channel-2 calibration. A non-invariant TSC is identified in the boot log: elapsed-time accuracy across frequency changes is not promised.

To link Zero and .NET together, all Zero compiler/runtime symbols must be prefixed and its __modules, __managedcode and __unbox sections separated from the real runtime module tables. Restore only xfe_* imports and the C ABI exports. Map the Zero references SystemNative_Abort/SystemNative_Malloc to xfe_zero_abort/xfe_zero_malloc; do not bind either module to the other's Rhp* implementations or share Zero objects with the full .NET GC.