duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 508a18b8d4a3d5f044187ebf3150f2c193d98cf5
parent 54bad5ff45ecd33fe462358ffae2956f13446b37
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 13 Aug 2022 14:38:37 -0400

cvm: add the ability to mount any file on the host has a drive

For example, if you want to mount "pc.img" as a FAT, you would do:

S" pc.img" mountImage mountFATvolume value myfat
0 S" init.fs" myfat FAT :child value myid
myid myfat FAT :open value myhdl
40 myhdl FATFile :readbuf rtype

And it will yield something like:

\ Initialization for PC
: ARCH S" i386"  ok

Diffstat:
Mposix/glue.fs | 3+++
Mposix/vm.c | 54+++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/posix/glue.fs b/posix/glue.fs @@ -7,3 +7,6 @@ create _POSIXFS ' abort , _POSIXFS ' activefs rebind + +: mountImage ( imgname -- drv ) + _mountdrv here 512 , ['] _drv@ , ['] _drv! , ; diff --git a/posix/vm.c b/posix/vm.c @@ -49,7 +49,7 @@ struct VM { }; static struct VM vm = {0}; -static FILE *bootfp; +static FILE *fp; // Utilities static void vmabort() { vm.PC = MEMSZ + 1; } @@ -256,7 +256,7 @@ static void _TO_() { // op: 12 } static void BOOTRD() { // op: 13 - ppush(fgetc(bootfp)); + ppush(fgetc(fp)); } static void STDOUT() { // op: 14 @@ -830,7 +830,7 @@ static void FREADBUF () { // op: 5f ppush((dword)res); } -static void FCLOSE () { // op: 60 +static void FCLOSE() { // op: 60 dword hdl = ppop(); int fd = getfiledesc(hdl); if (fd) { @@ -840,7 +840,43 @@ static void FCLOSE () { // op: 60 } } -#define OPCNT 0x61 +// ( imgname -- ) +static void MOUNTDRV() { // op: 61 + char buf[64] = {0}; + dword str = ppop(); + byte slen = gb(str++); + memcpy(buf, &vm.mem[str], slen); + if (fp) { + fclose(fp); + fp = NULL; + } + fp = fopen(buf, "r+"); + if (!fp) { + printf("Can't open %s.\n", buf); + BYEFAIL(); + } +} + +#define SECSZ 512 +// ( sec dst drv -- ) +static void DRVRD() { // op: 62 + DROP(); + dword dst = ppop(); + dword sec = ppop(); + fseek(fp, SECSZ * sec, SEEK_SET); + fread(&vm.mem[dst], SECSZ, 1, fp); +} + +// ( sec src drv -- ) +static void DRVWR() { // op: 63 + DROP(); + dword src = ppop(); + dword sec = ppop(); + fseek(fp, SECSZ * sec, SEEK_SET); + fread(&vm.mem[src], SECSZ, 1, fp); +} + +#define OPCNT 0x64 static void (*ops[OPCNT])() = { JUMP, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT_, EXECUTE, CELL, VAL, ALIAS, DOES, SLIT, BR, CBR, @@ -854,7 +890,7 @@ static void (*ops[OPCNT])() = { RSHIFT, LITN, EXECUTEWR, EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD, PARSE, REQ, FIND, APOS, COMPILING, SWR, STARTCOMP, STOPCOMP, RUNWORD, EXIT, FCHILD, FOPEN, FREADBUF, - FCLOSE}; + FCLOSE, MOUNTDRV, DRVRD, DRVWR}; static char *opnames[OPCNT] = { NULL, NULL, NULL, NULL, "bye", "byefail", "quit", "(abort)", @@ -869,7 +905,7 @@ static char *opnames[OPCNT] = { "rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word", "parse", "[]=", "find", "'", "compiling", ",\"", "]", "[", "runword", "exit", "_fchild", "_fopen", "_freadbuf", - "_fclose"}; + "_fclose", "_mountdrv", "_drv@", "_drv!"}; static void oprun1() { // run next op if (!memchk(vm.PC)) return; @@ -959,15 +995,15 @@ static void buildsysdict() { // Interpret loop int main() { strcpy(fsids[0], "fs"); // Set FS root path - bootfp = fopen("posix/boot.fs", "r"); - if (!bootfp) { + fp = fopen("posix/boot.fs", "r"); + if (!fp) { printf("Can't open boot file.\n"); return 1; } buildsysdict(); vm.PC = find("(abort)"); while (vm.PC < MEMSZ) oprun1(); - fclose(bootfp); + if (fp) fclose(fp); if (vm.PC > MEMSZ) { fprintf(stderr, "Dumping memory to memdump.\n"); FILE *fp = fopen("memdump", "w");