aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-08-01 18:37:15 +0200
committerMarvin Borner2020-08-01 18:37:15 +0200
commit1686173757af4e453e7a32d152ec4bd20d789652 (patch)
tree539d90855fa59c85c043976fcd9cd3075ebc8d8d
parent928bf3f29d7a8b2163a3c1d5c15554d5b42c606b (diff)
Started multitasking
-rw-r--r--apps/Makefile6
-rw-r--r--apps/a.c (renamed from apps/test.c)2
-rw-r--r--apps/b.c46
-rw-r--r--apps/root.c48
-rwxr-xr-xrun2
-rw-r--r--src/Makefile1
-rw-r--r--src/features/load.c13
-rw-r--r--src/features/proc.c64
-rw-r--r--src/inc/load.h4
-rw-r--r--src/inc/proc.h22
-rw-r--r--src/inc/timer.h1
-rw-r--r--src/main.c2
12 files changed, 198 insertions, 13 deletions
diff --git a/apps/Makefile b/apps/Makefile
index 574f135..56e5472 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -1,6 +1,6 @@
# MIT License, Copyright (c) 2020 Marvin Borner
-COBJS = test.o
+COBJS = a.o b.o root.o
CC = ../cross/opt/bin/i686-elf-gcc
LD = ../cross/opt/bin/i686-elf-ld
OC = ../cross/opt/bin/i686-elf-objcopy
@@ -10,7 +10,7 @@ CFLAGS = $(CSFLAGS) -Wall -Wextra -nostdlib -nostdinc -ffreestanding -ffunction-
all: $(COBJS)
%.o: %.c
- @mkdir -p ../build/
+ @mkdir -p ../build/apps/
@$(CC) -c $(CFLAGS) $< -o $@
@$(LD) -o $(@:.o=.elf) -Tlink.ld $@
- @$(OC) -O binary $(@:.o=.elf) ../build/$(@:.o=)
+ @$(OC) -O binary $(@:.o=.elf) ../build/apps/$(@:.o=)
diff --git a/apps/test.c b/apps/a.c
index ad84996..f09bb96 100644
--- a/apps/test.c
+++ b/apps/a.c
@@ -42,5 +42,5 @@ void serial_print(const char *data)
void main()
{
- serial_print("Follow the white rabbit.");
+ serial_print("a");
}
diff --git a/apps/b.c b/apps/b.c
new file mode 100644
index 0000000..3de20bf
--- /dev/null
+++ b/apps/b.c
@@ -0,0 +1,46 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#include <def.h>
+
+u32 strlen(const char *s)
+{
+ const char *ss = s;
+ while (*ss)
+ ss++;
+ return ss - s;
+}
+
+u8 inb(u16 port)
+{
+ u8 value;
+ __asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
+ return value;
+}
+
+void outb(u16 port, u8 data)
+{
+ __asm__ volatile("outb %0, %1" ::"a"(data), "Nd"(port));
+}
+
+int is_transmit_empty()
+{
+ return inb(0x3f8 + 5) & 0x20;
+}
+
+void serial_put(char ch)
+{
+ while (is_transmit_empty() == 0)
+ ;
+ outb(0x3f8, (u8)ch);
+}
+
+void serial_print(const char *data)
+{
+ for (u32 i = 0; i < strlen(data); i++)
+ serial_put(data[i]);
+}
+
+void main()
+{
+ serial_print("b");
+}
diff --git a/apps/root.c b/apps/root.c
new file mode 100644
index 0000000..e7cbf4e
--- /dev/null
+++ b/apps/root.c
@@ -0,0 +1,48 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#include <def.h>
+
+u32 strlen(const char *s)
+{
+ const char *ss = s;
+ while (*ss)
+ ss++;
+ return ss - s;
+}
+
+u8 inb(u16 port)
+{
+ u8 value;
+ __asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
+ return value;
+}
+
+void outb(u16 port, u8 data)
+{
+ __asm__ volatile("outb %0, %1" ::"a"(data), "Nd"(port));
+}
+
+int is_transmit_empty()
+{
+ return inb(0x3f8 + 5) & 0x20;
+}
+
+void serial_put(char ch)
+{
+ while (is_transmit_empty() == 0)
+ ;
+ outb(0x3f8, (u8)ch);
+}
+
+void serial_print(const char *data)
+{
+ for (u32 i = 0; i < strlen(data); i++)
+ serial_put(data[i]);
+}
+
+void main()
+{
+ serial_print("root loaded\n");
+ while (1) {
+ };
+}
diff --git a/run b/run
index 97fe9e0..cd8a023 100755
--- a/run
+++ b/run
@@ -96,7 +96,7 @@ make_build() {
mkdir -p mnt/
sudo mount build/disk.img mnt/
sudo cp -r disk/* mnt/
- sudo cp build/test mnt/
+ sudo cp build/apps/* mnt/
cat disk/**/* >/dev/null
sudo umount mnt/
rm -rf mnt/
diff --git a/src/Makefile b/src/Makefile
index 37ad049..e4b11fd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -13,6 +13,7 @@ COBJS = main.o \
features/psf.o \
features/gui.o \
features/load.o \
+ features/proc.o \
lib/str.o \
lib/mem.o \
lib/math.o \
diff --git a/src/features/load.c b/src/features/load.c
index 958acd7..2cfa546 100644
--- a/src/features/load.c
+++ b/src/features/load.c
@@ -2,15 +2,16 @@
#include <def.h>
#include <fs.h>
-#include <load.h>
+#include <mem.h>
#include <print.h>
+#include <proc.h>
-void bin_load(char *path)
+void bin_load(char *path, struct proc *proc)
{
char *data = read_file(path);
+ u32 stack = (u32)malloc(0x1000) + 0x1000;
- void (*entry)();
- *(void **)(&entry) = data;
-
- entry();
+ proc->regs.ebp = stack;
+ proc->regs.esp = stack;
+ proc->regs.eip = (u32)&data;
}
diff --git a/src/features/proc.c b/src/features/proc.c
new file mode 100644
index 0000000..92e17f1
--- /dev/null
+++ b/src/features/proc.c
@@ -0,0 +1,64 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#include <interrupts.h>
+#include <load.h>
+#include <mem.h>
+#include <print.h>
+#include <proc.h>
+#include <timer.h>
+
+u32 pid = 0;
+struct proc *root;
+struct proc *current;
+struct proc *last;
+
+void scheduler(struct regs *regs)
+{
+ printf(".");
+ memcpy(&current->regs, regs, sizeof(struct regs));
+
+ timer_handler();
+
+ if (!current->next)
+ current = root;
+ else
+ current = current->next;
+
+ while (current->state == PROC_ASLEEP)
+ if (!current->next)
+ current = root;
+ else
+ current = current->next;
+
+ memcpy(regs, &current->regs, sizeof(struct regs));
+}
+
+void proc_attach(struct proc *proc)
+{
+ if (!last->next) {
+ last->next = proc;
+ } else {
+ struct proc *save = last;
+ while (save->next)
+ save = save->next;
+ save->next = proc;
+ }
+}
+
+struct proc *proc_make()
+{
+ struct proc *proc = (struct proc *)malloc(sizeof(*proc));
+ proc->pid = pid++;
+ proc->state = PROC_RUNNING;
+ if (current)
+ proc_attach(proc);
+ last = proc;
+ return proc;
+}
+
+void proc_init()
+{
+ current = root = proc_make();
+ bin_load("/root", root);
+ irq_install_handler(0, scheduler);
+}
diff --git a/src/inc/load.h b/src/inc/load.h
index a02afc0..60fecf9 100644
--- a/src/inc/load.h
+++ b/src/inc/load.h
@@ -3,6 +3,8 @@
#ifndef LOAD_H
#define LOAD_H
-void bin_load(char *path);
+#include <proc.h>
+
+void bin_load(char *path, struct proc *proc);
#endif
diff --git a/src/inc/proc.h b/src/inc/proc.h
new file mode 100644
index 0000000..dc8b9e9
--- /dev/null
+++ b/src/inc/proc.h
@@ -0,0 +1,22 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#ifndef PROC_H
+#define PROC_H
+
+#include <def.h>
+#include <interrupts.h>
+
+enum state { PROC_RUNNING, PROC_ASLEEP };
+
+struct proc {
+ u32 pid;
+ enum state state;
+ struct regs regs;
+ /* struct proc *parent; */
+ struct proc *next;
+};
+
+void proc_init();
+struct proc *proc_make();
+
+#endif
diff --git a/src/inc/timer.h b/src/inc/timer.h
index 4b2bb8c..7c4f077 100644
--- a/src/inc/timer.h
+++ b/src/inc/timer.h
@@ -6,5 +6,6 @@
#include <def.h>
void timer_install();
+void timer_handler(); // For scheduler
#endif
diff --git a/src/main.c b/src/main.c
index ba390fa..0e08229 100644
--- a/src/main.c
+++ b/src/main.c
@@ -42,7 +42,7 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
gui_init(FONT_PATH);
gui_term_write("Wake up, " USERNAME "...\n");
- bin_load("/test");
+ proc_init();
while (1) {
};