Makar can recompile its own kernel from source using the shipped TinyCC
(/apps/tcc.elf), then boot the new image without leaving QEMU. This
is the “self-host” milestone (v0.9): the bootable Multiboot 2 ELF you
just booted is the same artifact you can produce by running TCC from
the live shell.
There are two surfaces:
| Surface | What it builds with | When to use |
|---|---|---|
./build-kernel-tcc.sh (host) |
Your host’s TCC build out of vendor/tinycc/ |
Sanity-check the recipe + regenerate src/userspace/rebuild-kernel.sh |
/apps/rebuild-kernel.sh (in-OS) |
The shipped /apps/tcc.elf inside a running Makar |
Actually rebuild the kernel while booted |
Both share a single source-file list, generated by build-kernel-tcc.sh.
The default ISO already ships everything the in-OS build needs:
/apps/tcc.elf — TinyCC v0.9.27 cross-built and dropped on every ISO/apps/kend.S — the _kernel_end sentinel (TCC has no linker
script support, so this object is linked LAST and exposes
_kernel_end from BSS the way linker.ld does for the GCC build)/usr/include/kernel-build/ — kernel headers re-exported into the
sysroot so #include <kernel/...> resolves/usr/include/ — userspace libc headers (TCC sysroot)/usr/lib/{crt1,crti,crtn}.o, /usr/lib/libc.a — CRT + libc/usr/lib/tcc/libtcc1.a, /usr/lib/tcc/include/ — TCC’s own runtime
library + builtin headers (stdarg, stddef, the Makar stdint.h
stub, etc.)/src/... — the full kernel + libc source tree (so the rebuild
driver can point tcc -c at it directly)You also need ~64 MiB of RAM (qemu -m 64) and the test ISO booted
with a writable /tmp overlay (the default).
From any shell prompt inside Makar:
./apps/rebuild-kernel.sh
or, if you’re not in /apps:
sh /apps/rebuild-kernel.sh
What it does, step by step (the script itself is regenerated, so don’t
hand-edit src/userspace/rebuild-kernel.sh — edit build-kernel-tcc.sh
and re-run it):
mkdir /bin/ktcc — scratch dir for the .o files. /bin lives on
the rootfs (the installer creates it; tmpfs is flat so /tmp can’t
hold the per-source tree). On a CD-ROM-only live boot the rootfs is
read-only ISO9660 and this step will fail — run from an installed
HDD boot instead.tcc -c /apps/kend.S -o /tmp/ktcc/kend.o — the _kernel_end
sentinel.tcc -ffreestanding -D__is_kernel -DDEV_BUILD -DMAKAR_IN_OS_BUILD=1 \
-I/usr/include/kernel-build -c <src> -o /tmp/ktcc/NNN.o
MAKAR_IN_OS_BUILD=1 is the build-origin marker (see
src/kernel/arch/i386/boot/build_origin.c) so the boot banner of
the resulting kernel prints “Self-hosted kernel (built in Makar)”
instead of “Self-hosted kernel (built on host with TCC)” or
“Host-built kernel”. All three origins boot identically; only the
banner string differs.
tcc -static -nostdlib -Wl,-Ttext=0x100000 ... into
/bin/makar.kernel.tcc — a valid Multiboot 2 ELF that GRUB will
load like the original.REBUILD-KERNEL: ALL PASS on success, orREBUILD-KERNEL: FAIL if any compile/link step returned non-zero.Each tcc -c runs as its own ring-3 task (you can watch them tick by
in maktop). The driver also writes a rebuild-kernel: cc <file>
serial line per source so a headless capture (-serial file:...) gives
a complete build log.
The script does not copy the kernel into /boot automatically.
That’s a manual step so you can decide whether to keep the GCC kernel
around to fall back to.
On a live boot (CD-ROM or HDD install) you have two options.
If you booted from a writable HDD partition (/boot mirrors the FAT32
boot partition), copy and reboot:
cp /bin/makar.kernel.tcc /boot/makar.kernel
reboot
reboot is a shell builtin that triggers ACPI shutdown (port 0x604).
GRUB picks the kernel back up from /boot/makar.kernel on the next
boot. If the boot fails or panics, drop into a known-good ISO and
overwrite /boot/makar.kernel with the original.
The CD-ROM is read-only, so you can’t write /boot/makar.kernel back.
What you can do:
/bin lives on the rootfs, and the
CD-ROM rootfs (ISO9660) is read-only. You’ll get mkdir: cannot
create /bin/ktcc and every per-source tcc -c will silently
produce no .o. Install Makar to disk first (installer from
the shell), reboot off the HDD, then run rebuild-kernel.sh.For a turn-key “boot the freshly-built kernel without leaving QEMU,”
either work off an HDD image (./run.sh hdd boot) so /boot is
writable, or run the same recipe on the host with
./build-kernel-tcc.sh and rebuild a fresh ISO.
If you want to confirm the recipe works without booting Makar at all:
./build-kernel-tcc.sh
This drives the host TCC (vendor/tinycc/i386-tcc) against the same
source list and writes build/ktcc/makar.kernel.tcc. You can then:
qemu-system-i386 -kernel build/ktcc/makar.kernel.tcc -m 64
…or roll it into an ISO yourself and verify the boot banner reads
“Self-hosted kernel (built on host with TCC)” (the
MAKAR_IN_OS_BUILD=1 define is only set by the in-OS driver).
The boot banner is the easiest tell. Right after the “Initializing X… [OK]” sequence the kernel prints one of:
| Banner | Built by |
|---|---|
Host-built kernel |
i686-elf-gcc (the normal CI build) |
Self-hosted kernel (built on host with TCC) |
./build-kernel-tcc.sh |
Self-hosted kernel (built in Makar) |
/apps/rebuild-kernel.sh |
The string comes from MAKAR_BUILD_ORIGIN in
src/kernel/arch/i386/boot/build_origin.c, selected at compile time
via __TINYC__ + MAKAR_IN_OS_BUILD.
The end-to-end in-OS rebuild is opt-in (slow under TCG ≈ 10 min):
TEST_CMDLINE='test_mode test=rebuild-kernel' CFLAGS='-O0 -g3' TEST_ISO=1 \
bash iso.sh
qemu-system-i386 -cdrom makar-test.iso -serial file:/tmp/rk.log \
-display none -no-reboot -m 64 \
-device isa-debug-exit,iobase=0xf4,iosize=0x04
Then grep /tmp/rk.log for REBUILD-KERNEL: ALL PASS.
For a faster smoke that the in-OS TCC asm path still works (the
strtoull/(null):3811692 regression that bit kend.S compilation),
the regular LIBC-TCC suite now includes a compile-kend-S probe.
Run it via:
./run.sh iso test
— LIBC-TCC’s ALL PASS line guarantees that bare 0 literals in
in-OS asm still parse, without paying for the full rebuild-kernel run.
docs/history.md — shipped v0.9 self-host changesdocs/tcc-feasibility.md — why TCC, what’s covered, what’s leftdocs/userland-libc.md — the libc side of the same effortsrc/userspace/rebuild-kernel.sh — the generated driver (do not
edit; edit build-kernel-tcc.sh and re-run it)