mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[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:
|
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
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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 <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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
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