SYS_EXIT, RUN command
Added ability to RUN a PGX file and the SYS_EXIT call.
This commit is contained in:
parent
ee4d8db4fa
commit
a3dab23bac
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -50,3 +50,6 @@ modules.order
|
|||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
samples/HelloPGX/hello.pgx
|
||||
samples/HelloPGX/hello.pgx
|
||||
samples/HelloPGX/hello.lst
|
||||
|
|
|
@ -7,28 +7,32 @@ F00:0006
|
|||
F00:0007 dc.b "PGX", $02
|
||||
S01:00010000: 50 47 58
|
||||
S01:00010003: 02
|
||||
F00:0008 dc.l _start
|
||||
F00:0008 dc.l start
|
||||
S01:00010004: 00 01 00 08
|
||||
F00:0009
|
||||
F00:0010 _start: move.l #_greet_end-_greet+1,d3 ; Length of the message
|
||||
S01:00010008: 76 0E
|
||||
F00:0011 move.l #_greet,d2 ; Pointer to the message
|
||||
S01:0001000A: 24 3C 00 01 00 18
|
||||
F00:0012 clr.l d1 ; Write to channel #0 (main screen)
|
||||
S01:00010010: 72 00
|
||||
F00:0013 move.l #$14,d0 ; sys_chan_write_b
|
||||
S01:00010012: 70 14
|
||||
F00:0014 trap #15 ; Call it
|
||||
F00:0010 start: move.l #$13,d0 ; sys_chan_write
|
||||
S01:00010008: 70 13
|
||||
F00:0011 clr.l d1 ; Channel #0
|
||||
S01:0001000A: 72 00
|
||||
F00:0012 move.l #greet,d2 ; Pointer to message
|
||||
S01:0001000C: 24 3C 00 01 00 1C
|
||||
F00:0013 move.l #greet_end-greet+1,d3 ; Length of message
|
||||
S01:00010012: 76 0E
|
||||
F00:0014 trap #15
|
||||
S01:00010014: 4E 4F
|
||||
F00:0015
|
||||
F00:0016 _lock: bra _lock
|
||||
S01:00010016: 60 FE
|
||||
F00:0017
|
||||
F00:0018 _greet: dc.b "Hello, world!"
|
||||
S01:00010018: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21
|
||||
F00:0019 _greet_end: dc.b 0
|
||||
S01:00010025: 00
|
||||
F00:0020
|
||||
F00:0016 done: clr.l d0 ; sys_exit
|
||||
S01:00010016: 70 00
|
||||
F00:0017 clr.l d1 ; Return value = 0
|
||||
S01:00010018: 72 00
|
||||
F00:0018 trap #15
|
||||
S01:0001001A: 4E 4F
|
||||
F00:0019
|
||||
F00:0020 greet: dc.b "Hello, world!"
|
||||
S01:0001001C: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21
|
||||
F00:0021 greet_end: dc.b 0
|
||||
S01:00010029: 00
|
||||
F00:0022
|
||||
|
||||
|
||||
Sections:
|
||||
|
@ -40,14 +44,14 @@ F00 hello.s
|
|||
|
||||
|
||||
Symbols:
|
||||
_lock EXPR(65558=0x10016) ABS
|
||||
_greet EXPR(65560=0x10018) ABS
|
||||
_greet_end EXPR(65573=0x10025) ABS
|
||||
_start EXPR(65544=0x10008) ABS
|
||||
done EXPR(65558=0x10016) UNUSED ABS
|
||||
greet_end EXPR(65577=0x10029) ABS
|
||||
greet EXPR(65564=0x1001c) ABS
|
||||
start EXPR(65544=0x10008) ABS
|
||||
_MOVEMBYTES EXPR(0=0x0) INTERNAL
|
||||
MOVEMSIZE EXPR(0=0x0) INTERNAL
|
||||
_MOVEMREGS EXPR(0=0x0) INTERNAL
|
||||
__LINE__ EXPR(20=0x14) INTERNAL
|
||||
__LINE__ EXPR(22=0x16) INTERNAL
|
||||
__FO EXPR(0=0x0) INTERNAL
|
||||
__RS EXPR(0=0x0) INTERNAL
|
||||
REPTN EXPR(-1=0xffffffff) INTERNAL
|
||||
|
|
Binary file not shown.
|
@ -5,15 +5,17 @@
|
|||
org $010000
|
||||
|
||||
dc.b "PGX", $02
|
||||
dc.l _start
|
||||
dc.l start
|
||||
|
||||
_start: move.l #_greet_end-_greet+1,d3 ; Length of the message
|
||||
move.l #_greet,d2 ; Pointer to the message
|
||||
clr.l d1 ; Write to channel #0 (main screen)
|
||||
move.l #$14,d0 ; sys_chan_write_b
|
||||
trap #15 ; Call it
|
||||
start: move.l #$13,d0 ; sys_chan_write
|
||||
clr.l d1 ; Channel #0
|
||||
move.l #greet,d2 ; Pointer to message
|
||||
move.l #greet_end-greet+1,d3 ; Length of message
|
||||
trap #15
|
||||
|
||||
_lock: bra _lock
|
||||
done: clr.l d0 ; sys_exit
|
||||
clr.l d1 ; Return value = 0
|
||||
trap #15
|
||||
|
||||
_greet: dc.b "Hello, world!"
|
||||
_greet_end: dc.b 0
|
||||
greet: dc.b "Hello, world!"
|
||||
greet_end: dc.b 0
|
||||
|
|
|
@ -21,7 +21,8 @@ export MODEL=4
|
|||
export AS = vasmm68k_mot
|
||||
export ASFLAGS = -quiet -Fvobj -nowarn=62
|
||||
export CC = vc
|
||||
export CFLAGS = +../vbcc/config/m68k-foenix -I. -Iinclude -DCPU=$(CPU) -DMODEL=$(MODEL)
|
||||
export DEFINES = -DCPU=$(CPU) -DMODEL=$(MODEL) -DKBD_POLLED=1
|
||||
export CFLAGS = +../vbcc/config/m68k-foenix -I. -Iinclude
|
||||
export RM = cmd /C del /Q /F
|
||||
|
||||
cpu = m68k
|
||||
|
@ -60,7 +61,7 @@ cli:
|
|||
$(MAKE) --directory=cli
|
||||
|
||||
foenixmcp.s68: $(c_obj) $(cpu) dev fatfs snd cli
|
||||
$(CC) $(CFLAGS) -o foenixmcp.s68 $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
|
||||
$(CC) $(CFLAGS) $(DEFINES) -o foenixmcp.s68 $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
|
||||
|
||||
%.o: %.c $(DEPS)
|
||||
$(CC) -S -c -o $@ $< $(CFLAGS)
|
||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
|||
all: $(cobjects)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -27,27 +27,10 @@ typedef struct s_cli_command {
|
|||
} t_cli_command, *p_cli_command;
|
||||
|
||||
/*
|
||||
* Commands
|
||||
* Variables
|
||||
*/
|
||||
|
||||
extern const t_cli_command g_cli_commands[];
|
||||
|
||||
//
|
||||
// List all the commands
|
||||
//
|
||||
int cmd_help(short channel, int argc, char * argv[]) {
|
||||
p_cli_command command;
|
||||
|
||||
for (command = g_cli_commands; (command != 0) && (command->name != 0); command++) {
|
||||
sys_chan_write(channel, command->help, strlen(command->help));
|
||||
sys_chan_write(channel, "\n", 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// CLI variables
|
||||
//
|
||||
short g_current_channel = 0;
|
||||
|
||||
const t_cli_command g_cli_commands[] = {
|
||||
{ "?", "? -- print this helpful message", cmd_help },
|
||||
|
@ -61,10 +44,24 @@ const t_cli_command g_cli_commands[] = {
|
|||
{ "POKE8", "POKE8 <address> <value> -- write the byte value to the address in memory", mem_cmd_poke8},
|
||||
{ "POKE16", "POKE16 <address> <value> -- write the 16-bit word value to the address in memory", mem_cmd_poke16},
|
||||
{ "POKE32", "POKE32 <address> <value> -- write the 32-bit long word value to the address in memory", mem_cmd_poke32},
|
||||
{ "RUN", "RUN <path> -- execute a binary file", cmd_run },
|
||||
{ "TYPE", "TYPE <path> -- print the contents of a text file", cmd_type },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
//
|
||||
// List all the commands
|
||||
//
|
||||
int cmd_help(short channel, int argc, char * argv[]) {
|
||||
p_cli_command command;
|
||||
|
||||
for (command = g_cli_commands; (command != 0) && (command->name != 0); command++) {
|
||||
sys_chan_write(channel, command->help, strlen(command->help));
|
||||
sys_chan_write(channel, "\n", 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to execute a command
|
||||
//
|
||||
|
@ -126,6 +123,12 @@ char * strtok_r(char * source, const char * delimiter, char ** saveptr) {
|
|||
return x;
|
||||
}
|
||||
|
||||
short cli_rerepl() {
|
||||
while (1) {
|
||||
cli_repl(g_current_channel);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Enter the CLI's read-eval-print loop
|
||||
//
|
||||
|
@ -137,8 +140,7 @@ short cli_repl(short channel) {
|
|||
int argc = 0;
|
||||
char * argv[MAX_ARGC];
|
||||
|
||||
const char * welcome = "\n\nFoenix/MCP Command Line Utility... online.\nType \"HELP\" or \"?\" for help.\n\n";
|
||||
sys_chan_write(channel, welcome, strlen(welcome));
|
||||
g_current_channel = channel;
|
||||
|
||||
while (1) {
|
||||
sys_chan_write(channel, "\n> ", 3); // Print our prompt
|
||||
|
|
|
@ -39,4 +39,9 @@ extern short cli_repl(short channel);
|
|||
*/
|
||||
extern long cli_eval_number(const char * arg);
|
||||
|
||||
/*
|
||||
* Print a help message
|
||||
*/
|
||||
extern int cmd_help(short channel, int argc, char * argv[]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,11 +5,24 @@
|
|||
#include "log.h"
|
||||
#include "simpleio.h"
|
||||
#include "cli.h"
|
||||
#include "proc.h"
|
||||
#include "cli/dos_cmds.h"
|
||||
#include "dev/block.h"
|
||||
#include "dev/fsys.h"
|
||||
#include "fatfs/ff.h"
|
||||
|
||||
short cmd_run(short screen, int argc, char * argv[]) {
|
||||
TRACE("cmd_run");
|
||||
|
||||
if (argc > 1) {
|
||||
short result = proc_run(argv[1]);
|
||||
if (result < 0) {
|
||||
log_num(LOG_ERROR, "Unable to run: ", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
short cmd_dir(short screen, int argc, char * argv[]) {
|
||||
t_file_info my_file;
|
||||
char * path = "";
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
#ifndef __DOS_CMDS_H
|
||||
#define __DOS_CMDS_H
|
||||
|
||||
/*
|
||||
* Execute a binary file
|
||||
*/
|
||||
extern short cmd_run(short screen, int argc, char * argv[]);
|
||||
|
||||
/*
|
||||
* List the directory at the given path
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
|||
all: $(cobjects)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -278,6 +278,8 @@ short chan_write_b(short channel, uint8_t b) {
|
|||
p_dev_chan cdev;
|
||||
short res;
|
||||
|
||||
TRACE("chan_write_b");
|
||||
|
||||
res = chan_get_records(channel, &chan, &cdev);
|
||||
if (res == 0) {
|
||||
return cdev->write_b(chan, b);
|
||||
|
|
|
@ -35,7 +35,11 @@ short con_write_b(p_channel chan, uint8_t b) {
|
|||
short con_read_b(p_channel chan) {
|
||||
char c;
|
||||
do {
|
||||
#ifdef KBD_POLLED
|
||||
c = kbdmo_getc_poll();
|
||||
#else
|
||||
c = kbdmo_getc();
|
||||
#endif
|
||||
} while (c == 0);
|
||||
|
||||
// Echo the character to the screen
|
||||
|
|
|
@ -221,7 +221,9 @@ short kbdmo_init() {
|
|||
int_register(INT_KBD_A2560K, kbdmo_handle_irq);
|
||||
|
||||
/* Enable the interrupt for the keyboard */
|
||||
#ifndef KBD_POLLED
|
||||
int_enable(INT_KBD_A2560K);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ cobjects = $(subst .c,.o,$(csources))
|
|||
all: $(cobjects)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ void initialize() {
|
|||
text_init(); // Initialize the text channels
|
||||
DEBUG("Foenix/MCP starting up...");
|
||||
|
||||
log_setlevel(LOG_VERBOSE);
|
||||
log_setlevel(LOG_ERROR);
|
||||
|
||||
/* Initialize the interrupt system */
|
||||
int_init();
|
||||
|
@ -174,50 +174,6 @@ void initialize() {
|
|||
int_enable_all();
|
||||
}
|
||||
|
||||
// void try_mo_scancodes(short screen) {
|
||||
// // volatile unsigned short * kbd_mo_data = ((volatile unsigned short *)0x00C00040);
|
||||
// // volatile unsigned short * kbd_mo_stat = ((volatile unsigned short *)0x00C00042);
|
||||
//
|
||||
// print(screen, "mo> ");
|
||||
//
|
||||
// do {
|
||||
// // unsigned short status = *kbd_mo_stat;
|
||||
// // if ((status & KBD_MO_STAT_EMPTY) != KBD_MO_STAT_EMPTY) {
|
||||
// // unsigned short data = *kbd_mo_data;
|
||||
// // print(screen, "[");
|
||||
// // print_hex_16(screen, status);
|
||||
// // print(screen, "]: {");
|
||||
// //
|
||||
// // print_hex_16(screen, data);
|
||||
// // print(screen, "}\n ");
|
||||
// // // }
|
||||
// // }
|
||||
//
|
||||
// unsigned short scancode = kbdmo_get_scancode_poll();
|
||||
// if (scancode != 0) {
|
||||
// print(screen, "[");
|
||||
// print_hex_16(screen, scancode);
|
||||
// print(screen, "]\n");
|
||||
// }
|
||||
//
|
||||
// } while (1);
|
||||
// }
|
||||
|
||||
// void try_mo_chars(short screen) {
|
||||
// char buffer[2];
|
||||
// buffer[1] = 0;
|
||||
//
|
||||
// print(screen, "mo> ");
|
||||
//
|
||||
// while (1) {
|
||||
// unsigned char c = kbdmo_getc_poll();
|
||||
// if (c) {
|
||||
// // text_put_raw(screen, c);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void uart_send(short uart, char * message) {
|
||||
int i, j;
|
||||
|
||||
|
@ -380,14 +336,6 @@ int main(int argc, char * argv[]) {
|
|||
print(CDEV_CONSOLE, "Text Channel A\n");
|
||||
print(CDEV_EVID, "Text Channel B\n");
|
||||
|
||||
print(CDEV_CONSOLE, "MASK_GRP1: ");
|
||||
print_hex_16(CDEV_CONSOLE, *MASK_GRP1);
|
||||
print(CDEV_CONSOLE, "\n");
|
||||
|
||||
print(CDEV_CONSOLE, "MASK_PEND1: ");
|
||||
print_hex_16(CDEV_CONSOLE, *PENDING_GRP1);
|
||||
print(CDEV_CONSOLE, "\n");
|
||||
|
||||
// uart_test_send(0);
|
||||
|
||||
/* Register a handler for the SOF interrupt and enable it */
|
||||
|
@ -413,6 +361,9 @@ int main(int argc, char * argv[]) {
|
|||
// }
|
||||
// }
|
||||
|
||||
|
||||
const char * welcome = "\n\nFoenix/MCP Command Line Utility... online.\nType \"HELP\" or \"?\" for help.\n\n";
|
||||
sys_chan_write(0, welcome, strlen(welcome));
|
||||
cli_repl(0);
|
||||
|
||||
DEBUG("Stopping.");
|
||||
|
|
3623
src/foenixmcp.s68
3623
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@
|
|||
#ifndef __ERRORS_H
|
||||
#define __ERRORS_H
|
||||
|
||||
#define MAX_ERROR_NUMBER 15 // Largest (absolute value) of the error number
|
||||
#define MAX_ERROR_NUMBER 16 // Largest (absolute value) of the error number
|
||||
|
||||
#define ERR_GENERAL -1 // A general error condition
|
||||
#define DEV_ERR_BADDEV -2 // Device number is bad (too big or no device assigned)
|
||||
|
@ -22,5 +22,5 @@
|
|||
#define ERR_BAD_EXTENSION -13 // The path to load did not have an extension that matched registered loaders
|
||||
#define ERR_OUT_OF_MEMORY -14 // Unable to allocate more memory
|
||||
#define ERR_BAD_BINARY -15 // Bad binary file format... i.e. binary format does not match expectations
|
||||
|
||||
#define ERR_NOT_EXECUTABLE -16 // Binary file format does not have a starting address
|
||||
#endif
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
//
|
||||
// #elif SYSTEM == SYS_FOENIX_A2560K
|
||||
#define PS2_STATUS ((unsigned char *)0x00C02064)
|
||||
#define PS2_CMD_BUF ((unsigned char *)0x00C02060)
|
||||
#define PS2_CMD_BUF ((unsigned char *)0x00C02064)
|
||||
#define PS2_OUT_BUF ((unsigned char *)0x00C02060)
|
||||
#define PS2_INPT_BUF ((unsigned char *)0x00C02060)
|
||||
#define PS2_DATA_BUF ((unsigned char *)0x00C02060)
|
||||
|
|
|
@ -89,6 +89,18 @@ extern int32_t syscall(int32_t function, ...);
|
|||
*** Core system calls
|
||||
***/
|
||||
|
||||
/*
|
||||
* Quit the current user process
|
||||
*
|
||||
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||
* may cause execution to return to the program that started
|
||||
* the user process.
|
||||
*
|
||||
* Inputs:
|
||||
* result = the code to return to the kernel
|
||||
*/
|
||||
extern void sys_exit(int result);
|
||||
|
||||
/*
|
||||
* Enable all interrupts
|
||||
*
|
||||
|
|
|
@ -85,7 +85,7 @@ void log3(short level, char * message1, char * message2, char * message3) {
|
|||
void log_num(short level, char * message, int n) {
|
||||
if (level <= log_level) {
|
||||
print(log_channel, message);
|
||||
print_hex_16(log_channel, n);
|
||||
print_hex_32(log_channel, n);
|
||||
print_c(log_channel, '\n');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ all: $(aobjects) $(cobjects)
|
|||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS) $(DEFINES)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32
|
|||
/* Core System Calls */
|
||||
switch (function) {
|
||||
case KFN_EXIT:
|
||||
proc_exit((int)param0);
|
||||
break;
|
||||
|
||||
case KFN_WARMBOOT:
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
xref ___main
|
||||
xref _cli_rerepl
|
||||
|
||||
xdef _syscall
|
||||
xdef ___exit
|
||||
xdef _int_enable_all
|
||||
xdef _int_disable_all
|
||||
xdef _call_user
|
||||
xdef _restart_cli
|
||||
|
||||
section "vectors",code
|
||||
|
||||
|
@ -240,3 +244,22 @@ h_trap_15:
|
|||
add.l #28,sp ; Remove parameters from the stack
|
||||
|
||||
rte ; Return to the caller
|
||||
|
||||
;
|
||||
; Jump into a user mode code
|
||||
;
|
||||
; Inputs:
|
||||
; a0 = pointer to code to execute
|
||||
; a1 = location to set user stack pointer
|
||||
;
|
||||
_call_user:
|
||||
move.l (4,a7),a0
|
||||
move.l (8,a7),a1
|
||||
andi #$dfff,sr ; Drop into user mode
|
||||
movea.l a1,a7 ; Set the stack
|
||||
jmp (a0)
|
||||
|
||||
_restart_cli:
|
||||
lea ___STACK,sp
|
||||
jsr _cli_rerepl
|
||||
bra _restart_cli
|
||||
|
|
8682
src/mapfile
8682
src/mapfile
File diff suppressed because it is too large
Load diff
91
src/proc.c
Normal file
91
src/proc.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Routines to support processes
|
||||
*
|
||||
* NOTE: at the moment, FoenixMCP is single tasking only, so there is only
|
||||
* one "process" besides the kernel.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "errors.h"
|
||||
#include "log.h"
|
||||
#include "dev/fsys.h"
|
||||
|
||||
static const long k_default_stack = 0x0000ffff; /* For now... we're just going to put the user stack under 0x00010000 */
|
||||
static int g_proc_result;
|
||||
|
||||
/*
|
||||
* Assembly routine: reset the supervisor stack pointer and restart the CLI
|
||||
*/
|
||||
extern void restart_cli();
|
||||
|
||||
extern void call_user(long start, long stack);
|
||||
|
||||
/*
|
||||
* Start a user mode process
|
||||
*
|
||||
* Inputs:
|
||||
* start = the address to start execution
|
||||
* stack = the location to start the user mode stack
|
||||
*/
|
||||
void proc_exec(long start, long stack) {
|
||||
TRACE("proc_exec");
|
||||
|
||||
log_num(LOG_INFO, "proc_exec start: ", start);
|
||||
log_num(LOG_INFO, "proc_exec stack: ", stack);
|
||||
|
||||
g_proc_result = 0;
|
||||
call_user(start, stack);
|
||||
}
|
||||
|
||||
/*
|
||||
* Quit the current user process
|
||||
*
|
||||
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||
* may cause execution to return to the program that started
|
||||
* the user process.
|
||||
*
|
||||
* Inputs:
|
||||
*/
|
||||
void proc_exit(int result) {
|
||||
g_proc_result = result;
|
||||
restart_cli();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the result code of the previously running user process
|
||||
*/
|
||||
int proc_get_result() {
|
||||
return g_proc_result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an executable binary matching the path, load it, and execute it
|
||||
*
|
||||
* Inputs:
|
||||
* path = the path to try to load
|
||||
*
|
||||
* Returns:
|
||||
* returns an error code on failure, will not return on success
|
||||
*/
|
||||
short proc_run(const char * path) {
|
||||
|
||||
TRACE("proc_run");
|
||||
|
||||
/* TODO: allow for commands without extensions */
|
||||
/* TODO: allow for a search PATH */
|
||||
/* TODO: allocate stack more dynamically */
|
||||
|
||||
long start = 0;
|
||||
short result = fsys_load(path, 0, &start);
|
||||
if (result == 0) {
|
||||
if (start != 0) {
|
||||
proc_exec(start, k_default_stack);
|
||||
} else {
|
||||
log_num(LOG_ERROR, "Couldn't execute file: ", result);
|
||||
return ERR_NOT_EXECUTABLE;
|
||||
}
|
||||
} else {
|
||||
log_num(LOG_ERROR, "Couldn't load file: ", result);
|
||||
return result;
|
||||
}
|
||||
}
|
48
src/proc.h
Normal file
48
src/proc.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Routines to support processes
|
||||
*
|
||||
* NOTE: at the moment, FoenixMCP is single tasking only, so there is only
|
||||
* one "process" besides the kernel.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PROC_H
|
||||
#define __PROC_H
|
||||
|
||||
/*
|
||||
* Start a user mode process
|
||||
*
|
||||
* Inputs:
|
||||
* start = the address to start execution
|
||||
* stack = the location to start the user mode stack
|
||||
*/
|
||||
extern void proc_exec(long start, long stack);
|
||||
|
||||
/*
|
||||
* Quit the current user process
|
||||
*
|
||||
* NOTE: at the moment, this relaunches the CLI. In the future, this
|
||||
* may cause execution to return to the program that started
|
||||
* the user process.
|
||||
*
|
||||
* Inputs:
|
||||
*/
|
||||
extern void proc_exit(int result);
|
||||
|
||||
/*
|
||||
* Return the result code of the previously running user process
|
||||
*/
|
||||
extern int proc_get_result();
|
||||
|
||||
/*
|
||||
* Find an executable binary matching the path, load it, and execute it
|
||||
*
|
||||
* Inputs:
|
||||
* path = the path to try to load
|
||||
*
|
||||
* Returns:
|
||||
* returns an error code on failure, will not return on success
|
||||
*/
|
||||
extern short proc_run(const char * path);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue