From ed3f9410a617d907bca6be7c24c4994ca54c2f0e Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 24 Mar 2019 13:44:25 -0700 Subject: [PATCH] Make nulldrv a small C++ program --- assets/initrd.toml | 4 +- modules.yaml | 3 +- scripts/templates/build.ninja.j2 | 2 +- scripts/templates/target.user.j2 | 49 +++++++++++++ src/drivers/nulldrv/main.cpp | 23 ++++++- src/drivers/nulldrv/main.s | 115 +++++++++++++++---------------- src/kernel/apic.cpp | 1 + src/kernel/syscall.cpp | 4 +- 8 files changed, 134 insertions(+), 67 deletions(-) create mode 100644 scripts/templates/target.user.j2 diff --git a/assets/initrd.toml b/assets/initrd.toml index 876430b..499a5c1 100644 --- a/assets/initrd.toml +++ b/assets/initrd.toml @@ -14,10 +14,10 @@ source = "../assets/fonts/tamsyn8x16r.psf" [[files]] dest = "nulldrv1" -source = "host/nulldrv" +source = "user/nulldrv" executable = true [[files]] dest = "nulldrv2" -source = "host/nulldrv" +source = "user/nulldrv" executable = true diff --git a/modules.yaml b/modules.yaml index ffc3342..aa296dc 100644 --- a/modules.yaml +++ b/modules.yaml @@ -56,9 +56,10 @@ boot: nulldrv: kind: exe - target: host + target: user output: nulldrv source: + - src/drivers/nulldrv/main.cpp - src/drivers/nulldrv/main.s elf: diff --git a/scripts/templates/build.ninja.j2 b/scripts/templates/build.ninja.j2 index e2ee594..1e33c76 100644 --- a/scripts/templates/build.ninja.j2 +++ b/scripts/templates/build.ninja.j2 @@ -179,7 +179,7 @@ build $builddir/fatroot/efi/boot/bootx64.efi : cp $builddir/boot/boot.efi build $builddir/fatroot/initrd.img : makerd ${srcroot}/assets/initrd.toml | $ ${builddir}/native/makerd $ - ${builddir}/host/nulldrv + ${builddir}/user/nulldrv build $builddir/popcorn.img : makefat | $ $builddir/fatroot/initrd.img $ diff --git a/scripts/templates/target.user.j2 b/scripts/templates/target.user.j2 new file mode 100644 index 0000000..a31e8dd --- /dev/null +++ b/scripts/templates/target.user.j2 @@ -0,0 +1,49 @@ +{% extends "target.default.j2" %} + +{% block binaries %} +cc = ${srcroot}/sysroot/bin/clang +cxx = ${srcroot}/sysroot/bin/clang++ +ld = ${srcroot}/sysroot/bin/x86_64-elf-ld +ar = ${srcroot}/sysroot/bin/x86_64-elf-ar +nasm = ${srcroot}/sysroot/bin/nasm +objcopy = ${srcroot}/sysroot/bin/x86_64-elf-objcopy +{% endblock %} + +{% block variables %} + +ccflags = $ccflags $ + -nostdlib $ + -nodefaultlibs $ + -fno-builtin $ + -mno-sse $ + -fno-omit-frame-pointer $ + -mno-red-zone $ + -g $ + -mcmodel=large $ + -D__ELF__ $ + -D__POPCORN__ $ + -isystem${srcroot}/sysroot/include $ + --sysroot="${srcroot}/sysroot" + +cxxflags = $cxxflags $ + -fno-exceptions $ + -fno-rtti $ + -isystem${srcroot}/sysroot/include/c++/v1 + +ldflags = $ldflags $ + -g $ + -nostdlib $ + -znocombreloc $ + -Bsymbolic $ + -nostartfiles $ + -Bstatic $ + --sysroot="${srcroot}/sysroot" $ + -L "${srcroot}/sysroot/lib" $ + +libs = $libs $ + -lc + +{% endblock %} + +# vim: ft=ninja et ts=4 sts=4 sw=4 + diff --git a/src/drivers/nulldrv/main.cpp b/src/drivers/nulldrv/main.cpp index 60d7ba6..54100d6 100644 --- a/src/drivers/nulldrv/main.cpp +++ b/src/drivers/nulldrv/main.cpp @@ -1 +1,22 @@ -int main(int argc, const char **argv) { return 0; } +#include +#include + +extern "C" { + int32_t getpid(); + void sleep(uint64_t til); + void debug(); + + int main(int, const char **); +} + + +int +main(int argc, const char **argv) +{ + int32_t pid = getpid(); + debug(); + for (int i = 1; i < 5; ++i) + sleep(i*10); + debug(); + return 0; +} diff --git a/src/drivers/nulldrv/main.s b/src/drivers/nulldrv/main.s index 3106842..b5e8254 100644 --- a/src/drivers/nulldrv/main.s +++ b/src/drivers/nulldrv/main.s @@ -1,68 +1,63 @@ section .bss -mypid: resq 1 -mychild: resq 1 +mymessage: + resq 1024 + +extern main section .text +global getpid +getpid: + push rbp + mov rbp, rsp + + mov rax, 5 ; getpid syscall + syscall ; pid is now already in rax, so just return + + pop rbp + ret + +global debug +debug: + push rbp + mov rbp, rsp + + mov rax, 1 ; debug syscall + syscall + + pop rbp + ret + +global sleep +sleep: + push rbp + mov rbp, rsp + + mov rax, 4 ; sleep syscall + syscall + + pop rbp + ret + + +__localexit: + push rbp + mov rbp, rsp + + mov rax, 9 ; exit syscall + syscall + jmp __localexit ; shouldn't get here + + global _start _start: xor rbp, rbp ; Sentinel rbp + push rbp + push rbp + mov rbp, rsp - mov rax, 5 ; GETPID syscall - syscall ; int 0xee - mov [mypid], rax + mov rdi, 0 + mov rsi, 0 + call main - mov rax, 8 ; FORK syscall - syscall ; int 0xee - mov [mychild], rax - - mov r12, [mypid] - mov r13, [mychild] - mov rax, 1 ; DEBUG syscall - syscall ; int 0xee - - cmp r13, 0 - je .doexit - - cmp r12, 1 - je .dosend - jne .doreceive - -.preloop: - mov r11, 0 ; counter - mov rbx, 20 ; sleep timeout - -.loop: - mov rax, 1 ; MESSAGE syscall - ;mov rax, 0 ; NOOP syscall - ;syscall - syscall ; int 0xee - - inc r11 - cmp r11, 2 - - jle .loop - - mov rax, 4 ; SLEEP syscall - ; syscall - syscall ; int 0xee - - add rbx, 20 - - mov r11, 0 - jmp .loop - -.dosend: - mov rax, 6 ; SEND syscall - mov rdi, 2 ; target is pid 2 - syscall ; int 0xee - jmp .preloop - -.doreceive: - mov rax, 7 ; RECEIVE syscall - mov rdi, 1 ; source is pid 2 - syscall ; int 0xee - jmp .preloop - -.doexit: - mov rax, 9 ; EXIT syscall - syscall + mov rdi, rax + call __localexit diff --git a/src/kernel/apic.cpp b/src/kernel/apic.cpp index 617cc83..6803550 100644 --- a/src/kernel/apic.cpp +++ b/src/kernel/apic.cpp @@ -46,6 +46,7 @@ apic::apic(uint32_t *base) : lapic::lapic(uint32_t *base, isr spurious) : apic(base) { + // TODO: This causes a "reserved" page fault under KVM apic_write(m_base, 0xf0, static_cast(spurious)); log::info(logs::apic, "LAPIC created, base %lx", m_base); } diff --git a/src/kernel/syscall.cpp b/src/kernel/syscall.cpp index 71bf6a6..bcee5b3 100644 --- a/src/kernel/syscall.cpp +++ b/src/kernel/syscall.cpp @@ -79,10 +79,10 @@ syscall_dispatch(uintptr_t return_rsp, cpu_state ®s) { cons->set_color(11); cons->printf("\nProcess %d: Received SLEEP syscall\n", p->pid); - cons->printf("Sleeping until %lu\n", regs.rbx); + cons->printf("Sleeping until %lu\n", regs.rdi); cons->set_color(); - p->wait_on_time(regs.rbx); + p->wait_on_time(regs.rdi); return_rsp = s.schedule(return_rsp); } break;