# The Loup Freestanding Book

*For Loup 1.25. Freestanding support is experimental in this release; features the Language Reference specifies but the toolchain does not implement yet are marked ⚠ Planned.*

This book teaches `@mode(freestanding)`: writing kernels, boot loaders, firmware and other bare-metal programs in Loup. A freestanding image runs with no operating system, no libc and no Loup runtime underneath it — when it starts, the only code in memory is what you wrote and what the toolchain linked for you (`memcpy` and similar helpers). Loup's type system, ownership verbs, `unique` values and lifetimes all work there, together with the features bare metal needs: inline assembly, volatile MMIO, interrupt handlers, naked functions, layout control and linker sections.

## Who this book is for

- You are writing an operating-system kernel, a boot loader, a hypervisor payload or microcontroller firmware.
- You know what a linker script, an interrupt vector and a memory-mapped register are.
- You have written some Loup, or are willing to pick up the syntax from [The Loup Scripting Book](../loup-scripting/) or [The Loup Native Book](../loup-native/) — the hosted books are the gentler place to learn the language and its ownership system.

## The mode directive

Freestanding source files use the `.lpfree` extension and begin with:

```loup
@mode(freestanding)

const UART0_BASE: uint64 = 0x0900_0000u64
```

The directive must be the file's first token (only comments may precede it). There is no `main`: the image's entry point is a function marked `@entry`.

## Installing the toolchain

Loup is installed from the official releases at `github.com/code-craft-ai-company/loup-releases`:

```sh
# Linux and macOS
curl -fsSL https://github.com/code-craft-ai-company/loup-releases/releases/latest/download/loup-install.sh | sh
```

```sh
# Windows (PowerShell)
irm https://github.com/code-craft-ai-company/loup-releases/releases/latest/download/loup-install.ps1 | iex
```

The installer puts the tools in `~/.loup/bin` (or `%LOCALAPPDATA%\Programs\Loup`) and adds them to `PATH`; no administrator rights are needed. To pin a version, run the script with `sh -s -- --version 1.25.1` or set `LOUP_VERSION`. After a browser download on macOS, clear the quarantine flag with `xattr -dr com.apple.quarantine <dir>`.

What each platform can do with freestanding code in 1.25:

- **Type-checking** (`loup check` in a project; `loup-bootstrap check` on Linux x86-64) works on every platform.
- **Building images** (`loup build --target freestanding --arch …`) works on **Linux x86-64** and needs `ld.lld`. The default back end is Loup's own clang-free `llbe`; `--backend llvm` uses clang.
- **Running images** needs QEMU (`qemu-system-x86_64`, `qemu-system-aarch64`, `qemu-system-riscv64`, `qemu-system-arm`) or real hardware. x86_64, aarch64, riscv64, armv7 and Cortex-M images are boot-tested under QEMU.

## Hello, bare metal

Three files print a line on the serial console of QEMU's AArch64 `virt` machine. `src/main.lpfree`:

```loup
@mode(freestanding)

# QEMU `virt` (AArch64): the PL011 UART's data register.
let UART0_DATA = Volatile[uint8].at(0x0900_0000)

func uartWrite(s: string): void {
    for (c in s) {
        UART0_DATA.write(c as uint8)
    }
}

func kernelMain(): void {
    uartWrite("Hello from Loup freestanding\n")
    while (true) {
        asm { "wfi" clobbers: [] }
    }
}

@entry
@naked
@unsafe("naked: runs before any stack exists; sets sp from __stack_top")
@section(".text.boot")
func _start(): void {
    asm {
        "adrp x0, __stack_top"
        "add x0, x0, :lo12:__stack_top"
        "mov sp, x0"
        "bl kernelMain"
        "1: wfe"
        "b 1b"
        clobbers: ["memory"]
    }
}
```

`kernel.ld`:

```text
ENTRY(_start)

PHDRS {
    text PT_LOAD FLAGS(7);
}

SECTIONS {
    . = 0x40080000;
    .text.boot : { KEEP(*(.text.boot)) } :text
    .text      : { *(.text .text.*) }       :text
    .rodata    : { *(.rodata .rodata.*) }   :text
    .data      : { *(.data .data.*) }       :text
    .bss       : {
        *(.bss .bss.*)
        . = ALIGN(16);
        . = . + 65536;
        __stack_top = .;
    } :text
}
```

`hello.lppkg`:

```toml
name = "hello"
version = "0.1.0"

[build]
entry  = "src/main.lpfree"
target = "freestanding"
mode   = "freestanding"
arch   = "aarch64"
panic  = "halt"

[linker]
script = "kernel.ld"
entry  = "_start"

[freestanding]
stack_size = 65536
```

Build on Linux x86-64 and boot:

```sh
loup build
qemu-system-aarch64 -M virt -cpu cortex-a53 -m 256M -nographic -kernel ./hello
```

```text
Hello from Loup freestanding
```

Chapters 1 and 2 explain every line; chapter 21 builds a larger kernel for x86_64.

## The Loup books

| Mode | What it is for | Book |
|---|---|---|
| `host.scripted` | scripts and tools run by the interpreter | [The Loup Scripting Book](../loup-scripting/) |
| `host.dual`, `host.native` | applications compiled to native binaries (or run by the interpreter) | [The Loup Native Book](../loup-native/) |
| `web.scripted`, `web.compiled` | browser applications (the browser runtime is planned) | [The Loup Web Book](../loup-web/) |
| `freestanding` | kernels, boot loaders, firmware — no runtime | **this book** |

## What freestanding keeps, and what it leaves out

You keep the type system, generics and interfaces (resolved at compile time), `match`, `Result`-based error handling, the ownership verbs and `unique` values, borrows and lifetimes, and compile-time evaluation. You gain `@entry`, `@naked`, `@callconv`, `asm { }`, `Volatile[T]` and `volatile borrow`, `@repr`, `@align`, `@section`, `buffer[T, N]`, `onstack`, `@interrupt`, `@interruptSafe`, `InterruptGuard`, `@panic_handler`, `@allocator`, `PartialInit[T]`, and bare intrinsics for atomics and raw memory.

You leave out everything that needs a runtime: exceptions (`throw`, `catch (T as e)`), `weak` references, `dynamic class`, `defer import`, `consume`, `async`/`await`, `bigint`/`decimal`, growable collections, template fences, reflection, and the hosted standard library. Chapter 1 lists which of these the 1.25 checker rejects and which it does not yet catch.

## Table of contents

### Part I: The Bare-Metal Foundation

1. [What Is Freestanding Mode?](ch01-what-is-freestanding.md)
2. [Building a Bare-Metal Binary](ch02-building-a-bare-metal-binary.md)
3. [Integer Types and Wrapping Arithmetic](ch03-integer-types-and-wrapping-arithmetic.md)
4. [Functions and Control Flow](ch04-functions-and-control-flow.md)

### Part II: Data and Types on the Metal

5. [Structs and Layout Control](ch05-structs-and-layout.md)
6. [Enums and Pattern Matching](ch06-enums-and-pattern-matching.md)
7. [Classes and Allocators](ch07-classes-and-allocators.md)
8. [Interfaces and Generics](ch08-interfaces-and-generics.md)

### Part III: Safety Without a Runtime

9. [Error Handling with Result](ch09-error-handling-with-result.md)
10. [Ownership Verbs](ch10-ownership-verbs.md)
11. [Borrow and Lifetimes](ch11-borrow-and-lifetimes.md)
12. [Unique Ownership](ch12-unique-ownership.md)
13. [Memory Primitives](ch13-memory-primitives.md)

### Part IV: Talking to Hardware

14. [Inline Assembly](ch14-inline-assembly.md)
15. [MMIO with Volatile](ch15-mmio-with-volatile.md)
16. [Interrupts and Naked Functions](ch16-interrupts-and-naked-functions.md)
17. [Entry Points and Panic](ch17-entry-points-and-panic.md)
18. [Sections and the Linker](ch18-sections-and-linker.md)

### Part V: Putting It Together

19. [Multicore and Atomics](ch19-multicore-and-atomics.md)
20. [The Available Standard Library Subset](ch20-available-stdlib-subset.md)
21. [Example — x86_64 Kernel Stub](ch21-example-x86_64-kernel-stub.md)
22. [Testing and Deploying Firmware](ch22-testing-and-deploying-firmware.md)
23. [Memory Safety and Kernel Development Patterns](ch23-memory-safety-and-kernel-patterns.md) — kernel problems worked through with Loup features: fixed-capacity structures, address newtypes, user-pointer validation, DMA hand-off with `unique` ownership, cleanup with `finally`, generation-checked handles, interrupt-safe rings, and the `@unsafe` audit.
24. [`synchronized` Classes and Lock Ordering](ch24-synchronized-and-lock-ordering.md)

## Conventions

- Every chapter's first listing shows `@mode(freestanding)`. Later listings may hide it, along with helper declarations, so the visible code stays focused; every listing marked as compiling is type-checked with the 1.25 toolchain as a complete `src/main.lpfree`.
- A listing labelled as not compiling is followed by the compiler's actual diagnostic. Listings marked as compiling but behaving wrongly are explained in the text.
- `> ⚠ **Planned.**` marks a feature the Language Reference specifies that Loup 1.25 does not implement yet.
- Shell commands are shown in `sh` blocks, program and compiler output in `text` blocks, manifests in `toml` blocks.
- Section references such as "§3-3.17b" point into the four-volume Loup Language Reference; freestanding mode is specified in volume 3 (compilation), §3-3, at [loup-language-compilation-v1_20.md](../../specs/loup-language-compilation-v1_20.md), and the core language in [loup-language-core-v1_20.md](../../specs/loup-language-core-v1_20.md). Where the toolchain and the reference disagree, the book shows what the toolchain does and says what the reference specifies.
