[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:
@@ -84,7 +84,6 @@ modules:
|
||||
source:
|
||||
- src/drivers/nulldrv/io.cpp
|
||||
- src/drivers/nulldrv/main.cpp
|
||||
- src/drivers/nulldrv/main.s
|
||||
- src/drivers/nulldrv/serial.cpp
|
||||
|
||||
fb:
|
||||
@@ -95,7 +94,6 @@ modules:
|
||||
- libc
|
||||
source:
|
||||
- src/drivers/fb/main.cpp
|
||||
- src/drivers/fb/main.s
|
||||
|
||||
kutil:
|
||||
kind: lib
|
||||
@@ -132,6 +130,8 @@ modules:
|
||||
#- LACKS_TIME_H
|
||||
source:
|
||||
- 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/ctype/isalnum.c
|
||||
- src/libraries/libc/ctype/isalpha.c
|
||||
|
||||
@@ -1,25 +1,16 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "j6/types.h"
|
||||
#include "j6/init.h"
|
||||
#include "j6/errors.h"
|
||||
#include "j6/signals.h"
|
||||
#include "j6/types.h"
|
||||
|
||||
#include <j6libc/syscalls.h>
|
||||
|
||||
extern "C" {
|
||||
void _init_libc(j6_process_init *);
|
||||
int main(int, const char **);
|
||||
}
|
||||
|
||||
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]);
|
||||
void _get_init(size_t *initc, struct j6_init_value **initv);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -27,12 +18,25 @@ main(int argc, const char **argv)
|
||||
{
|
||||
_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;
|
||||
|
||||
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) {
|
||||
fb[i] = 0xff;
|
||||
fbp[i] = 0xff;
|
||||
}
|
||||
|
||||
_syscall_system_log("fb driver done, exiting");
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "serial.h"
|
||||
|
||||
char inbuf[1024];
|
||||
j6_handle_t sys = j6_handle_invalid;
|
||||
extern j6_handle_t __handle_sys;
|
||||
j6_handle_t endp = j6_handle_invalid;
|
||||
|
||||
extern "C" {
|
||||
@@ -51,12 +51,6 @@ thread_proc()
|
||||
_syscall_thread_exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
_init_libc(j6_process_init *init)
|
||||
{
|
||||
sys = init->handles[0];
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
@@ -65,6 +59,9 @@ main(int argc, const char **argv)
|
||||
|
||||
_syscall_system_log("main thread starting");
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
_syscall_system_log(argv[i]);
|
||||
|
||||
void *base = malloc(0x1000);
|
||||
if (!base)
|
||||
return 1;
|
||||
@@ -97,7 +94,7 @@ main(int argc, const char **argv)
|
||||
if (tag != 17)
|
||||
_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)
|
||||
return result;
|
||||
|
||||
|
||||
@@ -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
30
src/include/j6/init.h
Normal 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;
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <j6/init.h>
|
||||
|
||||
#include "apic.h"
|
||||
#include "clock.h"
|
||||
#include "console.h"
|
||||
@@ -63,6 +65,14 @@ scheduler::scheduler(lapic *apic) :
|
||||
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
|
||||
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
|
||||
// process code and load it
|
||||
process &proc = process::current();
|
||||
thread &th = thread::current();
|
||||
vm_space &space = proc.space();
|
||||
|
||||
vm_area *vma = new vm_area_open(bytes, space, vm_flags::zero|vm_flags::write);
|
||||
space.add(virt, vma);
|
||||
vma->commit(phys, 0, memory::page_count(bytes));
|
||||
|
||||
tcb->rsp3 -= 2 * sizeof(uint64_t);
|
||||
uint64_t *sentinel = reinterpret_cast<uint64_t*>(tcb->rsp3);
|
||||
sentinel[0] = sentinel[1] = 0;
|
||||
// double zero stack sentinel
|
||||
*push<uint64_t>(tcb->rsp3) = 0;
|
||||
*push<uint64_t>(tcb->rsp3) = 0;
|
||||
|
||||
tcb->rsp3 -= sizeof(j6_process_init);
|
||||
j6_process_init *init = reinterpret_cast<j6_process_init*>(tcb->rsp3);
|
||||
const char message[] = "Hello from the kernel!";
|
||||
char *message_arg = push<char>(tcb->rsp3, sizeof(message));
|
||||
kutil::memcpy(message_arg, message, sizeof(message));
|
||||
|
||||
init->process = proc.add_handle(&proc);
|
||||
init->handles[0] = proc.add_handle(system::get());
|
||||
init->handles[1] = j6_handle_invalid;
|
||||
init->handles[2] = j6_handle_invalid;
|
||||
j6_init_framebuffer *fb_desc = push<j6_init_framebuffer>(tcb->rsp3);
|
||||
fb_desc->addr = reinterpret_cast<void*>(0x100000000);
|
||||
fb_desc->size = fb_size;
|
||||
|
||||
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
|
||||
init->handles[1] = reinterpret_cast<j6_handle_t>(fb_size);
|
||||
vma = new vm_area_open(fb_size, space, vm_flags::write|vm_flags::mmio);
|
||||
space.add(0x100000000, vma);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
section .bss
|
||||
mymessage:
|
||||
resq 1024
|
||||
|
||||
extern main
|
||||
extern _init_libc
|
||||
extern exit
|
||||
extern _init_libc
|
||||
|
||||
section .text
|
||||
|
||||
global _start
|
||||
global _start:function (_start.end - _start)
|
||||
_start:
|
||||
mov rbp, rsp
|
||||
|
||||
mov rdi, rsp
|
||||
|
||||
call _init_libc
|
||||
|
||||
mov rdi, 0
|
||||
mov rsi, 0
|
||||
pop rdi
|
||||
mov rsi, rsp
|
||||
|
||||
call main
|
||||
|
||||
mov rdi, rax
|
||||
call exit
|
||||
.end:
|
||||
36
src/libraries/libc/arch/x86_64/init_libc.c
Normal file
36
src/libraries/libc/arch/x86_64/init_libc.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user