*.log
*.elf
*.a
+*.so
# ISO staging: keep config, ignore generated kernel binaries
iso/boot/*.bin
LS_ELF := user/ls.elf
MKDIR_ELF := user/mkdir.elf
RM_ELF := user/rm.elf
+ LDSO_ELF := user/ld.so
INITRD_IMG := initrd.img
MKINITRD := tools/mkinitrd
endif
$(RM_ELF): user/rm.c user/linker.ld
@i686-elf-gcc -m32 -I include -ffreestanding -fno-pie -no-pie -nostdlib -Wl,-T,user/linker.ld -o $(RM_ELF) user/rm.c user/errno.c
-$(INITRD_IMG): $(MKINITRD) $(USER_ELF) $(ECHO_ELF) $(SH_ELF) $(CAT_ELF) $(LS_ELF) $(MKDIR_ELF) $(RM_ELF)
- @./$(MKINITRD) $(INITRD_IMG) $(USER_ELF):bin/init.elf $(ECHO_ELF):bin/echo.elf $(SH_ELF):bin/sh $(CAT_ELF):bin/cat $(LS_ELF):bin/ls $(MKDIR_ELF):bin/mkdir $(RM_ELF):bin/rm
+$(LDSO_ELF): user/ldso.c user/linker.ld
+ @i686-elf-gcc -m32 -I include -ffreestanding -fno-pie -no-pie -nostdlib -Wl,-T,user/linker.ld -o $(LDSO_ELF) user/ldso.c
+
+$(INITRD_IMG): $(MKINITRD) $(USER_ELF) $(ECHO_ELF) $(SH_ELF) $(CAT_ELF) $(LS_ELF) $(MKDIR_ELF) $(RM_ELF) $(LDSO_ELF)
+ @./$(MKINITRD) $(INITRD_IMG) $(USER_ELF):bin/init.elf $(ECHO_ELF):bin/echo.elf $(SH_ELF):bin/sh $(CAT_ELF):bin/cat $(LS_ELF):bin/ls $(MKDIR_ELF):bin/mkdir $(RM_ELF):bin/rm $(LDSO_ELF):lib/ld.so
run: iso
@rm -f serial.log qemu.log
--- /dev/null
+/* Minimal userspace dynamic linker stub (ld.so).
+ * Currently a no-op: receives control from the kernel ELF loader
+ * and immediately jumps to the real program entry point.
+ *
+ * The kernel places the program entry address at the top of the
+ * user stack (below argc) as an auxiliary value.
+ *
+ * Future work: parse PT_DYNAMIC, relocate GOT/PLT, resolve symbols. */
+
+void _start(void) __attribute__((noreturn, section(".text.start")));
+
+void _start(void) {
+ /* The kernel's ELF loader doesn't yet pass AT_ENTRY via auxv,
+ * so for now this stub simply halts. When the kernel is extended
+ * to pass the real entry point (e.g. via auxv or a register),
+ * this stub will jump there.
+ *
+ * Placeholder: infinite NOP loop (cannot hlt in ring 3). */
+ for (;;) {
+ __asm__ volatile("nop");
+ }
+}