Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ time.

## [Unreleased](https://github.com/bboe/BBoeOS/compare/0.11.0...main)

- **Wire user/libbboeos clang exports into the shared blob.**
`user/libbboeos/libbboeos.a` (clang-compiled) now links into `build/libbboeos`
alongside the asm helpers via the existing ld pipeline; `-ffunction-sections`
+ `--gc-sections` drop everything the pointer table doesn't reference, so the
blob pays only for what it actually exports. First entry: `strcmp`, with a
new `FUNCTION_STRCMP_PTR` constant at `FUNCTION_POINTER_TABLE + 52`.
Cc.py-side wiring (extern-call fallback that emits `call
[FUNCTION_<name>_PTR]` for unknown names) lands in a follow-up — this PR is
the build-pipeline plumbing. `VDSO_SIGRETURN_OFFSET` moves from `0x460` →
`0xFE0` so the helper region can grow past 1 KB without colliding with the
sigreturn trampoline; sigreturn now lives near the end of page 0 (past the
pointer table at `0x800..0x83C`).
- **cc.py: fold byte-immediate store + movzx reload through local.** When a
one-shot struct literal local is read via ``*(uint8_t *)&local`` — the driver
port-I/O idiom — the compiler was emitting ``mov byte [ebp-N],
Expand All @@ -22,7 +34,6 @@ time.
~5 bytes per fold and trims the kernel's per-function frame traffic for every
bitfield-struct + ``kernel_outb`` site. Total kernel kasm reduction: 217
bytes.

- **Switch libbboeos build to nasm-elf + ld + linker script.** vdso.asm is now
`nasm -f elf32`-assembled with section directives
(`.libbboeos.function_table`, `.libbboeos.text`, `.libbboeos.rodata`,
Expand Down
14 changes: 13 additions & 1 deletion kernel/include/constants.asm
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@
%assign FUNCTION_PRINT_STRING_PTR FUNCTION_POINTER_TABLE + 40
%assign FUNCTION_PRINTF_PTR FUNCTION_POINTER_TABLE + 44
%assign FUNCTION_WRITE_STDOUT_PTR FUNCTION_POINTER_TABLE + 48
;; Clang-compiled libbboeos exports (Phase 3+). Sorted
;; alphabetically — and stays that way until the cc.py extern-call
;; fallback ships and the first program with a baked-in
;; FUNCTION_<name>_PTR offset gets written to disk. After that
;; the block becomes append-only (same ABI contract as the
;; legacy block above) because reordering would shift offsets
;; under existing on-disk bin/* binaries. Until then, treat
;; new entries like a freely-reorderable sorted list — insert
;; in alphabetical position and renumber accordingly. Order
;; must match the LONG()s after the legacy block in
;; user/libbboeos/libbboeos.ld.
%assign FUNCTION_STRCMP_PTR FUNCTION_POINTER_TABLE + 52
%assign IPPROTO_ICMP 1 ; Protocol argument to net_open for SOCK_DGRAM ICMP sockets
%assign IPPROTO_UDP 17 ; Protocol argument to net_open for SOCK_DGRAM UDP sockets
%assign KERNEL_VIRT_BASE 0FF800000h ; Lowest kernel-virt address. User pointers + lengths must stay strictly below this; idt.asm's user-fault triage and access_ok both gate on it. Equals USER_STACK_TOP and DIRECT_MAP_BASE — all three move in lockstep.
Expand Down Expand Up @@ -280,7 +292,7 @@
%assign USER_DATA_SELECTOR 23h ; GDT[4] | RPL=3: ring-3 data segment (flat 4 GB)
%assign USER_STACK_TOP 0FF800000h ; Ring-3 stack top (one past last user-virt page); 64 KB stack at 0xFF7F0000-0xFF800000, 64 KB guard at 0xFF7E0000-0xFF7F0000. Top sits exactly at the user/kernel boundary so ESP=USER_STACK_TOP can push 4 B into [0xFF7FFFFC, 0xFF800000) without crossing into the kernel half.
%assign VDSO_PAGE_COUNT_MAX 4 ; Compile-time ceiling on how many 4 KB pages the kernel will map for the shared libbboeos image starting at FUNCTION_TABLE. vdso_install reads `lib/libbboeos` at boot and rounds up to ceil(size / 4096); this constant sizes the per-page phys-frame array (vdso_code_phys) and bounds the per-program map loop in build_child_program_state. Bumping it costs (4 * VDSO_PAGE_COUNT_MAX) bytes of kernel BSS.
%assign VDSO_SIGRETURN_OFFSET 0460h ; offset within the vDSO page (FUNCTION_TABLE) of the __kernel_sigreturn trampoline that ends every signal handler — `mov ah, SYS_SYS_SIGRETURN; int 30h`.
%assign VDSO_SIGRETURN_OFFSET 0FE0h ; offset within the vDSO page (FUNCTION_TABLE) of the __kernel_sigreturn trampoline that ends every signal handler — `mov ah, SYS_SYS_SIGRETURN; int 30h`. Anchored near the end of page 0 (past the pointer table at 0x800..0x83C) so libbboeos.text can grow well past 0x460 as clang-compiled exports accumulate.

;; PIT constants used by entry.asm's IRQ 0 hookup and rtc.c's
;; PIT-driven sleep / tick counter. PIC_EOI lives above with
Expand Down
7 changes: 6 additions & 1 deletion make_os.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@ done
# anchor; objcopy -O binary flattens the linked ELF into the on-disk
# blob.
mkdir -p build
make -C user/libbboeos libbboeos.a >/dev/null || exit 1
nasm -f elf32 -i kernel/include/ -o build/libbboeos.o user/vdso/vdso.asm || exit 1
# --gc-sections drops every clang-compiled libbboeos function the
# pointer-table LONG()s don't reference, so the blob pays only for
# what it actually exports.
ld -m elf_i386 -T user/libbboeos/libbboeos.ld -Map=build/libbboeos.map \
-o build/libbboeos.elf build/libbboeos.o || exit 1
--gc-sections -o build/libbboeos.elf \
build/libbboeos.o user/libbboeos/libbboeos.a || exit 1
objcopy -O binary build/libbboeos.elf build/libbboeos || exit 1

# Two-pass build: assemble kernel.bin first, measure its sector count,
Expand Down
1 change: 1 addition & 0 deletions user/libbboeos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ CC := clang # force clang — `?=` would lose to Make's built-in CC=cc
CFLAGS := --target=i386-pc-none-elf -m32 -march=i386 -mno-mmx -mno-sse -mno-sse2 \
-mno-implicit-float -fno-vectorize -fno-slp-vectorize \
-ffreestanding -fno-pic -fno-stack-protector \
-ffunction-sections -fdata-sections \
-nostdlib -nostdinc -O2 -Wall -Wextra -Werror -Iinclude
C_SRCS := builtins.c ctype.c dirent.c errno.c math.c signal.c stdio.c stdlib.c string.c syscall.c
OBJS = $(C_SRCS:.c=.o) $(S_SRCS:.S=.o)
Expand Down
54 changes: 39 additions & 15 deletions user/libbboeos/libbboeos.ld
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,47 @@
* 0x10046 .libbboeos.text shared_* helper bodies (ported
* from src/lib/{proc,print}.asm).
* ... .libbboeos.rodata print_datetime_month_lengths.
* 0x10460 .libbboeos.sigreturn __kernel_sigreturn trampoline
* 0x10FE0 .libbboeos.sigreturn __kernel_sigreturn trampoline
* (matches VDSO_SIGRETURN_OFFSET).
* 0x10800 .libbboeos.pointer_table FUNCTION_POINTER_TABLE — 13
* absolute LONG(shared_*) entries
* the linker resolves at link
* time, replacing the previous
* gen_libbboeos_pointers.py +
* python-concat dance.
* 0x10800 .libbboeos.pointer_table FUNCTION_POINTER_TABLE. 13
* legacy LONG(shared_*) entries
* + a growing tail of clang-
* compiled libbboeos exports.
* Entry order MUST match the
* FUNCTION_*_PTR offsets in
* kernel/include/constants.asm.
*
* Future libbboeos C bodies (Phase 3+) land in .libbboeos.text, growing
* the helper region until it bumps into the 0x10460 sigreturn anchor.
* objcopy -O binary flattens the linked ELF into build/libbboeos, which
* Clang-compiled libbboeos C bodies (string.c, etc.) land in
* .libbboeos.text via `*(.text .text.*)`; -ffunction-sections + ld
* --gc-sections drop any function the LONG()s below don't reference,
* so only what the blob actually exports gets paid for. objcopy -O
* binary flattens the linked ELF into build/libbboeos, which
* make_os.sh adds to the disk image as `lib/libbboeos`. */

ENTRY(function_table)

/* Force ld to pull these archive members in (and seed --gc-sections).
* Without EXTERN, the LONG() references inside SECTIONS aren't enough
* to trigger archive resolution. */
EXTERN(strcmp)

SECTIONS {
. = 0x00010000;

.libbboeos.function_table : { KEEP(*(.libbboeos.function_table)) }
.libbboeos.text : { *(.libbboeos.text) }
.libbboeos.rodata : { *(.libbboeos.rodata) }

. = 0x00010460;
.libbboeos.sigreturn : { KEEP(*(.libbboeos.sigreturn)) }
.libbboeos.text : {
*(.libbboeos.text)
*(.text .text.*)
}
.libbboeos.rodata : {
*(.libbboeos.rodata)
*(.rodata .rodata.*)
}

. = 0x00010800;
.libbboeos.pointer_table : {
/* Legacy vDSO helpers (asm). Order pinned by FUNCTION_*_PTR in
* kernel/include/constants.asm — entries here align 1:1. */
LONG(shared_die);
LONG(shared_exit);
LONG(shared_get_character);
Expand All @@ -51,8 +64,19 @@ SECTIONS {
LONG(shared_print_string);
LONG(shared_printf);
LONG(shared_write_stdout);
/* Clang-compiled libbboeos exports. Sorted alphabetically.
* Stays freely-reorderable until the cc.py extern-call fallback
* ships and the first on-disk bin/* program bakes in an
* offset; from then on the block becomes append-only. Until
* then, insert new entries in alphabetical position and update
* the matching FUNCTION_<name>_PTR offsets in
* kernel/include/constants.asm together. */
LONG(strcmp);
}

. = 0x00010FE0;
.libbboeos.sigreturn : { KEEP(*(.libbboeos.sigreturn)) }

/DISCARD/ : {
*(.note*)
*(.comment)
Expand Down