C userspace programs
This commit is contained in:
14
Makefile
14
Makefile
@ -1,10 +1,15 @@
|
|||||||
.PHONY: clean prepare cleanall iso base kernel user test
|
.PHONY: clean prepare cleanall iso base kernel user test
|
||||||
|
|
||||||
|
ARCH ?= x86_64
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
make -C kernel ROOT=$(PWD) all
|
make -C kernel ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
user:
|
user:
|
||||||
make -C user ROOT=$(PWD) all
|
make -C user ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
|
ulib:
|
||||||
|
make -C ulib ARCH=$(ARCH) ROOT=$(PWD) all
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
if [ ! -d limine ]; then \
|
if [ ! -d limine ]; then \
|
||||||
@ -18,8 +23,9 @@ cleanall:
|
|||||||
rm -rf limine
|
rm -rf limine
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C kernel ROOT=$(PWD) clean
|
make -C kernel ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
make -C user ROOT=$(PWD) clean
|
make -C user ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
|
make -C ulib ARCH=$(ARCH) ROOT=$(PWD) clean
|
||||||
rm -f mop2.iso base.img
|
rm -f mop2.iso base.img
|
||||||
|
|
||||||
base:
|
base:
|
||||||
|
@ -2,14 +2,14 @@ include $(ROOT)/mk/grabsrc.mk
|
|||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
ARCH ?= x86_64
|
|
||||||
PUTCHAR_ ?= fb
|
PUTCHAR_ ?= fb
|
||||||
|
|
||||||
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
||||||
|
|
||||||
CFLAGS += -I. \
|
CFLAGS += -I. \
|
||||||
-I$(ROOT)/limine \
|
-I$(ROOT)/limine \
|
||||||
-I./std/include \
|
-I$(ROOT)/std/include \
|
||||||
|
-I./std \
|
||||||
-I./flanterm/src \
|
-I./flanterm/src \
|
||||||
-DPRINTF_INCLUDE_CONFIG_H=1 \
|
-DPRINTF_INCLUDE_CONFIG_H=1 \
|
||||||
-DLFS_NO_ASSERT \
|
-DLFS_NO_ASSERT \
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
CC := x86_64-elf-gcc
|
include $(ROOT)/mk/arch/toolchain-x86_64.mk
|
||||||
LD := x86_64-elf-ld
|
|
||||||
|
|
||||||
CFLAGS += -m64 \
|
CFLAGS += -m64 \
|
||||||
-fPIE \
|
-fPIE \
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#include "hal/hal.h"
|
#include "hal/hal.h"
|
||||||
#include "bootinfo/bootinfo.h"
|
#include "bootinfo/bootinfo.h"
|
||||||
|
|
||||||
LocalCpuData HAL_CPUS[HAL_CPUS_MAX];
|
|
||||||
|
|
||||||
uint64_t hal_cpu_rdmsr(uint32_t id) {
|
uint64_t hal_cpu_rdmsr(uint32_t id) {
|
||||||
uint32_t lo, hi;
|
uint32_t lo, hi;
|
||||||
asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(id));
|
asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(id));
|
||||||
@ -21,8 +19,3 @@ uint64_t hal_cpu_wrmsr(uint32_t id, uint64_t val) {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_cpu_init(uint32_t cpu) {
|
|
||||||
void *addr = pmm_alloc(16) + (16 * HAL_PAGE_SIZE);
|
|
||||||
HAL_CPUS[cpu].syscall_kstack = (uint64_t *)VIRT(addr);
|
|
||||||
HAL_CPUS[cpu].kcr3 = hal_vmm_current_cr3();
|
|
||||||
}
|
|
||||||
|
@ -13,24 +13,13 @@
|
|||||||
#define HAL_CPU_STAR 0xC0000081
|
#define HAL_CPU_STAR 0xC0000081
|
||||||
#define HAL_CPU_LSTAR 0xC0000082
|
#define HAL_CPU_LSTAR 0xC0000082
|
||||||
#define HAL_CPU_CSTAR 0xC0000083
|
#define HAL_CPU_CSTAR 0xC0000083
|
||||||
#define HAL_CPU_SFMASK 0xC0000084
|
#define HAL_CPU_FMASK 0xC0000084
|
||||||
|
|
||||||
#define HAL_CPU_FSBASE 0xC0000100
|
#define HAL_CPU_FSBASE 0xC0000100
|
||||||
#define HAL_CPU_GSBASE 0xC0000101
|
#define HAL_CPU_GSBASE 0xC0000101
|
||||||
#define HAL_CPU_KGSBASE 0xC0000102
|
#define HAL_CPU_KGSBASE 0xC0000102
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t *syscall_kstack;
|
|
||||||
uint64_t *syscall_ustack;
|
|
||||||
PgTable *kcr3;
|
|
||||||
PgTable *pcr3;
|
|
||||||
IntrStackFrame *frame;
|
|
||||||
} PACKED LocalCpuData;
|
|
||||||
|
|
||||||
uint64_t hal_cpu_rdmsr(uint32_t id);
|
uint64_t hal_cpu_rdmsr(uint32_t id);
|
||||||
uint64_t hal_cpu_wrmsr(uint32_t id, uint64_t val);
|
uint64_t hal_cpu_wrmsr(uint32_t id, uint64_t val);
|
||||||
void hal_cpu_init(uint32_t cpu);
|
|
||||||
|
|
||||||
extern LocalCpuData HAL_CPUS[HAL_CPUS_MAX];
|
|
||||||
|
|
||||||
#endif // HAL_CPU_H_
|
#endif // HAL_CPU_H_
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
#include "syscall.h"
|
|
||||||
|
|
||||||
void hal_init(void) {
|
void hal_init(void) {
|
||||||
if (!serial_init()) {
|
if (!serial_init()) {
|
||||||
@ -33,7 +32,6 @@ void hal_init_withmalloc(void) {
|
|||||||
pit_init();
|
pit_init();
|
||||||
ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER);
|
ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER);
|
||||||
hal_intr_disable();
|
hal_intr_disable();
|
||||||
hal_syscall_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_wait(uint32_t ms) {
|
void hal_wait(uint32_t ms) {
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
#include "proc/proc.h"
|
#include "proc/proc.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
void hal_intr_disable(void) {
|
void hal_intr_disable(void) {
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
@ -122,6 +124,9 @@ void intr_init(void) {
|
|||||||
MKINTR(45, 0);
|
MKINTR(45, 0);
|
||||||
MKINTR(46, 0);
|
MKINTR(46, 0);
|
||||||
MKINTR(47, 0);
|
MKINTR(47, 0);
|
||||||
|
|
||||||
|
extern void intr_vec128(void);
|
||||||
|
idt_setentry(0x80, (uint64_t)&intr_vec128, 0, 0xEE);
|
||||||
|
|
||||||
idt_init();
|
idt_init();
|
||||||
}
|
}
|
||||||
@ -149,14 +154,33 @@ void intr_dumpframe(IntrStackFrame *frame) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hal_syscalldispatch(IntrStackFrame *frame) {
|
||||||
|
uint64_t sysnum = frame->regs.rax;
|
||||||
|
if (sysnum < SYSCALLS_MAX) {
|
||||||
|
SyscallFn fn = SYSCALL_TABLE[sysnum];
|
||||||
|
if (fn == NULL) {
|
||||||
|
frame->regs.rax = E_BADSYSCALL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int32_t ret = fn(frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
|
||||||
|
frame->regs.r10, frame->regs.r8, frame->regs.r9);
|
||||||
|
|
||||||
|
if (sysnum == SYS_QUITPROC) {
|
||||||
|
proc_sched((void *)frame);
|
||||||
|
}
|
||||||
|
frame->regs.rax = *(uint64_t *)&ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void intr_handleintr(IntrStackFrame *frame) {
|
void intr_handleintr(IntrStackFrame *frame) {
|
||||||
if (frame->trapnum <= 31) {
|
if (frame->trapnum <= 31) {
|
||||||
|
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
|
||||||
|
intr_dumpframe(frame);
|
||||||
if (frame->trapnum == 14 && frame->errnum & 0x4) {
|
if (frame->trapnum == 14 && frame->errnum & 0x4) {
|
||||||
|
kprintf("killed pid %ld %s\n", PROCS.current->pid, PROCS.current->name);
|
||||||
proc_killself();
|
proc_killself();
|
||||||
proc_sched((void *)frame);
|
proc_sched((void *)frame);
|
||||||
}
|
}
|
||||||
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
|
|
||||||
intr_dumpframe(frame);
|
|
||||||
hal_hang();
|
hal_hang();
|
||||||
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
|
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
|
||||||
if (frame->trapnum == INTR_TIMER) {
|
if (frame->trapnum == INTR_TIMER) {
|
||||||
@ -167,6 +191,8 @@ void intr_handleintr(IntrStackFrame *frame) {
|
|||||||
lapic_write(LAPIC_EOI, 0x00);
|
lapic_write(LAPIC_EOI, 0x00);
|
||||||
|
|
||||||
proc_sched((void *)frame);
|
proc_sched((void *)frame);
|
||||||
|
} else if (frame->trapnum == 0x80) {
|
||||||
|
hal_syscalldispatch(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
.global intr_vec45
|
.global intr_vec45
|
||||||
.global intr_vec46
|
.global intr_vec46
|
||||||
.global intr_vec47
|
.global intr_vec47
|
||||||
|
.global intr_vec128
|
||||||
|
|
||||||
.macro _vecintr_errorcode_present_save num
|
.macro _vecintr_errorcode_present_save num
|
||||||
pushq $\num
|
pushq $\num
|
||||||
@ -215,3 +216,6 @@ intr_vec46:
|
|||||||
intr_vec47:
|
intr_vec47:
|
||||||
_vecintr_plain_save 47
|
_vecintr_plain_save 47
|
||||||
_vecintr_bodygen
|
_vecintr_bodygen
|
||||||
|
intr_vec128:
|
||||||
|
_vecintr_plain_save 128
|
||||||
|
_vecintr_bodygen
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include "syscall.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "intr.h"
|
|
||||||
#include "syscall/syscall.h"
|
|
||||||
#include "proc/proc.h"
|
|
||||||
#include "kprintf.h"
|
|
||||||
#include "errors.h"
|
|
||||||
|
|
||||||
extern void hal_enable_syscallentry(void);
|
|
||||||
extern void hal_syscallentry(void);
|
|
||||||
|
|
||||||
void hal_syscalldispatch(IntrStackFrame *frame) {
|
|
||||||
uint64_t sysnum = frame->regs.rax;
|
|
||||||
if (sysnum < SYSCALLS_MAX) {
|
|
||||||
SyscallFn fn = SYSCALL_TABLE[sysnum];
|
|
||||||
if (fn == NULL) {
|
|
||||||
frame->regs.rax = E_BADSYSCALL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int32_t ret = fn(frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
|
|
||||||
frame->regs.r10, frame->regs.r8, frame->regs.r9);
|
|
||||||
|
|
||||||
if (sysnum == SYS_QUITPROC) {
|
|
||||||
proc_sched((void *)frame);
|
|
||||||
}
|
|
||||||
frame->regs.rax = *(uint64_t *)&ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_syscall_init(void) {
|
|
||||||
hal_cpu_init(0);
|
|
||||||
LocalCpuData *lcd = &HAL_CPUS[0];
|
|
||||||
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_EFER, hal_cpu_rdmsr(HAL_CPU_EFER) | 0x1);
|
|
||||||
hal_enable_syscallentry();
|
|
||||||
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_GSBASE, (uint64_t)lcd);
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_KGSBASE, (uint64_t)lcd);
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_SFMASK, (uint64_t)0);
|
|
||||||
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_LSTAR, (uint64_t)&hal_syscallentry);
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef HAL_SYSCALL_H_
|
|
||||||
#define HAL_SYSCALL_H_
|
|
||||||
|
|
||||||
void hal_syscall_init(void);
|
|
||||||
|
|
||||||
#endif // HAL_SYSCALL_H_
|
|
@ -1,48 +0,0 @@
|
|||||||
#include "regs.S"
|
|
||||||
|
|
||||||
.extern hal_syscalldispatch
|
|
||||||
|
|
||||||
.global hal_enable_syscallentry
|
|
||||||
hal_enable_syscallentry:
|
|
||||||
movq $0xC0000080, %rcx
|
|
||||||
rdmsr
|
|
||||||
or $0x1, %eax
|
|
||||||
wrmsr
|
|
||||||
movq $0xC0000081, %rcx
|
|
||||||
rdmsr
|
|
||||||
movl $0x180008, %edx
|
|
||||||
wrmsr
|
|
||||||
ret
|
|
||||||
|
|
||||||
.global hal_syscallentry
|
|
||||||
hal_syscallentry:
|
|
||||||
cli
|
|
||||||
swapgs
|
|
||||||
|
|
||||||
movq %rsp, %gs:0x8
|
|
||||||
movq %gs:0x0, %rsp
|
|
||||||
|
|
||||||
pushq $0x23
|
|
||||||
pushq %gs:0x8
|
|
||||||
|
|
||||||
swapgs
|
|
||||||
|
|
||||||
pushq %r11
|
|
||||||
pushq $0x1b
|
|
||||||
pushq %rcx
|
|
||||||
|
|
||||||
_push_regs
|
|
||||||
|
|
||||||
mov %rsp, %rdi
|
|
||||||
mov $0x0, %rbp
|
|
||||||
|
|
||||||
call hal_syscalldispatch
|
|
||||||
cli
|
|
||||||
|
|
||||||
_pop_regs
|
|
||||||
|
|
||||||
popq %rcx
|
|
||||||
add $0x8, %rsp
|
|
||||||
popq %r11
|
|
||||||
popq %rsp
|
|
||||||
sysret
|
|
@ -155,7 +155,7 @@ Proc *proc_spawnuser(char *mountpoint, char *path) {
|
|||||||
ElfAuxval aux = proc_load_elf_segs(proc, data);
|
ElfAuxval aux = proc_load_elf_segs(proc, data);
|
||||||
|
|
||||||
proc->platformdata.trapframe.ss = 0x20 | 0x3;
|
proc->platformdata.trapframe.ss = 0x20 | 0x3;
|
||||||
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(sp);
|
proc->platformdata.trapframe.rsp = (uint64_t)sp;
|
||||||
proc->platformdata.trapframe.rflags = 0x202;
|
proc->platformdata.trapframe.rflags = 0x202;
|
||||||
proc->platformdata.trapframe.cs = 0x18 | 0x3;
|
proc->platformdata.trapframe.cs = 0x18 | 0x3;
|
||||||
proc->platformdata.trapframe.rip = aux.entry;
|
proc->platformdata.trapframe.rip = aux.entry;
|
||||||
@ -231,13 +231,10 @@ void proc_sched(void *cpustate) {
|
|||||||
IntrStackFrame *frame = cpustate;
|
IntrStackFrame *frame = cpustate;
|
||||||
|
|
||||||
PROCS.current->platformdata.trapframe = *frame;
|
PROCS.current->platformdata.trapframe = *frame;
|
||||||
PROCS.current->platformdata.fsbase = hal_cpu_rdmsr(HAL_CPU_FSBASE);
|
|
||||||
|
|
||||||
PROCS.current = proc_nextready();
|
PROCS.current = proc_nextready();
|
||||||
PROCS.current->state = PROC_RUNNING;
|
PROCS.current->state = PROC_RUNNING;
|
||||||
|
|
||||||
hal_cpu_wrmsr(HAL_CPU_FSBASE, PROCS.current->platformdata.fsbase);
|
|
||||||
HAL_CPUS[0].syscall_kstack = VIRT(PROCS.current->platformdata.kstack);
|
|
||||||
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,8 +279,8 @@ void proc_init(void) {
|
|||||||
proc_register(idle);
|
proc_register(idle);
|
||||||
PROCS.current = idle;
|
PROCS.current = idle;
|
||||||
|
|
||||||
proc_register(proc_spawnkern(&proc_status, "status"));
|
/* proc_register(proc_spawnkern(&proc_status, "status")); */
|
||||||
proc_register(proc_spawnuser("base", "/bin/hello"));
|
proc_register(proc_spawnuser("base", "/bin/init"));
|
||||||
|
|
||||||
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
hal_switchproc(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#define PROC_MAX 0x100 // max amount of processes
|
#define PROC_MAX 0x100 // max amount of processes
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t fsbase;
|
|
||||||
IntrStackFrame trapframe;
|
IntrStackFrame trapframe;
|
||||||
uint8_t *kstack;
|
uint8_t *kstack;
|
||||||
PgTable *cr3;
|
PgTable *cr3;
|
||||||
|
@ -5,14 +5,9 @@
|
|||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "proc/proc.h"
|
#include "proc/proc.h"
|
||||||
|
|
||||||
int32_t SYSCALL2(sys_debugprint, string1, len) {
|
int32_t SYSCALL1(sys_debugprint, string) {
|
||||||
char *buf = dlmalloc(len);
|
char *p = (char *)string;
|
||||||
if (buf == NULL) {
|
kprintf("%s\n", p);
|
||||||
return E_NOMEMORY;
|
|
||||||
}
|
|
||||||
ksnprintf(buf, len, "%s", string1);
|
|
||||||
kprintf("%s\n", buf);
|
|
||||||
dlfree(buf);
|
|
||||||
return E_OK;
|
return E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
mk/arch/toolchain-x86_64.mk
Normal file
3
mk/arch/toolchain-x86_64.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
CC := x86_64-elf-gcc
|
||||||
|
LD := x86_64-elf-ld
|
||||||
|
AR := x86_64-elf-ar
|
13
mk/user/x86_64.mk
Normal file
13
mk/user/x86_64.mk
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
CFLAGS += -m64 \
|
||||||
|
-fPIE \
|
||||||
|
-mno-80387 \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-sse \
|
||||||
|
-nostartfiles \
|
||||||
|
-nostdlib \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mno-red-zone \
|
||||||
|
-fno-stack-protector \
|
||||||
|
-fno-stack-check \
|
||||||
|
-fno-builtin \
|
||||||
|
-Os \
|
@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
make -B kernel && make -B user && make base && make iso
|
make -B kernel && make -B ulib && make -B user && make base && make iso
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#define atomic_compare_exchange_strong(p, old, new) \
|
#define atomic_compare_exchange_strong(p, old, new) \
|
||||||
__atomic_compare_exchange_n(p, old, new, false, memory_order_relaxed, memory_order_relaxed)
|
__atomic_compare_exchange_n(p, old, new, false, memory_order_relaxed, memory_order_relaxed)
|
||||||
|
|
||||||
#define atomic_bool volatile bool
|
#define atomic_bool _Atomic(bool)
|
||||||
|
|
||||||
#endif
|
#endif
|
1
ulib/.gitignore
vendored
Normal file
1
ulib/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.o
|
33
ulib/Makefile
Normal file
33
ulib/Makefile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
include $(ROOT)/mk/grabsrc.mk
|
||||||
|
include $(ROOT)/mk/arch/toolchain-$(ARCH).mk
|
||||||
|
include $(ROOT)/mk/user/$(ARCH).mk
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
SRCFILES := $(call GRABSRC, \
|
||||||
|
. \
|
||||||
|
syscall \
|
||||||
|
string \
|
||||||
|
system \
|
||||||
|
)
|
||||||
|
|
||||||
|
CFLAGS += -isystem $(ROOT)/ulib -isystem $(ROOT)/std/include
|
||||||
|
|
||||||
|
ASFILES := $(call GET_ASFILES, $(SRCFILES))
|
||||||
|
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||||
|
OBJ := $(call GET_OBJ, $(SRCFILES))
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
libulib.a: $(OBJ)
|
||||||
|
$(AR) rcs libulib.a $(OBJ)
|
||||||
|
|
||||||
|
all: libulib.a
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ)
|
||||||
|
rm -f libulib.a
|
22
ulib/_premain.c
Normal file
22
ulib/_premain.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
extern void main(void);
|
||||||
|
|
||||||
|
extern uint8_t _bss_start[];
|
||||||
|
extern uint8_t _bss_end[];
|
||||||
|
|
||||||
|
void bss_clear(void) {
|
||||||
|
uint8_t *p = _bss_start;
|
||||||
|
while (p != _bss_end) {
|
||||||
|
*p = 0;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ulib initialization goes here
|
||||||
|
void _premain(void) {
|
||||||
|
bss_clear();
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
10
ulib/_start.S
Normal file
10
ulib/_start.S
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <syscall/syscall.h>
|
||||||
|
|
||||||
|
.extern _premain
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
call _premain
|
||||||
|
|
||||||
|
mov $SYS_QUITPROC, %rax
|
||||||
|
int $0x80
|
BIN
ulib/libulib.a
Normal file
BIN
ulib/libulib.a
Normal file
Binary file not shown.
11
ulib/string/string.c
Normal file
11
ulib/string/string.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <string/string.h>
|
||||||
|
|
||||||
|
size_t string_len(const char *s) {
|
||||||
|
size_t l = 0;
|
||||||
|
while (*s != '\0') {
|
||||||
|
l++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
8
ulib/string/string.h
Normal file
8
ulib/string/string.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef ULIB_STRING_STRING_H_
|
||||||
|
#define ULIB_STRING_STRING_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
size_t string_len(const char *s);
|
||||||
|
|
||||||
|
#endif // ULIB_STRING_STRING_H_
|
27
ulib/syscall/syscall.c
Normal file
27
ulib/syscall/syscall.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint64_t syscall(uint64_t num, uint64_t arg1, uint64_t arg2,
|
||||||
|
uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6) {
|
||||||
|
uint64_t ret = 0;
|
||||||
|
asm volatile (
|
||||||
|
"mov %[SYSNUM], %%rax\n"
|
||||||
|
"mov %[ARG1], %%rdi\n"
|
||||||
|
"mov %[ARG2], %%rsi\n"
|
||||||
|
"mov %[ARG3], %%rdx\n"
|
||||||
|
"mov %[ARG4], %%r10\n"
|
||||||
|
"mov %[ARG5], %%r8\n"
|
||||||
|
"mov %[ARG6], %%r9\n"
|
||||||
|
"int $0x80\n"
|
||||||
|
"mov %%rax, %[RESULT]\n"
|
||||||
|
: [RESULT]"=r"(ret)
|
||||||
|
: [SYSNUM]"r"(num),
|
||||||
|
[ARG1]"r"(arg1),
|
||||||
|
[ARG2]"r"(arg2),
|
||||||
|
[ARG3]"r"(arg3),
|
||||||
|
[ARG4]"r"(arg4),
|
||||||
|
[ARG5]"r"(arg5),
|
||||||
|
[ARG6]"r"(arg6)
|
||||||
|
: "%rax", "%rdi", "%rsi", "%rdx", "%r10", "%r8", "%r9", "memory"
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
|
}
|
14
ulib/syscall/syscall.h
Normal file
14
ulib/syscall/syscall.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef ULIB_SYSCALL_SYSCALL_H_
|
||||||
|
#define ULIB_SYSCALL_SYSCALL_H_
|
||||||
|
|
||||||
|
#define SYS_DEBUGPRINT 1
|
||||||
|
#define SYS_QUITPROC 2
|
||||||
|
|
||||||
|
#if !defined(__ASSEMBLER__)
|
||||||
|
|
||||||
|
uint64_t syscall(uint64_t num, uint64_t arg1, uint64_t arg2,
|
||||||
|
uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6);
|
||||||
|
|
||||||
|
#endif // ! __ASSEMBLER__
|
||||||
|
|
||||||
|
#endif // ULIB_SYSCALL_SYSCALL_H_
|
9
ulib/system/system.c
Normal file
9
ulib/system/system.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <system/system.h>
|
||||||
|
#include <syscall/syscall.h>
|
||||||
|
|
||||||
|
|
||||||
|
void sys_debugprint(const char *string) {
|
||||||
|
syscall(SYS_DEBUGPRINT, (uint64_t)string, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
6
ulib/system/system.h
Normal file
6
ulib/system/system.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ULIB_SYSTEM_SYSTEM_H_
|
||||||
|
#define ULIB_SYSTEM_SYSTEM_H_
|
||||||
|
|
||||||
|
void sys_debugprint(const char *string);
|
||||||
|
|
||||||
|
#endif // ULIB_SYSTEM_SYSTEM_H_
|
@ -1,6 +1,5 @@
|
|||||||
ARCH ?= x86_64
|
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc \
|
||||||
|
-isystem $(ROOT)/std/include -isystem $(ROOT)/ulib
|
||||||
CFLAGS := -ffreestanding -Wall -Wextra -g -fcommon -nostdinc
|
|
||||||
|
|
||||||
CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x0000000000000000;
|
/* . = 0x0000000000000000; */
|
||||||
|
|
||||||
.rodata ALIGN(4K):
|
|
||||||
{
|
|
||||||
*(.rodata .rodata.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
.text ALIGN(4K):
|
.text ALIGN(4K):
|
||||||
{
|
{
|
||||||
*(.text .text.*)
|
*(.text .text.*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rodata (READONLY): ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
.data ALIGN(4K):
|
.data ALIGN(4K):
|
||||||
{
|
{
|
||||||
@ -20,6 +20,8 @@ SECTIONS {
|
|||||||
|
|
||||||
.bss ALIGN(4K):
|
.bss ALIGN(4K):
|
||||||
{
|
{
|
||||||
|
_bss_start = .;
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
|
_bss_end = .;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,5 @@
|
|||||||
CC := x86_64-elf-gcc
|
include $(ROOT)/mk/user/x86_64.mk
|
||||||
LD := x86_64-elf-ld
|
include $(ROOT)/mk/arch/toolchain-x86_64.mk
|
||||||
|
|
||||||
CFLAGS += -m64 \
|
|
||||||
-fPIE \
|
|
||||||
-mno-80387 \
|
|
||||||
-mno-mmx \
|
|
||||||
-mno-sse \
|
|
||||||
-nostartfiles \
|
|
||||||
-nostdlib \
|
|
||||||
-mno-sse2 \
|
|
||||||
-mno-red-zone \
|
|
||||||
-fno-stack-protector \
|
|
||||||
-fno-stack-check \
|
|
||||||
-Os \
|
|
||||||
|
|
||||||
LDFLAGS += -m elf_x86_64 \
|
LDFLAGS += -m elf_x86_64 \
|
||||||
-pie \
|
-pie \
|
||||||
|
@ -14,9 +14,9 @@ OBJ := $(call GET_OBJ, $(SRCFILES))
|
|||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
hello: $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
$(LD) $^ $(LDFLAGS) -o $@
|
$(LD) $^ $(LDFLAGS) -o $@
|
||||||
echo $(realpath hello) >> $(FILES)
|
echo $$(realpath $(TARGET)) >> $(FILES)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) $(TARGET)
|
rm -f $(OBJ) $(TARGET)
|
||||||
|
@ -11,8 +11,7 @@ _start:
|
|||||||
movq $1, %rax
|
movq $1, %rax
|
||||||
lea STRING(%rip), %rdi
|
lea STRING(%rip), %rdi
|
||||||
lea STRING_LEN(%rip), %rsi
|
lea STRING_LEN(%rip), %rsi
|
||||||
syscall
|
int $0x80
|
||||||
|
|
||||||
movq $2, %rax
|
movq $2, %rax
|
||||||
syscall
|
int $0x80
|
||||||
|
|
||||||
|
2
user/init/.gitignore
vendored
Normal file
2
user/init/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
init
|
24
user/init/Makefile
Normal file
24
user/init/Makefile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
include $(ROOT)/mk/grabsrc.mk
|
||||||
|
include ../Makefile.inc
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
TARGET := init
|
||||||
|
|
||||||
|
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
|
||||||
|
|
||||||
|
SRCFILES := $(call GRABSRC, .)
|
||||||
|
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||||
|
OBJ := $(call GET_OBJ, $(SRCFILES))
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
$(LD) $^ $(LDFLAGS) -o $@
|
||||||
|
echo $$(realpath $(TARGET)) >> $(FILES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(TARGET)
|
6
user/init/main.c
Normal file
6
user/init/main.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <system/system.h>
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
sys_debugprint("Hello world from userspace in C");
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user