[kernel] Improve process init

Move process init from each process needing a main.s with _start to
crt0.s in libc. Also change to a sysv-like initial stack with a
j6-specific array of initialization values after the program arguments.
This commit is contained in:
2020-12-31 00:57:51 -08:00
committed by Justin C. Miller
parent a8024d3dd3
commit 7fcb4efab6
8 changed files with 148 additions and 71 deletions

View File

@@ -84,7 +84,6 @@ modules:
source: source:
- src/drivers/nulldrv/io.cpp - src/drivers/nulldrv/io.cpp
- src/drivers/nulldrv/main.cpp - src/drivers/nulldrv/main.cpp
- src/drivers/nulldrv/main.s
- src/drivers/nulldrv/serial.cpp - src/drivers/nulldrv/serial.cpp
fb: fb:
@@ -95,7 +94,6 @@ modules:
- libc - libc
source: source:
- src/drivers/fb/main.cpp - src/drivers/fb/main.cpp
- src/drivers/fb/main.s
kutil: kutil:
kind: lib kind: lib
@@ -132,6 +130,8 @@ modules:
#- LACKS_TIME_H #- LACKS_TIME_H
source: source:
- src/libraries/libc/arch/x86_64/_Exit.s - src/libraries/libc/arch/x86_64/_Exit.s
- src/libraries/libc/arch/x86_64/crt0.s
- src/libraries/libc/arch/x86_64/init_libc.c
- src/libraries/libc/arch/x86_64/syscalls.s - src/libraries/libc/arch/x86_64/syscalls.s
- src/libraries/libc/ctype/isalnum.c - src/libraries/libc/ctype/isalnum.c
- src/libraries/libc/ctype/isalpha.c - src/libraries/libc/ctype/isalpha.c

View File

@@ -1,25 +1,16 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "j6/types.h" #include "j6/init.h"
#include "j6/errors.h" #include "j6/errors.h"
#include "j6/signals.h" #include "j6/signals.h"
#include "j6/types.h"
#include <j6libc/syscalls.h> #include <j6libc/syscalls.h>
extern "C" { extern "C" {
void _init_libc(j6_process_init *);
int main(int, const char **); int main(int, const char **);
} void _get_init(size_t *initc, struct j6_init_value **initv);
j6_handle_t sys = j6_handle_invalid;
size_t size = 0;
void
_init_libc(j6_process_init *init)
{
sys = init->handles[0];
size = reinterpret_cast<size_t>(init->handles[1]);
} }
int int
@@ -27,12 +18,25 @@ main(int argc, const char **argv)
{ {
_syscall_system_log("fb driver starting"); _syscall_system_log("fb driver starting");
if (size == 0) size_t initc = 0;
j6_init_value *initv = nullptr;
_get_init(&initc, &initv);
j6_init_framebuffer *fb = nullptr;
for (unsigned i = 0; i < initc; ++i) {
if (initv[i].type == j6_init_desc_framebuffer) {
fb = reinterpret_cast<j6_init_framebuffer*>(initv[i].value);
break;
}
}
if (!fb)
return 1; return 1;
uint32_t *fb = reinterpret_cast<uint32_t*>(0x100000000); uint32_t *fbp = reinterpret_cast<uint32_t*>(fb->addr);
size_t size = fb->size;
for (size_t i=0; i < size/4; ++i) { for (size_t i=0; i < size/4; ++i) {
fb[i] = 0xff; fbp[i] = 0xff;
} }
_syscall_system_log("fb driver done, exiting"); _syscall_system_log("fb driver done, exiting");

View File

@@ -11,7 +11,7 @@
#include "serial.h" #include "serial.h"
char inbuf[1024]; char inbuf[1024];
j6_handle_t sys = j6_handle_invalid; extern j6_handle_t __handle_sys;
j6_handle_t endp = j6_handle_invalid; j6_handle_t endp = j6_handle_invalid;
extern "C" { extern "C" {
@@ -51,12 +51,6 @@ thread_proc()
_syscall_thread_exit(0); _syscall_thread_exit(0);
} }
void
_init_libc(j6_process_init *init)
{
sys = init->handles[0];
}
int int
main(int argc, const char **argv) main(int argc, const char **argv)
{ {
@@ -65,6 +59,9 @@ main(int argc, const char **argv)
_syscall_system_log("main thread starting"); _syscall_system_log("main thread starting");
for (int i = 0; i < argc; ++i)
_syscall_system_log(argv[i]);
void *base = malloc(0x1000); void *base = malloc(0x1000);
if (!base) if (!base)
return 1; return 1;
@@ -97,7 +94,7 @@ main(int argc, const char **argv)
if (tag != 17) if (tag != 17)
_syscall_system_log("GOT WRONG TAG FROM SENDRECV"); _syscall_system_log("GOT WRONG TAG FROM SENDRECV");
result = _syscall_system_bind_irq(sys, endp, 3); result = _syscall_system_bind_irq(__handle_sys, endp, 3);
if (result != j6_status_ok) if (result != j6_status_ok)
return result; return result;

View File

@@ -1,24 +0,0 @@
section .bss
mymessage:
resq 1024
extern main
extern _init_libc
extern exit
section .text
global _start
_start:
mov rbp, rsp
mov rdi, rsp
call _init_libc
mov rdi, 0
mov rsi, 0
call main
mov rdi, rax
call exit

30
src/include/j6/init.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
/// \file init.h
/// Types used in process and thread initialization
#include <stdint.h>
enum j6_init_type { // `value` is a:
j6_init_handle_system, // Handle to the system
j6_init_handle_process, // Handle to this process
j6_init_handle_thread, // Handle to this thread
j6_init_handle_space, // Handle to this process' address space
j6_init_desc_framebuffer // Pointer to a j6_init_framebuffer descriptor
};
struct j6_init_value {
enum j6_init_type type;
uint64_t value;
};
/// Structure defining a framebuffer.
/// `flags` has the following bits:
/// 0-3: Pixel layout. 0000: bgr8, 0001: rgb8
struct j6_init_framebuffer {
void* addr;
size_t size;
uint32_t vertical;
uint32_t horizontal;
uint32_t scanline;
uint32_t flags;
};

View File

@@ -1,5 +1,7 @@
#include <stddef.h> #include <stddef.h>
#include <j6/init.h>
#include "apic.h" #include "apic.h"
#include "clock.h" #include "clock.h"
#include "console.h" #include "console.h"
@@ -63,6 +65,14 @@ scheduler::scheduler(lapic *apic) :
bsp_cpu_data.t = idle; bsp_cpu_data.t = idle;
} }
template <typename T>
inline T * push(uintptr_t &rsp, size_t size = sizeof(T)) {
rsp -= size;
T *p = reinterpret_cast<T*>(rsp);
rsp &= ~(sizeof(uint64_t)-1); // Align the stack
return p;
}
uintptr_t uintptr_t
load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb)
{ {
@@ -72,31 +82,60 @@ load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb)
// We're now in the process space for this process, allocate memory for the // We're now in the process space for this process, allocate memory for the
// process code and load it // process code and load it
process &proc = process::current(); process &proc = process::current();
thread &th = thread::current();
vm_space &space = proc.space(); vm_space &space = proc.space();
vm_area *vma = new vm_area_open(bytes, space, vm_flags::zero|vm_flags::write); vm_area *vma = new vm_area_open(bytes, space, vm_flags::zero|vm_flags::write);
space.add(virt, vma); space.add(virt, vma);
vma->commit(phys, 0, memory::page_count(bytes)); vma->commit(phys, 0, memory::page_count(bytes));
tcb->rsp3 -= 2 * sizeof(uint64_t); // double zero stack sentinel
uint64_t *sentinel = reinterpret_cast<uint64_t*>(tcb->rsp3); *push<uint64_t>(tcb->rsp3) = 0;
sentinel[0] = sentinel[1] = 0; *push<uint64_t>(tcb->rsp3) = 0;
tcb->rsp3 -= sizeof(j6_process_init); const char message[] = "Hello from the kernel!";
j6_process_init *init = reinterpret_cast<j6_process_init*>(tcb->rsp3); char *message_arg = push<char>(tcb->rsp3, sizeof(message));
kutil::memcpy(message_arg, message, sizeof(message));
init->process = proc.add_handle(&proc); j6_init_framebuffer *fb_desc = push<j6_init_framebuffer>(tcb->rsp3);
init->handles[0] = proc.add_handle(system::get()); fb_desc->addr = reinterpret_cast<void*>(0x100000000);
init->handles[1] = j6_handle_invalid; fb_desc->size = fb_size;
init->handles[2] = j6_handle_invalid;
j6_init_value *initv = push<j6_init_value>(tcb->rsp3);
initv->type = j6_init_handle_system;
initv->value = static_cast<uint64_t>(proc.add_handle(system::get()));
initv = push<j6_init_value>(tcb->rsp3);
initv->type = j6_init_handle_process;
initv->value = static_cast<uint64_t>(proc.add_handle(&proc));
initv = push<j6_init_value>(tcb->rsp3);
initv->type = j6_init_handle_thread;
initv->value = static_cast<uint64_t>(proc.add_handle(&th));
initv = push<j6_init_value>(tcb->rsp3);
initv->type = j6_init_handle_space;
//initv->value = static_cast<uint64_t>(proc.add_handle(&space));
initv = push<j6_init_value>(tcb->rsp3);
initv->type = j6_init_desc_framebuffer;
initv->value = reinterpret_cast<uint64_t>(fb_desc);
uint64_t *initc = push<uint64_t>(tcb->rsp3);
*initc = 5;
char **argv0 = push<char*>(tcb->rsp3);
*argv0 = message_arg;
uint64_t *argc = push<uint64_t>(tcb->rsp3);
*argc = 1;
// Crazypants framebuffer part // Crazypants framebuffer part
init->handles[1] = reinterpret_cast<j6_handle_t>(fb_size);
vma = new vm_area_open(fb_size, space, vm_flags::write|vm_flags::mmio); vma = new vm_area_open(fb_size, space, vm_flags::write|vm_flags::mmio);
space.add(0x100000000, vma); space.add(0x100000000, vma);
vma->commit(fb_loc, 0, memory::page_count(fb_size)); vma->commit(fb_loc, 0, memory::page_count(fb_size));
thread::current().clear_state(thread::state::loading); th.clear_state(thread::state::loading);
return tcb->rsp3; return tcb->rsp3;
} }

View File

@@ -1,24 +1,19 @@
section .bss
mymessage:
resq 1024
extern main extern main
extern _init_libc
extern exit extern exit
extern _init_libc
section .text global _start:function (_start.end - _start)
global _start
_start: _start:
mov rbp, rsp mov rbp, rsp
mov rdi, rsp mov rdi, rsp
call _init_libc call _init_libc
mov rdi, 0 pop rdi
mov rsi, 0 mov rsi, rsp
call main call main
mov rdi, rax mov rdi, rax
call exit call exit
.end:

View File

@@ -0,0 +1,36 @@
#include <stdint.h>
#include <j6/init.h>
#include <j6/types.h>
static size_t __initc = 0;
static struct j6_init_value *__initv = 0;
j6_handle_t __handle_sys = j6_handle_invalid;
void
_get_init(size_t *initc, struct j6_init_value **initv)
{
if (!initc)
return;
*initc = __initc;
if (initv)
*initv = __initv;
}
void
_init_libc(uint64_t *rsp)
{
uint64_t argc = *rsp++;
rsp += argc;
__initc = *rsp++;
__initv = (struct j6_init_value *)rsp;
for (unsigned i = 0; i < __initc; ++i) {
if (__initv[i].type == j6_init_handle_system) {
__handle_sys = __initv[i].value;
break;
}
}
}