Skip to content
48 changes: 33 additions & 15 deletions src/apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
set(APPS_BASE_DIR ${CMAKE_BINARY_DIR}/apps)
execute_process(COMMAND mkdir -p ${APPS_BASE_DIR})
set(DRIVE_BASE_DIR ${CMAKE_BINARY_DIR}/drive)
execute_process(COMMAND mkdir -p ${DRIVE_BASE_DIR})

macro(add_app target)
cross_target(${target})
target_link_libraries(${target} libc)
target_link_libraries(${target} cinit libc)
cross_target_binary(${target})

add_custom_command(OUTPUT ${APPS_BASE_DIR}/${target}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin ${APPS_BASE_DIR}/${target}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${APPS_BASE_DIR}/${target}.elf
# Build raw binary for execution in os
add_custom_command(OUTPUT ${DRIVE_BASE_DIR}/${target}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin ${DRIVE_BASE_DIR}/${target}

# Output from cross_target_binary
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin)

# Build elf executable for future use
add_custom_command(OUTPUT ${DRIVE_BASE_DIR}/${target}.elf
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${DRIVE_BASE_DIR}/${target}.elf

# Output from cross_target_binary
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf)

add_custom_target(${target}_app
DEPENDS ${APPS_BASE_DIR}/${target})
DEPENDS ${DRIVE_BASE_DIR}/${target} ${DRIVE_BASE_DIR}/${target}.elf)

list(APPEND APPS_TARGETS ${target} ${target}_app)
set(APPS_TARGETS ${APPS_TARGETS} PARENT_SCOPE)
endmacro()

# Code to run before calling app main (includes __start entrypoint)
add_subdirectory(cinit)

# Programs loaded from disk
add_subdirectory(foo)
add_subdirectory(bar)
add_subdirectory(init)
Expand All @@ -30,20 +43,25 @@ add_subdirectory(getpid)
message("App targets are ${APPS_TARGETS}")

add_custom_command(
OUTPUT ${APPS_BASE_DIR}/data/
COMMAND rm -rf ${APPS_BASE_DIR}/data/
COMMAND mkdir -p ${APPS_BASE_DIR}/data/
COMMAND cp -r ${CMAKE_SOURCE_DIR}/drive/* ${APPS_BASE_DIR}/data
DEPENDS ${CMAKE_SOURCE_DIR}/drive/
)
OUTPUT ${DRIVE_BASE_DIR}/data/
COMMAND rm -rf ${DRIVE_BASE_DIR}/data/
COMMAND mkdir -p ${DRIVE_BASE_DIR}/data/
COMMAND cp -r ${CMAKE_SOURCE_DIR}/drive/* ${DRIVE_BASE_DIR}/data
DEPENDS ${CMAKE_SOURCE_DIR}/drive/)

add_custom_target(apps_data
DEPENDS ${APPS_BASE_DIR}/data/)
DEPENDS ${DRIVE_BASE_DIR}/data/)

# Delete files in build/apps/data so it can be removed
set_property(
TARGET apps_data
APPEND
PROPERTY ADDITIONAL_CLEAN_FILES ${DRIVE_BASE_DIR}/data/)

add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/apps.tar
COMMAND tar -cf ${CMAKE_BINARY_DIR}/apps.tar *
DEPENDS ${APPS_TARGETS} apps_data
WORKING_DIRECTORY ${APPS_BASE_DIR})
WORKING_DIRECTORY ${DRIVE_BASE_DIR})

add_custom_target(apps_image ALL
DEPENDS ${CMAKE_BINARY_DIR}/apps.tar)
2 changes: 1 addition & 1 deletion src/apps/bar/src/bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "libc/stdio.h"

int __start(size_t argc, char ** argv) {
int main(size_t argc, char ** argv) {
printf("Bar got %u arguments\n", argc);

for (size_t i = 0; i < argc; i++) {
Expand Down
4 changes: 4 additions & 0 deletions src/apps/cinit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set(TARGET cinit)

cross_target(${TARGET})
target_link_libraries(${TARGET} libc)
30 changes: 30 additions & 0 deletions src/apps/cinit/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ENTRY(__start)

SECTIONS {
. = 0x400000;

.text :
{
*(.text.entry)
*(.text)
}

/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}

/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}

/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
}
14 changes: 14 additions & 0 deletions src/apps/cinit/src/cinit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "libc/proc.h"
#include "libc/stdio.h"

extern int main(size_t argc, char ** argv);

void __cinit(size_t argc, char ** argv) {
printf("c init\n");
// TODO init malloc
// TODO is there anything in signals or system calls to setup?
// TODO do stdio handles setup here?
int res = main(argc, argv);
printf("Main returned %d\n", res);
proc_exit(res);
}
9 changes: 9 additions & 0 deletions src/apps/cinit/src/entry.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extern __cinit
extern main

section .text.entry

global __start
__start:
call __cinit
; jmp main
2 changes: 1 addition & 1 deletion src/apps/demo/src/demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "libc/proc.h"
#include "libc/stdio.h"

int __start(size_t argc, char ** argv) {
int main(size_t argc, char ** argv) {
printf("Lets demo some cool features of printf\n");
int len = printf("Like the percent sign %%, \na signed int %d, a signed int with width formatting %4d, \nleading zeros %04d, left align %-4d\n", 10, 10, 10, 10);
len += printf("How about negative numbers: signed %d and unsigned %u\n", -10, -10);
Expand Down
2 changes: 1 addition & 1 deletion src/apps/foo/src/foo.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ void foo() {
proc_exit(0);
}

void __start() {
void main() {
foo();
}
2 changes: 1 addition & 1 deletion src/apps/getpid/src/getpid.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "libc/proc.h"
#include "libc/stdio.h"

void __start() {
void main() {
int pid = getpid();
printf("PID is %u\n");
}
4 changes: 0 additions & 4 deletions src/apps/ping/src/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,3 @@ void main() {
yield();
}
}

void __start() {
main();
}
4 changes: 0 additions & 4 deletions src/apps/pong/src/pong.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,3 @@ void main() {
yield();
}
}

void __start() {
main();
}
2 changes: 1 addition & 1 deletion src/apps/shell/src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static size_t buff_read(const cb_t * cb, uint8_t * data, size_t count);
static size_t buff_remove(cb_t * cb, size_t count);
static void exec_buff();

int __start(size_t argc, char ** argv) {
int main(size_t argc, char ** argv) {
term_command_add("help", help_cmd);
init_commands();

Expand Down
4 changes: 1 addition & 3 deletions src/kernel/include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ void kernel_queue_event(ebus_event_t * event);

typedef int (*_proc_call_t)(void * data);

int kernel_call_as_proc(int pid, _proc_call_t fn, void * data);

int kernel_switch_task();
void kernel_switch_task();

#endif // KERNEL_H
6 changes: 4 additions & 2 deletions src/kernel/src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,10 @@ int kernel_exec(const char * filename, size_t argc, char ** argv) {
return pid;
}

int kernel_switch_task() {
return scheduler_run(&__kernel.scheduler);
void kernel_switch_task() {
if (scheduler_run(&__kernel.scheduler)) {
KPANIC("Failed to switch tasks");
}
}

process_t * get_current_process() {
Expand Down
72 changes: 19 additions & 53 deletions src/kernel/src/kernel/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,44 @@
#include "kernel/logs.h"
#include "libc/string.h"

static void idle();

int scheduler_init(scheduler_t * scheduler, proc_man_t * pm) {
if (!scheduler || !pm) {
if (!scheduler) {
KLOG_ERROR("scheduler_init received a null pointer for the scheduler struct");
return -1;
}
if (!pm) {
KLOG_ERROR("scheduler_init received a null pointer for the process manager struct");
return -1;
}

KLOG_TRACE("Clearing scheduler struct");
kmemset(scheduler, 0, sizeof(scheduler_t));

KLOG_TRACE("Useing process manager %p in scheduler %p", pm, scheduler);
scheduler->pm = pm;

KLOG_TRACE("Finished init of scheduler %p", scheduler);

return 0;
}

// TODO this is just a copy of the kernel / process manager current behavior
int scheduler_run(scheduler_t * scheduler) {
if (!scheduler) {
KLOG_ERROR("scheduler_run received a null pointer");
return -1;
}

if (cb_len(&get_kernel()->event_queue.queue) > 0) {
KLOG_DEBUG("There are %u events ready", cb_len(&get_kernel()->event_queue.queue));
ebus_event_t event;

if (cb_pop(&get_kernel()->event_queue.queue, &event) < 0) {
KPANIC("Failed to pop from event queue");
}

switch (event.event_id) {
case EBUS_EVENT_EXEC: {
int pid = kernel_exec(event.exec.filename, event.exec.argc, event.exec.argv);
if (pid > 0) {
ebus_event_t proc_event = {0};
proc_event.event_id = EBUS_EVENT_PROC_MADE;
proc_event.proc_made.pid = pid;
if (ebus_push(&get_kernel()->event_queue, &proc_event)) {
KPANIC("Ebus push failed");
}
}
} break;

case EBUS_EVENT_PROC_CLOSE: {
process_t * proc = kernel_find_pid(event.proc_close.pid);
if (!proc) {
KPANIC("Failed to find pid");
}
if (pm_remove_proc(&get_kernel()->pm, proc->pid)) {
KPANIC("Failed to remove process from pm");
}
process_free(proc);
} break;

default: {
if (pm_push_event(&get_kernel()->pm, &event)) {
KPANIC("Failed to push event to process manager");
}
} break;
}
process_t * proc = get_active_task();
if (!proc) {
KPANIC("Failed to get active process");
}

process_t * next = pm_get_next(scheduler->pm);
process_t * next = pm_get_next(kernel_get_proc_man());
KLOG_TRACE("Next after %u is %u in state %u", proc->pid, next->pid, next->state);

if (next) {
// TODO ebus events
process_resume(next, 0);
KPANIC("PROCESS SHOULD NOT RETURN TO SCHEDULER!");
if (pm_resume_process(kernel_get_proc_man(), next->pid)) {
KPANIC("Failed to resume process");
}
else {
idle();
}
}

static void idle() {
asm("hlt");
KLOG_TRACE("Returned to process %u", proc->pid);
}
15 changes: 3 additions & 12 deletions src/kernel/src/kernel/system_call_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) {
proc->state = PROCESS_STATE_WAITING;

enable_interrupts();
process_t * next = pm_get_next(kernel_get_proc_man());
if (pm_resume_process(kernel_get_proc_man(), next->pid)) {
KPANIC("Failed to resume process");
}
kernel_switch_task();

// args->filter doesn't appear to be valid here, why not?
if (!(proc->next_event.event_id == proc->filter_event.event_id)) {
Expand All @@ -65,10 +62,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) {

case SYS_CALL_EVENT_TIME: {
enable_interrupts();
process_t * next = pm_get_next(kernel_get_proc_man());
if (pm_resume_process(kernel_get_proc_man(), next->pid)) {
KPANIC("Failed to resume process");
}
kernel_switch_task();

return time_s();
} break;
Expand Down Expand Up @@ -103,10 +97,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) {

do {
enable_interrupts();
process_t * next = pm_get_next(kernel_get_proc_man());
if (pm_resume_process(kernel_get_proc_man(), next->pid)) {
KPANIC("Failed to resume process");
}
kernel_switch_task();
KLOG_TRACE("Back from timer %u", timer_id);
} while (proc->next_event.timer.id != timer_id);
} break;
Expand Down
Loading
Loading