From 5c7febbbf0de9ca0d3f02efb50a2688f14b17d75 Mon Sep 17 00:00:00 2001 From: slinky55 Date: Sun, 12 Jul 2026 20:13:13 -0500 Subject: [PATCH] shell can launch another user processgit add .git add .! --- build_programs.sh | 6 + compile_commands.json | 436 ++++++++++++++-------------- kernel/process.h | 3 + kernel/scheduler.c | 9 + kernel/scheduler.h | 1 + kernel/syscall.c | 20 +- programs/lib/rlibc.a | Bin 4470 -> 4542 bytes programs/rocksh/main.c | 23 ++ programs/test/compile_commands.json | 36 +++ programs/test/crt0.S | 21 ++ programs/test/linker.ld | 31 ++ programs/test/main.c | 6 + programs/test/makefile | 23 ++ rocklibc/include/syscall.h | 4 +- rocklibc/src/syscall.c | 4 + 15 files changed, 403 insertions(+), 220 deletions(-) create mode 100644 programs/test/compile_commands.json create mode 100644 programs/test/crt0.S create mode 100644 programs/test/linker.ld create mode 100644 programs/test/main.c create mode 100644 programs/test/makefile diff --git a/build_programs.sh b/build_programs.sh index 46d98e7..ef3803a 100755 --- a/build_programs.sh +++ b/build_programs.sh @@ -20,4 +20,10 @@ bear -- make cp vga_text_term.elf ../bin cd .. +cd test +make clean +bear -- make +cp test.elf ../bin +cd .. + cd .. \ No newline at end of file diff --git a/compile_commands.json b/compile_commands.json index a2afb42..3e32c19 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -26,12 +26,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/vfs.c.o", - "kernel/vfs.c" + "obj/kernel/kbd.c.o", + "kernel/kbd.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/vfs.c", - "output": "/home/slinky/source/RockOS/obj/kernel/vfs.c.o" + "file": "/home/slinky/source/RockOS/kernel/kbd.c", + "output": "/home/slinky/source/RockOS/obj/kernel/kbd.c.o" }, { "arguments": [ @@ -43,12 +43,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/kmain.c.o", - "kernel/kmain.c" + "obj/kernel/gdt.c.o", + "kernel/gdt.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/kmain.c", - "output": "/home/slinky/source/RockOS/obj/kernel/kmain.c.o" + "file": "/home/slinky/source/RockOS/kernel/gdt.c", + "output": "/home/slinky/source/RockOS/obj/kernel/gdt.c.o" }, { "arguments": [ @@ -67,91 +67,6 @@ "file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c", "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.c.o" }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/devfs/devfs.c.o", - "kernel/drivers/devfs/devfs.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/devfs/devfs.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/devfs/devfs.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/cpio/cpio.c.o", - "kernel/drivers/cpio/cpio.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/cpio/cpio.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/cpio/cpio.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/pty/pty.c.o", - "kernel/drivers/pty/pty.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/pty/pty.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pty/pty.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/vga/vga.c.o", - "kernel/drivers/vga/vga.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/ide/ide.c.o", - "kernel/drivers/ide/ide.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/ide/ide.c", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ide/ide.c.o" - }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -196,12 +111,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/gdt.c.o", - "kernel/gdt.c" + "obj/kernel/drivers/ide/ide.c.o", + "kernel/drivers/ide/ide.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/gdt.c", - "output": "/home/slinky/source/RockOS/obj/kernel/gdt.c.o" + "file": "/home/slinky/source/RockOS/kernel/drivers/ide/ide.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/ide/ide.c.o" }, { "arguments": [ @@ -213,12 +128,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/memory/mm.c.o", - "kernel/memory/mm.c" + "obj/kernel/drivers/vga/vga.c.o", + "kernel/drivers/vga/vga.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/memory/mm.c", - "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.c.o" + "file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga.c.o" }, { "arguments": [ @@ -230,12 +145,80 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/kbd.c.o", - "kernel/kbd.c" + "obj/kernel/drivers/cpio/cpio.c.o", + "kernel/drivers/cpio/cpio.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/kbd.c", - "output": "/home/slinky/source/RockOS/obj/kernel/kbd.c.o" + "file": "/home/slinky/source/RockOS/kernel/drivers/cpio/cpio.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/cpio/cpio.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/devfs/devfs.c.o", + "kernel/drivers/devfs/devfs.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/devfs/devfs.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/devfs/devfs.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/drivers/pty/pty.c.o", + "kernel/drivers/pty/pty.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/drivers/pty/pty.c", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pty/pty.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/scheduler.c.o", + "kernel/scheduler.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/scheduler.c", + "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/elf.c.o", + "kernel/elf.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/elf.c", + "output": "/home/slinky/source/RockOS/obj/kernel/elf.c.o" }, { "arguments": [ @@ -271,23 +254,6 @@ "file": "/home/slinky/source/RockOS/kernel/interrupts.c", "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.c.o" }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/elf.c.o", - "kernel/elf.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/elf.c", - "output": "/home/slinky/source/RockOS/obj/kernel/elf.c.o" - }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -315,63 +281,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/lib/stream.c.o", - "kernel/lib/stream.c" + "obj/kernel/kmain.c.o", + "kernel/kmain.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/stream.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/stream.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/lib/memory.c.o", - "kernel/lib/memory.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/memory.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/memory.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/lib/print.c.o", - "kernel/lib/print.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/print.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/print.c.o" - }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/lib/ringbuf.c.o", - "kernel/lib/ringbuf.c" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/lib/ringbuf.c", - "output": "/home/slinky/source/RockOS/obj/kernel/lib/ringbuf.c.o" + "file": "/home/slinky/source/RockOS/kernel/kmain.c", + "output": "/home/slinky/source/RockOS/obj/kernel/kmain.c.o" }, { "arguments": [ @@ -390,6 +305,40 @@ "file": "/home/slinky/source/RockOS/kernel/lib/tasks.c", "output": "/home/slinky/source/RockOS/obj/kernel/lib/tasks.c.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/lib/ringbuf.c.o", + "kernel/lib/ringbuf.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/lib/ringbuf.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/ringbuf.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/lib/stream.c.o", + "kernel/lib/stream.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/lib/stream.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/stream.c.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -417,12 +366,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/scheduler.c.o", - "kernel/scheduler.c" + "obj/kernel/lib/print.c.o", + "kernel/lib/print.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/scheduler.c", - "output": "/home/slinky/source/RockOS/obj/kernel/scheduler.c.o" + "file": "/home/slinky/source/RockOS/kernel/lib/print.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/print.c.o" }, { "arguments": [ @@ -434,12 +383,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/syscall.S.o", - "kernel/syscall.S" + "obj/kernel/lib/memory.c.o", + "kernel/lib/memory.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/syscall.S", - "output": "/home/slinky/source/RockOS/obj/kernel/syscall.S.o" + "file": "/home/slinky/source/RockOS/kernel/lib/memory.c", + "output": "/home/slinky/source/RockOS/obj/kernel/lib/memory.c.o" }, { "arguments": [ @@ -451,12 +400,29 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/common.S.o", - "kernel/common.S" + "obj/kernel/vfs.c.o", + "kernel/vfs.c" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/common.S", - "output": "/home/slinky/source/RockOS/obj/kernel/common.S.o" + "file": "/home/slinky/source/RockOS/kernel/vfs.c", + "output": "/home/slinky/source/RockOS/obj/kernel/vfs.c.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/memory/mm.c.o", + "kernel/memory/mm.c" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/memory/mm.c", + "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.c.o" }, { "arguments": [ @@ -475,23 +441,6 @@ "file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.S", "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.S.o" }, - { - "arguments": [ - "/home/slinky/opt/cross/bin/i686-elf-gcc", - "-c", - "-ffreestanding", - "-O2", - "-Wall", - "-Wextra", - "-Ikernel", - "-o", - "obj/kernel/drivers/pit/pit.S.o", - "kernel/drivers/pit/pit.S" - ], - "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S", - "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o" - }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -519,12 +468,46 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/memory/mm.S.o", - "kernel/memory/mm.S" + "obj/kernel/drivers/pit/pit.S.o", + "kernel/drivers/pit/pit.S" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/memory/mm.S", - "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.S.o" + "file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S", + "output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/syscall.S.o", + "kernel/syscall.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/syscall.S", + "output": "/home/slinky/source/RockOS/obj/kernel/syscall.S.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/interrupts.S.o", + "kernel/interrupts.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/interrupts.S", + "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.S.o" }, { "arguments": [ @@ -543,6 +526,23 @@ "file": "/home/slinky/source/RockOS/kernel/boot/boot.S", "output": "/home/slinky/source/RockOS/obj/kernel/boot/boot.S.o" }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-c", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-Ikernel", + "-o", + "obj/kernel/common.S.o", + "kernel/common.S" + ], + "directory": "/home/slinky/source/RockOS", + "file": "/home/slinky/source/RockOS/kernel/common.S", + "output": "/home/slinky/source/RockOS/obj/kernel/common.S.o" + }, { "arguments": [ "/home/slinky/opt/cross/bin/i686-elf-gcc", @@ -570,12 +570,12 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/gdt.S.o", - "kernel/gdt.S" + "obj/kernel/memory/mm.S.o", + "kernel/memory/mm.S" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/gdt.S", - "output": "/home/slinky/source/RockOS/obj/kernel/gdt.S.o" + "file": "/home/slinky/source/RockOS/kernel/memory/mm.S", + "output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.S.o" }, { "arguments": [ @@ -587,11 +587,11 @@ "-Wextra", "-Ikernel", "-o", - "obj/kernel/interrupts.S.o", - "kernel/interrupts.S" + "obj/kernel/gdt.S.o", + "kernel/gdt.S" ], "directory": "/home/slinky/source/RockOS", - "file": "/home/slinky/source/RockOS/kernel/interrupts.S", - "output": "/home/slinky/source/RockOS/obj/kernel/interrupts.S.o" + "file": "/home/slinky/source/RockOS/kernel/gdt.S", + "output": "/home/slinky/source/RockOS/obj/kernel/gdt.S.o" } ] diff --git a/kernel/process.h b/kernel/process.h index 153d380..b815226 100644 --- a/kernel/process.h +++ b/kernel/process.h @@ -12,6 +12,7 @@ typedef enum { STATE_SLEEPING = 2, STATE_BLOCKED = 3, STATE_DEAD = 4, + STATE_ZOMBIE = 5, } process_state_t; typedef enum { @@ -32,6 +33,8 @@ typedef struct process_t { uint32_t flags; file_t* fd_table[MAX_PROCESS_FDS]; struct process_t* sched_next; + struct process_t* waiting; + int exit_status; } __attribute__((packed)) process_t; #endif \ No newline at end of file diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 287061e..25bde99 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -186,4 +186,13 @@ void wake(process_t* task) { if (task->state == STATE_SLEEPING || task->state == STATE_BLOCKED) { task->state = STATE_READY; } +} + +process_t* get_task_by_pid(uint32_t pid) { + process_t* cur = process_table; + while (cur) { + if (cur->pid == pid) break; + cur = cur->sched_next; + } + return cur; } \ No newline at end of file diff --git a/kernel/scheduler.h b/kernel/scheduler.h index d9fab39..dc76995 100644 --- a/kernel/scheduler.h +++ b/kernel/scheduler.h @@ -11,6 +11,7 @@ void init_scheduler(); void init_task(process_t* process, uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp); process_t* current_task(); +process_t* get_task_by_pid(uint32_t pid); int get_next_pid(); void add_task(process_t* task); diff --git a/kernel/syscall.c b/kernel/syscall.c index eaac410..f12ce07 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -25,7 +25,11 @@ typedef struct registers { static int32_t sys_exit(int status) { process_t* task = current_task(); - task->state = STATE_DEAD; + task->state = STATE_ZOMBIE; + task->exit_status = status; + if (task->waiting) { + wake(task->waiting); + } exit(); return 0; } @@ -163,6 +167,9 @@ static int32_t sys_exec(registers_t* regs, const char* prgm) { clear_current_pd(); uint32_t eip = load_elf_program(prgm); + if (eip == 0) { + return 0; + } uint32_t stack_sz = PAGE_SIZE * 16; uint32_t stack_top = 0xBFFF0000; @@ -204,6 +211,16 @@ static int32_t sys_lseek(int fd, size_t offset, int whence) { return 1; } +static int32_t sys_waitpid(int pid, int* exit_status) { + process_t* current = current_task(); + process_t* child = get_task_by_pid(pid); + current->state = STATE_BLOCKED; + child->waiting = current; + yield(); + *exit_status = child->exit_status; + return 1; +} + void syscall(registers_t* regs) { int32_t ret; switch(regs->eax) { @@ -218,6 +235,7 @@ void syscall(registers_t* regs) { case 22: ret = sys_exec(regs, (const char*)regs->ebx); break; case 23: ret = sys_dup2(regs->ebx, regs->ecx); break; case 24: ret = sys_lseek(regs->ebx, regs->ecx, regs->edx); break; + case 25: ret = sys_waitpid(regs->ebx, (int*)regs->ecx); break; default: ret = -1; } regs->eax = ret; diff --git a/programs/lib/rlibc.a b/programs/lib/rlibc.a index b58cefa5276d4d289300669d16429a417c4412d9..f55aebb7bb51dd303d8317a18af3fdd49e66a4d2 100644 GIT binary patch delta 1764 zcma)6eN0FF6}3hhu(=~%TM{uK zDq%z5K*AmI-BP0rEwdk-Fg%)9v{IR6xoD`cCnFIFA*{hxvoLBKTJToM;Y!VGPh|qs zSWBxxGTGrpKl1h~Ql#plO3*!YROFUx*S@HVXY&y`tebX;5&iZwChE{Z-f5(5s7ouNYVA-@<@osS! zfn}7w`LX-p?`xYz}Yrj}IMLWA%S*tiC0<3yhEz7JmIO6e(`SvGDmdx|m3 zhmebT$mL7lm>Oj974&ifEulVat#P=utURmW1wZB4d z-cBSE%2jdYEO>LBv?E!awvMO~Wr7QeYU{}Gf-v+EF7wwS z(r4-Q6aIPw1DZmhgNHIeu_Y+8O7t=`S&IkHBM^IszTR;cMq=u{swWa#K(kKDSlZeY zi9L?U$@e^ti%INxX3&2Wc_DTYW8~>rJK8dzj@ENaUh7cfNfH@=x)JMUs4Nb?v&y~f zh3~|^jE3yKl`Y$!o^KKRA=*fDV`HsU-u$e`Dao6k%h|l0^c}d6_Xrrq?9pL6npu=i{Dp z?>XoG-nsAV+Qpj0mVuUCO^waXE|M0_Glp(LI&)l1Y{2#VoA;f;A z|5X2LXWu5M`Y(TU{PLq(SH26$Y-juwc&K6eFl5pPC$d%8z(Mp++?B?CH z5n8QoIBniv+KxSy5lR|RpQVJn2qWfCxHeo}g>P-ObOHXbi73CZFzK_4)CNvYq%k7G zmR*emhn_At|HR&0{F!WAx<46xBAoj;L**Ns-;8l-hIJF*@$+F8c-~rS;5i0mHXmfn zA?UUU27+}4f_(;peFlPk3_xLSG-krwBy1`ue@sI#g(p^VWbd0M;R z(GGSh%Xa79sd!{Mc4+4<@1t|~;*nH5IH7giro-w##yMxwq=jxPuA4O0o>8Zj->G** zo})`+R-%k<@9I7o8ZnTB$)eXC&ZM7e7wIKk{tON{wg&uo?Xiy3j-^>GIIcxf*V!N8 z!4E5$j5HICq)50-(zWvhA6T^2O4MQbZ+b_0XgS(>nm%}($z+sKVeb9>ki(~rdK!W| zj=HKtYZ+8Y?@bgWNS}jBzUsM;v5=%2eiKn|V&XAO{PNMY#Ob^6D(|96i15`7A7DZ@ zPV(Lx9z2Py_9A@g6uJ!*hE}~Dsq`M0;49tZ>2B;Wfm_w(^jqw_@!GXh3({hjI&T1j zZ?CFY>g{1Ojy#R3kk|7S##ili&L&vSeSZILSKYqD!FrdJec<!~kp zmH26W8>aaUU3p@~7*!(Mk=u|NodKU9nnW|`mU4Jk5U2?62_njCC_V5q$}hoMDw<+u dXtTTNhtOFn(pDHK6)VnQyT`L>49S3C^e?fk>DmAQ diff --git a/programs/rocksh/main.c b/programs/rocksh/main.c index 940da0c..825e782 100644 --- a/programs/rocksh/main.c +++ b/programs/rocksh/main.c @@ -1,3 +1,4 @@ +#include "syscall.h" #include #include #include @@ -7,6 +8,10 @@ const char* shell_prompt = "rocksh> "; char buf[256]; size_t buf_offset = 0; +char path[256]; + +const char* bin_dir = "/bin/"; + void parse_cmd() { if (strcmp(buf, "exit") == 0) { printf("bye!\n"); @@ -15,7 +20,25 @@ void parse_cmd() { if (strcmp(buf, "motd") == 0) { printf("rockos is the best!\n"); + return; } + + // need a strcat + char* dst = path; + strcpy(dst, bin_dir); + dst = path + strlen(bin_dir); + strcpy(dst, buf); + + int pid = fork(); + if (pid == 0) { + if (!exec(path)) { + return; + } + } + + int status; + waitpid(pid, &status); + printf("process exited with status %d\n", status); } void reset() { diff --git a/programs/test/compile_commands.json b/programs/test/compile_commands.json new file mode 100644 index 0000000..63209b9 --- /dev/null +++ b/programs/test/compile_commands.json @@ -0,0 +1,36 @@ +[ + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-I../../rocklibc/include", + "-c", + "-o", + "crt0.o", + "crt0.S" + ], + "directory": "/home/slinky/source/RockOS/programs/test", + "file": "/home/slinky/source/RockOS/programs/test/crt0.S", + "output": "/home/slinky/source/RockOS/programs/test/crt0.o" + }, + { + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-I../../rocklibc/include", + "-c", + "-o", + "main.o", + "main.c" + ], + "directory": "/home/slinky/source/RockOS/programs/test", + "file": "/home/slinky/source/RockOS/programs/test/main.c", + "output": "/home/slinky/source/RockOS/programs/test/main.o" + } +] diff --git a/programs/test/crt0.S b/programs/test/crt0.S new file mode 100644 index 0000000..d97f158 --- /dev/null +++ b/programs/test/crt0.S @@ -0,0 +1,21 @@ +.global _start +.extern exit +.section .text +_start: + xor %ebp, %ebp + + mov (%esp), %eax + lea 4(%esp), %ebx + lea 8(%esp,%eax,4), %ecx + + and $-16, %esp + + push %ecx + push %ebx + push %eax + + call main + + push %eax + call exit + diff --git a/programs/test/linker.ld b/programs/test/linker.ld new file mode 100644 index 0000000..03d6e3c --- /dev/null +++ b/programs/test/linker.ld @@ -0,0 +1,31 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0x40000000; + + .text ALIGN(4K) : + { + /* Force the crt0.o entry code to be placed FIRST in memory */ + KEEP(*crt0.o(.text)) + *(.text .text.*) + } + + .rodata ALIGN(4K) : + { + *(.rodata .rodata.*) + } + + .data ALIGN(4K) : + { + *(.data .data.*) + } + + .bss ALIGN(4K) : + { + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + } +} \ No newline at end of file diff --git a/programs/test/main.c b/programs/test/main.c new file mode 100644 index 0000000..cf4c43c --- /dev/null +++ b/programs/test/main.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char** argv) { + printf("hello, world!\n"); + return 0; +} \ No newline at end of file diff --git a/programs/test/makefile b/programs/test/makefile new file mode 100644 index 0000000..cca7c29 --- /dev/null +++ b/programs/test/makefile @@ -0,0 +1,23 @@ +CC = i686-elf-gcc +LD = i686-elf-ld + +CFLAGS = -ffreestanding -O2 -Wall -Wextra -I../../rocklibc/include +LDFLAGS = -m elf_i386 -nostdlib + +TARGET = test.elf + +all: $(TARGET) + +crt0.o: crt0.S + $(CC) $(CFLAGS) -c crt0.S -o crt0.o + +main.o: main.c + $(CC) $(CFLAGS) -c main.c -o main.o + +$(TARGET): crt0.o main.o ../lib/rlibc.a + $(LD) $(LDFLAGS) -T linker.ld crt0.o main.o ../lib/rlibc.a -o $(TARGET) + +clean: + rm -f *.o $(TARGET) + +.PHONY: all clean test \ No newline at end of file diff --git a/rocklibc/include/syscall.h b/rocklibc/include/syscall.h index 88fac70..65fe48d 100644 --- a/rocklibc/include/syscall.h +++ b/rocklibc/include/syscall.h @@ -13,7 +13,8 @@ #define SYS_FORK 21 #define SYS_EXEC 22 #define SYS_DUP2 23 -#define SYS_LSEEK 24 +#define SYS_LSEEK 24 +#define SYS_WAIT 25 int open(const char* path); int write(int fd, const void *buf, size_t count); @@ -32,5 +33,6 @@ int pty(int* slave); int fork(); int exec(const char* path); int dup2(int src, int dst); +int waitpid(int pid, int* status); #endif \ No newline at end of file diff --git a/rocklibc/src/syscall.c b/rocklibc/src/syscall.c index a7c05d9..e2b3063 100644 --- a/rocklibc/src/syscall.c +++ b/rocklibc/src/syscall.c @@ -61,4 +61,8 @@ int exec(const char* path) { int dup2(int src, int dst) { return syscall3(SYS_DUP2, src, dst, 0); +} + +int waitpid(int pid, int* status) { + return syscall3(SYS_WAIT, pid, (uint32_t)status, 0); } \ No newline at end of file