| git.druid.rocks | index | druid520 | kaboom | src/ | user/ | crt.s |
src/user/crt.s
/*
* userspace runtime shim, linked into every program under src/user/:
* a _start that matches what elf_call_entry (kernel side) actually
* does (argc/argv arrive in rdi/rsi, same as any ordinary call -- NOT
* a real os process entry, so no environ/auxv/stack setup happens
* here) and calls main(argc, argv), then ret's with main's return
* value still in %rax -- that's the exit code, as far as anything
* exists to call it that: there's no separate exit syscall, the
* kernel's elf_call_entry model is "call it like a function", so
* returning IS exiting.
*
* nscc's own -s/freestanding mode was deliberately NOT used for this
* (see kmain.nsc's note on the same choice for the kernel itself) --
* -s emits a _start that ends in a hardcoded linux/netbsd exit
* syscall, which doesn't exist in kaboom's syscall table and wouldn't
* match this calling convention (return, not trap-to-exit) even if
* it did.
*/
.section .text
.global _start
.type _start, @function
_start:
call main
ret
/*
* syscall wrappers: nsc can't do `int $0x80` itself (no inline asm),
* so every userspace program needs these, same reasoning as every
* other "nsc needs something only asm can do" gap in this kernel.
* kaboom's syscall convention (number in rax, args in rdi/rsi/rdx)
* happens to put the first three args in exactly the same registers
* the sysv c calling convention already put them in for a 3-arg
* function, so every wrapper here is just "set rax, trap, return" --
* no register shuffling needed at all.
*/
.global sys_debug_print
.type sys_debug_print, @function
sys_debug_print:
movq $1, %rax
int $0x80
ret
.global sys_write
.type sys_write, @function
sys_write:
movq $2, %rax
int $0x80
ret
.global sys_read
.type sys_read, @function
sys_read:
movq $3, %rax
int $0x80
ret
.global sys_open
.type sys_open, @function
sys_open:
movq $4, %rax
int $0x80
ret
.global sys_close
.type sys_close, @function
sys_close:
movq $5, %rax
int $0x80
ret
.global sys_listdir
.type sys_listdir, @function
sys_listdir:
movq $6, %rax
int $0x80
ret
/* exec takes 4 args -- sysv c calling convention puts the 4th in
* %rcx, but kaboom's syscall convention (matching real x86-64
* syscall's own register layout for familiarity, even though the
* actual entry mechanism here is int, not syscall) expects it in
* %r10, so this one wrapper actually needs a real move first. */
.global sys_exec
.type sys_exec, @function
sys_exec:
movq %rcx, %r10
movq $7, %rax
int $0x80
ret
.global sys_klog_read
.type sys_klog_read, @function
sys_klog_read:
movq $8, %rax
int $0x80
ret
.global sys_mkdir
.type sys_mkdir, @function
sys_mkdir:
movq $9, %rax
int $0x80
ret
.global sys_rmdir
.type sys_rmdir, @function
sys_rmdir:
movq $10, %rax
int $0x80
ret
.global sys_rm
.type sys_rm, @function
sys_rm:
movq $11, %rax
int $0x80
ret
.global sys_cd
.type sys_cd, @function
sys_cd:
movq $12, %rax
int $0x80
ret
.global sys_pwd
.type sys_pwd, @function
sys_pwd:
movq $13, %rax
int $0x80
ret
.global sys_info
.type sys_info, @function
sys_info:
movq $14, %rax
int $0x80
ret
/* 4 args, same reasoning as sys_exec: sysv puts the 4th in %rcx,
* kaboom's convention expects it in %r10. */
.global sys_writefile
.type sys_writefile, @function
sys_writefile:
movq %rcx, %r10
movq $15, %rax
int $0x80
ret
.global sys_vga_clear
.type sys_vga_clear, @function
sys_vga_clear:
movq $16, %rax
int $0x80
ret
.global sys_chmod
.type sys_chmod, @function
sys_chmod:
movq $17, %rax
int $0x80
ret
.global sys_alloc
.type sys_alloc, @function
sys_alloc:
movq $18, %rax
int $0x80
ret
.global sys_free
.type sys_free, @function
sys_free:
movq $19, %rax
int $0x80
ret
.global sys_stat
.type sys_stat, @function
sys_stat:
movq $20, %rax
int $0x80
ret
/* 4 args, same reasoning as sys_exec/sys_writefile. */
.global sys_listdir_path
.type sys_listdir_path, @function
sys_listdir_path:
movq %rcx, %r10
movq $21, %rax
int $0x80
ret
.global sys_date
.type sys_date, @function
sys_date:
movq $22, %rax
int $0x80
ret
.global sys_errno
.type sys_errno, @function
sys_errno:
movq $23, %rax
int $0x80
ret
.global sys_getperm
.type sys_getperm, @function
sys_getperm:
movq $24, %rax
int $0x80
ret
.global sys_fsize
.type sys_fsize, @function
sys_fsize:
movq $25, %rax
int $0x80
ret
.global sys_ino
.type sys_ino, @function
sys_ino:
movq $26, %rax
int $0x80
ret