started working on processes
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 29 Aug 2024 17:41:51 +0000 (20:41 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 29 Aug 2024 17:41:51 +0000 (20:41 +0300)
12 files changed:
kern/src/config.h
kern/src/dbg.h
kern/src/file.h
kern/src/intr.asm
kern/src/intr.c
kern/src/intr.h
kern/src/main.c
kern/src/proc.c [new file with mode: 0644]
kern/src/proc.h [new file with mode: 0644]
kern/src/ptest.asm [new file with mode: 0644]
kern/src/sys.c [new file with mode: 0644]
kern/src/sys.h [new file with mode: 0644]

index d46832b..869a09d 100644 (file)
@@ -6,4 +6,9 @@
 /* CONDEV: which device to use for the kernel console (DEV_VID or DEV_SER) */
 #define CONDEV         DEV_VID
 
+/* maximum number of open files per process */
+#define PROC_MAXFD     16
+/* maximum number of processes */
+#define MAX_PROCS      24
+
 #endif /* CONFIG_H_ */
index 607ffc6..629f0e0 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef DBG_H_
 #define DBG_H_
 
-__attribute__((noreturn))
-void panic(const char *fmt, ...);
+void panic(const char *fmt, ...) __attribute__((noreturn));
 
 void dbgping(int c);
 
index 5534135..0d22833 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "fs.h"
 
-enum { FILE_REG, FILE_CDEV, FILE_BDEV };
+enum { FILE_INVAL, FILE_REG, FILE_CDEV, FILE_BDEV };
 
 struct device;
 
index b30bfa3..424bda5 100644 (file)
@@ -20,13 +20,15 @@ intr_entry_%2:
 %endmacro
 
 intr_entry_common:
+       push es
+       push ds
        push ax
        mov ax, sp
-       add ax, 2
+       add ax, 14      ; sp before the interrupt (3 here + 1 above + 3 cpu) * 2
        push cx
        push dx
        push bx
-       push ax ; saved sp
+       push ax         ; calculated original sp
        push bp
        push si
        push di
@@ -39,6 +41,8 @@ intr_entry_common:
        pop dx
        pop cx
        pop ax
+       pop ds
+       pop es
        add sp, 2       ; remove interrupt number from the stack
        iret
 
@@ -73,7 +77,7 @@ int86:
        mov ax, [bp + 4]
        mov [cs:.intop + 1], al ; modify int instruction
 
-       mov [saved_sp], sp
+       mov [cs:saved_sp], sp
        mov sp, [bp + 6]
        pop ax
        pop bx
@@ -82,17 +86,17 @@ int86:
        pop si
        pop di
        popf
-       mov sp, [saved_sp]
+       mov sp, [cs:saved_sp]
 
 .intop:        int 0xff
 
-       mov [saved_ax], ax
+       mov [cs:saved_ax], ax
        pushf
        pop ax
        mov sp, [bp + 8]
        add sp, 14      ; sp at end of outregs
        push ax         ; flags
-       mov ax, [saved_ax]
+       mov ax, [cs:saved_ax]
        push di
        push si
        push dx
@@ -100,7 +104,7 @@ int86:
        push bx
        push ax
 
-       mov sp, [saved_sp]
+       mov sp, [cs:saved_sp]
        popf
        pop di
        pop si
@@ -111,4 +115,26 @@ int86:
 saved_sp dw 0
 saved_ax dw 0
 
+       ; takes a far pointer to the target stack which should contain an
+       ; intr_frame, switches to that stack, restores the CPU state and
+       ; executes an iret
+       global intr_ret
+intr_ret:
+       add ax, 2       ; discard return address
+       pop ss          ; new stack segment
+       pop sp          ; stack pointer to the intr_frame in the new stack
+       ; restore general purpose registers
+       pop di
+       pop si
+       pop bp
+       pop bx          ; ignore sp
+       pop bx
+       pop dx
+       pop cx
+       pop ax
+       pop ds
+       pop es
+       add sp, 2       ; skip intr num
+       iret
+
 ; vi:ts=8 sts=8 sw=8 ft=nasm:
index a76a72f..784037a 100644 (file)
@@ -1,4 +1,5 @@
 #include "intr.h"
+#include "sys.h"
 
 /* PIC command and data ports */
 #define PIC1_CMD       0x20
@@ -53,6 +54,7 @@ void init_intr(void)
        }
 
        set_intr_vect(0, 0, (uint16_t)intr_entry_div);
+       set_intr_vect(0x80, 0, (uint16_t)sys_enter);
 }
 
 void dispatch_intr(struct intr_frame frm)
index 569dbd7..891b116 100644 (file)
@@ -16,6 +16,8 @@ struct registers {
 struct intr_frame {
        /* registers pushed by intr_entry_* */
        struct registers regs;
+       /* data segment registers */
+       uint16_t ds, es;
        /* interrupt number */
        uint16_t inum;
        /* pushed by CPU during interrupt entry */
index 6fc49f6..088bfb2 100644 (file)
@@ -8,51 +8,20 @@
 #include "ser.h"
 #include "con.h"
 #include "mem.h"
+#include "proc.h"
 #include "dbg.h"
 
 void kmain(void)
 {
-       int i;
-
        vid_init();
        ser_init();
        con_init();
-       mem_init();
 
        printf("eightysix kernel %s\n", VERSTR);
 
-       printf("initial kmalloc stats\n");
-       dbg_print_kmalloc_stats();
-       printf("initial free pool\n");
-       dbg_print_kmalloc_pool();
-
-       void __far *ptr[32];
-
-       for(i=0; i<32; i++) {
-               ptr[i] = kmalloc(256);
-               printf("ALLOC(256) - %x:%x\n", FP_SEG(ptr[i]), FP_OFFS(ptr[i]));
-       }
-
-       printf("\nallocated 32 256b blocks ... ");
-       dbg_print_kmalloc_stats();
-       dbg_print_kmalloc_pool();
-
-       for(i=0; i<32; i++) {
-               int idx = rand() & 0x1f;
-               while(!ptr[idx]) {
-                       idx = (idx + 1) & 0x1f;
-               }
-               if(ptr[idx]) {
-                       printf("FREE(%x:%x)\n", FP_SEG(ptr[idx]), FP_OFFS(ptr[idx]));
-                       kfree(ptr[idx]);
-                       ptr[idx] = 0;
-                       dbg_print_kmalloc_pool();
-               }
-       }
-
-       printf("\nafter freeing some... kmalloc free pool\n");
-       dbg_print_kmalloc_stats();
-       dbg_print_kmalloc_pool();
-
+       mem_init();
        init_intr();
+
+       printf("starting init\n");
+       proc_init();
 }
diff --git a/kern/src/proc.c b/kern/src/proc.c
new file mode 100644 (file)
index 0000000..a896737
--- /dev/null
@@ -0,0 +1,42 @@
+#include <string.h>
+#include "proc.h"
+#include "mem.h"
+#include "intr.h"
+#include "asmutil.h"
+#include "dbg.h"
+
+int curpid;
+struct process procs[MAX_PROCS];
+
+static int curtime;
+static struct process *runlist, *runtail, *blklist, *blktail;
+static int num_run, num_blk;
+
+void intr_ret(void __far *sp);
+
+void proc_init(void)
+{
+       struct process *p;
+       struct intr_frame __far *sp;
+       int start;
+
+       p = procs + 1;
+       /* allocate space for the test init */
+       if((start = alloc_blocks(16)) == -1) {
+               panic("failed to allocate memory for the test init process");
+       }
+       p->state = PROC_RUN;
+       p->tseg = p->dseg = start << 6;
+       p->sp = 65536 - sizeof(struct intr_frame);
+       runlist = runtail = p;
+
+       sp = MK_FP(p->dseg, p->sp);
+       fmemset(&sp->regs, 0, sizeof sp->regs);
+       sp->regs.sp = FP_OFFS(sp);
+       sp->inum = 0;
+       sp->ip = 0;
+       sp->cs = p->tseg;
+       sp->flags = 0;
+
+       intr_ret(sp);
+}
diff --git a/kern/src/proc.h b/kern/src/proc.h
new file mode 100644 (file)
index 0000000..edd9db0
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef PROC_H_
+#define PROC_H_
+
+#include "config.h"
+#include <inttypes.h>
+#include "file.h"
+
+enum {
+       PROC_INVAL,
+       PROC_RUN,
+       PROC_BLK
+};
+
+struct process {
+       int state;
+       int uid, gid, euid, egid;
+       uint16_t tseg, dseg;
+       uint16_t sp;
+       unsigned long brk;
+       void __far *waitaddr;
+
+       struct file files[PROC_MAXFD];
+
+       struct process *next;
+};
+
+extern int curpid;
+extern struct process procs[MAX_PROCS];
+
+void proc_init(void);
+
+void schedule(void);
+
+int sys_fork(void);
+int sys_vfork(void);
+
+#endif /* PROC_H_ */
diff --git a/kern/src/ptest.asm b/kern/src/ptest.asm
new file mode 100644 (file)
index 0000000..0e1ade9
--- /dev/null
@@ -0,0 +1,16 @@
+; early processes test, hardcoded init
+       cpu 8086
+       bits 16
+       section .text
+
+       global ptest
+ptest:
+       mov ax, 64      ; sys_dbgwrite
+       mov bx, str_hello
+       mov cx, 7       ; size
+       int 80h
+
+.inf:  jmp .inf
+
+       section .rodata
+str_hello db 'hello!',10
diff --git a/kern/src/sys.c b/kern/src/sys.c
new file mode 100644 (file)
index 0000000..4ad0c76
--- /dev/null
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "sys.h"
+#include "proc.h"
+
+void sys_dbgwrite(struct registers *regs);
+
+void sys_enter(struct intr_frame *frm)
+{
+       switch(frm->regs.ax) {
+       case SYS_EXIT:
+       case SYS_OPEN:
+       case SYS_CLOSE:
+       case SYS_READ:
+       case SYS_WRITE:
+       case SYS_GETPID:
+       case SYS_FORK:
+       case SYS_VFORK:
+       case SYS_EXEC:
+               break;
+
+       case SYS_DBGWRITE:
+               sys_dbgwrite(&frm->regs);
+               break;
+
+       default:
+               printf("invalid system call: %x\n", frm->regs.ax);
+       }
+}
+
+void sys_dbgwrite(struct registers *regs)
+{
+       unsigned int i;
+       char __far *str = MK_FP(procs[curpid].dseg, regs->bx);
+       for(i=0; i<regs->cx; i++) {
+               putchar(str[i]);
+       }
+}
diff --git a/kern/src/sys.h b/kern/src/sys.h
new file mode 100644 (file)
index 0000000..c06004c
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SYS_H_
+#define SYS_H_
+
+#include "intr.h"
+
+enum {
+       SYS_EXIT                = 0,
+       SYS_OPEN                = 1,
+       SYS_CLOSE               = 2,
+       SYS_READ                = 3,
+       SYS_WRITE               = 4,
+       SYS_GETPID              = 5,
+       SYS_FORK                = 6,
+       SYS_VFORK               = 7,
+       SYS_EXEC                = 8,
+       SYS_DBGWRITE    = 64
+};
+
+void sys_enter(struct intr_frame *frm);
+
+#endif /* SYS_H_ */