Repository navigation
Releases
Releases · fels-lang/fels
fels 0.14.0
Fels runs without an operating system: --target uefi makes a UEFI application and
--target freestanding an ELF for a kernel, on x86-64 and now on 64-bit ARM too, with
interrupt handlers as plain functions and a heap a kernel can hand memory to. Programs can carry
debug info (-g), so a debugger shows their source lines, parameters and locals. And a few
fixes: a println in a long loop no longer runs out of stack, and in the editor a module's
function completes as the whole call.
Added
- Debug info:
-g(andfels build -gfor a project) gives a program the source lines,
functions, parameters and locals with their types that a debugger shows: a PDB beside a
Windows program, DWARF in a Linux one. On Windows the program is then linked by LLD, which
needs the Windows SDK's import libraries. - UEFI applications:
--target uefi(ora.target(.uefi)in build.fels) makesname.efi,
which the firmware starts with no operating system.printlngoes to the firmware's console,
zones take the firmware's pages, andstd.uefihas the system table,stall, keys,clear,
the framebuffer,shutdownandreboot.examples/uefidraws on the screen and turns off. - Freestanding programs:
--target freestanding(or.freestanding) makes a static ELF
with no operating system, for a kernel. A_startcallsmainand halts, or the program's
own#entryis the start; no function uses the red zone; zones take a static heap, and
std.freestanding.set_outputnames whereprintlnwrites.examples/kernelboots in QEMU
as a multiboot kernel and prints on the screen and the serial port. std.x86: port I/O,cli/sti/hlt,lgdt/lidt, the control registers, MSRs,
rdtscandcpuid.--link-arg <flag>passes a flag to the linker as it is, such as a linker script.- Interrupt handlers as functions:
#interruptmakes an x86-64 function the CPU calls with
the frame it pushed (*const x86::InterruptFrame) and, for some exceptions, an error code; it
saves every register it uses and returns withiretq.x86::Idtholds them
(set(vector, core::fn_ptr(f)),load()). Code can't call one. - 64-bit ARM without an operating system:
--target aarch64-uefiand
--target aarch64-freestanding(ora.arch(.aarch64)in build.fels).std.aarch64has the
barriers, the system registers and exception vectors that call an ordinary function with the
saved registers.examples/kernel_aarch64boots on QEMU'svirtmachine. - Memory for a kernel:
std.freestanding.add_memory(base, len)gives zones more memory and
free_memory()says how much is left. Zones give their memory back when they end.
Changed
- A freestanding program without an
#entryof its own starts where its linker script's
ENTRYsays, or at_start; the linker was told_startand ignored the script. #extern("kernel32.dll", …)built, but the program then did not start: Windows looked
forkernel32.dll.dll. A library name with.dllis now an error that shows the name
without it.
Fixed
#section,#weak,#cold,#keepand#link_namewere dropped from a function in every
native build: the passes that run before code generation rebuilt it without them.- A function named where an
extern fngoes (set_output(serial_write)) was passed as a
closure, so the callee called the wrong address. It is now the function's own address. - A
core::asmtemplate written as a"""block reached the assembler with its escapes and
quotes as written; it is now the block's lines. - A
println("{x}")in a loop crashed with a stack overflow (exit code0xC00000FD) after tens
of thousands of passes: each pass took more stack for the values in the braces and never gave
it back. A format's values now have one place on the stack, which every pass reuses. - In the editor, a module's function after
io::(or anyalias::) completed as its name only.
It now completes as the call, with a tab stop per argument, and shows its parameters and its
documentation, as a function in scope does.
Nightly 0.14.0
Automated build from the latest main, version 0.14.0.
Download fels-0.14.0-x86_64-windows.zip, extract, and run bin/fels
(the standard library + linker travel with it). Refreshed on every push.