feat: hello-world user-mode app loaded from initrd via VFS

- Created apps/hello-world/hello-world.S: AT&T assembly user program that
  calls SYS_WRITE to print 'Hello, World' then SYS_EXIT(0)
- Created apps/user.ld: linker script for user apps at 0x08048000
- Created scripts/build_apps.sh: builds each app dir into flat binary
- Updated CMakeLists.txt: added apps build target in ISO pipeline
- Updated gen_initrd.sh: packs built binaries from build/apps_bin/
- Updated kernel.c: replaced inline machine code with VFS-based loading
  of hello-world from /initrd/hello-world via cpio_find()

Verified: hello-world binary (49 bytes) loads from CPIO initrd,
prints 'Hello, World', and exits with code 0.
This commit is contained in:
AI
2026-02-23 12:30:36 +00:00
parent 0c5aa72fd3
commit a6e6e3d8ca
6 changed files with 141 additions and 63 deletions

49
scripts/build_apps.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/sh
# Build all user-mode applications as flat binaries.
# Usage: build_apps.sh <apps_dir> <output_dir>
# Each app directory in <apps_dir>/ gets compiled and its flat binary
# is placed in <output_dir>/.
set -e
APPS_DIR="$1"
OUTPUT_DIR="$2"
LINKER_SCRIPT="$APPS_DIR/user.ld"
CC="${CC:-clang}"
OBJCOPY="${OBJCOPY:-objcopy}"
CFLAGS="-ffreestanding -m32 -fno-pie -fno-pic -fno-builtin -fno-stack-protector -mno-sse -mno-mmx -O2 -Wall"
LDFLAGS="-m32 -nostdlib -no-pie -Wl,--no-dynamic-linker"
mkdir -p "$OUTPUT_DIR"
for app_dir in "$APPS_DIR"/*/; do
[ -d "$app_dir" ] || continue
app_name=$(basename "$app_dir")
echo "Building app: $app_name"
# Collect source files
OBJ_FILES=""
for src in "$app_dir"*.S "$app_dir"*.c; do
[ -f "$src" ] || continue
obj="$OUTPUT_DIR/${app_name}_$(basename "${src%.*}").o"
$CC $CFLAGS -c "$src" -o "$obj"
OBJ_FILES="$OBJ_FILES $obj"
done
if [ -z "$OBJ_FILES" ]; then
echo " No sources found, skipping"
continue
fi
# Link into ELF
elf="$OUTPUT_DIR/$app_name.elf"
$CC $LDFLAGS -T "$LINKER_SCRIPT" $OBJ_FILES -o "$elf"
# Convert to flat binary (strip non-code sections)
bin="$OUTPUT_DIR/$app_name"
$OBJCOPY -O binary --only-section=.text --only-section=.rodata --only-section=.data "$elf" "$bin"
size=$(wc -c < "$bin")
echo " Built: $bin ($size bytes)"
done

View File

@@ -1,14 +1,16 @@
#!/bin/sh
# Generate CPIO initial ramdisk from apps directory
# Usage: gen_initrd.sh <apps_dir> <output_file>
# Generate CPIO initial ramdisk from built application binaries.
# Usage: gen_initrd.sh <binaries_dir> <output_file>
# Packs all files in <binaries_dir> into a newc-format CPIO archive.
set -e
APPS_DIR="$1"
BIN_DIR="$1"
OUTPUT="$2"
# Ensure output directory exists
mkdir -p "$(dirname "$OUTPUT")"
cd "$APPS_DIR"
find . -not -name '.' | cpio -o -H newc > "$OUTPUT" 2>/dev/null
cd "$BIN_DIR"
# Only pack actual binary files (no .o, .elf intermediates)
find . -maxdepth 1 -type f ! -name '*.o' ! -name '*.elf' | cpio -o -H newc > "$OUTPUT" 2>/dev/null
echo "Generated initrd: $(wc -c < "$OUTPUT") bytes"