Adds starting processes via multiboot modules. Removes built-in module. Splits main.cu in main.cu and keyboard.cu.
This commit is contained in:
parent
6599c6c306
commit
ebb537d5e1
9 changed files with 618 additions and 582 deletions
27
Depfile
27
Depfile
|
@ -2,9 +2,11 @@
|
|||
Artifact=kernel
|
||||
TempDir=obj
|
||||
SourceDir=asm src csl
|
||||
AdditionalObjects=obj/main.o
|
||||
AdditionalObjects=
|
||||
ExternalObjects=conductance/|*.o
|
||||
|
||||
AdditionalDependencies=obj/main.in obj/keyboard.in
|
||||
|
||||
LexUseCpp
|
||||
YaccUseCpp
|
||||
|
||||
|
@ -28,25 +30,28 @@ LDFLAGS=-nostdlib -fno-builtin -Tkernel.ld
|
|||
|
||||
TOOLS=/home/felix/projects/Electronics/build-Electronics-Clang-Debug/bin
|
||||
|
||||
obj/main.o: scripts/main.cu
|
||||
obj/main.in: scripts/main.cu
|
||||
$(TOOLS)/copper \
|
||||
scripts/main.cu > \
|
||||
scripts/main.cu.spark
|
||||
$(TOOLS)/spark \
|
||||
scripts/main.cu.spark \
|
||||
obj/main.in
|
||||
objcopy -B i386 -I binary -O elf32-i386 \
|
||||
obj/main.in obj/main.o
|
||||
objcopy \
|
||||
--redefine-sym _binary_obj_main_in_start=mainscript_start \
|
||||
--redefine-sym _binary_obj_main_in_end=mainscript_end \
|
||||
--redefine-sym _binary_obj_main_in_size=mainscript_size \
|
||||
obj/main.o
|
||||
|
||||
obj/keyboard.in: scripts/keyboard.cu
|
||||
$(TOOLS)/copper \
|
||||
scripts/keyboard.cu > \
|
||||
scripts/keyboard.cu.spark
|
||||
$(TOOLS)/spark \
|
||||
scripts/keyboard.cu.spark \
|
||||
obj/keyboard.in
|
||||
|
||||
QEMUFLAGS=-serial stdio -kernel kernel -initrd obj/main.in,obj/keyboard.in
|
||||
|
||||
.PHONY: run
|
||||
run:
|
||||
qemu-system-i386 -serial stdio -kernel kernel
|
||||
qemu-system-i386 $(QEMUFLAGS)
|
||||
|
||||
.PHONY: debug
|
||||
debug:
|
||||
qemu-system-i386 -s -S -serial stdio -kernel kernel
|
||||
qemu-system-i386 -s -S $(QEMUFLAGS)
|
||||
|
|
35
Makefile
35
Makefile
|
@ -14,7 +14,7 @@ TEMPLE = mono temple.exe
|
|||
SRCS_AS = asm/dynamic.S asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
||||
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/serial.c src/stdlib.c src/timer.c src/vmm.c
|
||||
SRCS_CXX = src/cplusplus.cpp src/vm.cpp csl/casts.cpp csl/cpustatetype.cpp csl/io.cpp
|
||||
OBJS = obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o
|
||||
OBJS = obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o
|
||||
|
||||
# Flags
|
||||
FLAGS = -g -Wall -Wextra -m32 -DCIRCUIT_OS -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx -I/home/felix/projects/Electronics/Electronics/Conductance -I/home/felix/projects/Electronics/Electronics/Tools
|
||||
|
@ -28,10 +28,10 @@ all: kernel
|
|||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o
|
||||
$(RM) obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o
|
||||
|
||||
kernel: obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o
|
||||
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o
|
||||
kernel: obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o obj/main.in obj/keyboard.in
|
||||
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o
|
||||
|
||||
# src/console.c
|
||||
obj/console.o: src/console.c include/console.h include/kstdlib.h \
|
||||
|
@ -92,8 +92,8 @@ obj/cplusplus.o: src/cplusplus.cpp include/kstdlib.h include/varargs.h \
|
|||
# src/vm.cpp
|
||||
obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \
|
||||
include/malloc.h include/timer.h include/dynamic.h include/console.h \
|
||||
include/interrupts.h include/cpustate.h src/../csl/cpustatetype.hpp \
|
||||
src/../csl/io.hpp src/../csl/casts.hpp
|
||||
include/multiboot.h include/interrupts.h include/cpustate.h \
|
||||
src/../csl/cpustatetype.hpp src/../csl/io.hpp src/../csl/casts.hpp
|
||||
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
|
||||
|
||||
# csl/casts.cpp
|
||||
|
@ -129,25 +129,28 @@ obj/start.o: asm/start.S
|
|||
|
||||
TOOLS=/home/felix/projects/Electronics/build-Electronics-Clang-Debug/bin
|
||||
|
||||
obj/main.o: scripts/main.cu
|
||||
obj/main.in: scripts/main.cu
|
||||
$(TOOLS)/copper \
|
||||
scripts/main.cu > \
|
||||
scripts/main.cu.spark
|
||||
$(TOOLS)/spark \
|
||||
scripts/main.cu.spark \
|
||||
obj/main.in
|
||||
objcopy -B i386 -I binary -O elf32-i386 \
|
||||
obj/main.in obj/main.o
|
||||
objcopy \
|
||||
--redefine-sym _binary_obj_main_in_start=mainscript_start \
|
||||
--redefine-sym _binary_obj_main_in_end=mainscript_end \
|
||||
--redefine-sym _binary_obj_main_in_size=mainscript_size \
|
||||
obj/main.o
|
||||
|
||||
obj/keyboard.in: scripts/keyboard.cu
|
||||
$(TOOLS)/copper \
|
||||
scripts/keyboard.cu > \
|
||||
scripts/keyboard.cu.spark
|
||||
$(TOOLS)/spark \
|
||||
scripts/keyboard.cu.spark \
|
||||
obj/keyboard.in
|
||||
|
||||
QEMUFLAGS=-serial stdio -kernel kernel -initrd obj/main.in,obj/keyboard.in
|
||||
|
||||
.PHONY: run
|
||||
run:
|
||||
qemu-system-i386 -serial stdio -kernel kernel
|
||||
qemu-system-i386 $(QEMUFLAGS)
|
||||
|
||||
.PHONY: debug
|
||||
debug:
|
||||
qemu-system-i386 -s -S -serial stdio -kernel kernel
|
||||
qemu-system-i386 -s -S $(QEMUFLAGS)
|
||||
|
|
154
scripts/keyboard.cu
Normal file
154
scripts/keyboard.cu
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
.asmtype DRIVER
|
||||
.name KEYBOARDDRIVER
|
||||
|
||||
NATIVE print(...);
|
||||
|
||||
NATIVE outb(port : UINT16, value : UINT8);
|
||||
NATIVE inb(port : UINT16) → UINT8;
|
||||
|
||||
NATIVE toInt32(…) → INT32;
|
||||
NATIVE toUInt16(…) → UINT16;
|
||||
|
||||
TYPE CpuState IS
|
||||
eax : UINT32;
|
||||
ebx : UINT32;
|
||||
ecx : UINT32;
|
||||
END
|
||||
|
||||
PRI sendCommand(cmd : UINT8)
|
||||
BEGIN
|
||||
# Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist
|
||||
WHILE (inb(100u16) & 2u8) =/= 0u8 DO
|
||||
|
||||
END
|
||||
outb(toUInt16(96), cmd);
|
||||
END
|
||||
|
||||
PRI initKeyboard()
|
||||
BEGIN
|
||||
# Tastaturpuffer leeren
|
||||
WHILE (inb(100u16) & 1u8) =/= 0u8 DO
|
||||
inb(96u16);
|
||||
END
|
||||
|
||||
# Tastatur aktivieren
|
||||
# sendCommand(244u8);
|
||||
END
|
||||
|
||||
PRI handleKeyPress(keycode : INT, released : BOOL)
|
||||
BEGIN
|
||||
IF released = FALSE THEN
|
||||
print("[keycode=", keycode, "]\n");
|
||||
END
|
||||
END
|
||||
|
||||
PUB main() | i : INT
|
||||
BEGIN
|
||||
print("Initialize keyboard...\n");
|
||||
initKeyboard();
|
||||
END
|
||||
|
||||
# Status-Variablen fuer das Behandeln von e0- und e1-Scancodes
|
||||
VAR e0Code : BOOL;
|
||||
|
||||
# Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste
|
||||
# Datenbyte gelesen wurde
|
||||
VAR e1Code : INT;
|
||||
|
||||
VAR e1Prev : UINT16;
|
||||
|
||||
PRI translateKeyCode(extend : INT, scancode : INT) → keycode : INT
|
||||
BEGIN
|
||||
print("[extend=", extend, ",scancode=", scancode, "]\n");
|
||||
0 → keycode;
|
||||
IF extend = 0 THEN
|
||||
# LOTS OF CODE HERE. Maybe optimize this? :P
|
||||
IF scancode = 10 THEN 1 → keycode; RETURN; END
|
||||
END
|
||||
END
|
||||
|
||||
PRI handleKeyboardIRQ() | scancode : UINT8, keycode : INT, breakcode : BOOL
|
||||
BEGIN
|
||||
0 → keycode;
|
||||
FALSE → breakcode;
|
||||
inb(96u16) → scancode;
|
||||
|
||||
# Um einen Breakcode handelt es sich, wenn das oberste Bit gesetzt ist und
|
||||
# es kein e0 oder e1 fuer einen Extended-scancode ist
|
||||
IF ((scancode & 0x80u8) =/= 0u8) & ((e1Code =/= 0) | (scancode =/= 0xE1u8)) & (e0Code | (scancode =/= 0xE0u8)) THEN
|
||||
TRUE → breakcode;
|
||||
(scancode & 127u8) → scancode;
|
||||
END
|
||||
|
||||
# print("[scancode=", scancode, ",breakcode=", breakcode, "]");
|
||||
|
||||
IF e0Code THEN
|
||||
# Fake shift abfangen und ignorieren
|
||||
IF (scancode = 0x2Au8) | (scancode = 0x36u8) THEN
|
||||
FALSE → e0Code;
|
||||
RETURN;
|
||||
END
|
||||
|
||||
translateKeyCode(1, toInt32(scancode)) → keycode;
|
||||
FALSE → e0Code;
|
||||
ELSE
|
||||
IF e1Code = 2 THEN
|
||||
# Fertiger e1-Scancode
|
||||
# Zweiten Scancode in hoeherwertiges Byte packen
|
||||
(e1Prev | toUInt16(scancode * 256u8)) → e1Prev;
|
||||
translateKeyCode(2, toInt32(e1Prev)) → keycode;
|
||||
0 → e1Code;
|
||||
ELSE
|
||||
IF e1Code = 1 THEN
|
||||
# Erstes Byte fuer e1-Scancode
|
||||
toUInt16(scancode) → e1Prev;
|
||||
2 → e1Code;
|
||||
ELSE
|
||||
IF scancode = 0xE0u8 THEN
|
||||
TRUE → e0Code;
|
||||
ELSE
|
||||
IF scancode = 0xE1u8 THEN
|
||||
1 → e1Code;
|
||||
ELSE
|
||||
translateKeyCode(0, toInt32(scancode)) → keycode;
|
||||
END
|
||||
END
|
||||
END
|
||||
END
|
||||
END
|
||||
|
||||
IF keycode =/= 0 THEN
|
||||
handleKeyPress(keycode, breakcode);
|
||||
END
|
||||
END
|
||||
|
||||
PUB irq(id : INT, data : CpuState)
|
||||
BEGIN
|
||||
# print("irq:", id, ", ", data.eax, " ", data.ebx, "\n");
|
||||
IF id = 33 THEN
|
||||
handleKeyboardIRQ();
|
||||
END
|
||||
~data;
|
||||
END
|
||||
|
||||
#!
|
||||
Was noch gemacht werden muss, bis der Tastatur-Treiber funktionieren könnte:
|
||||
☑ Support für beliebige Typen in Copper
|
||||
☑ Pushen von Typen != INT
|
||||
☑ erweiterung von pushi um typcode (u?int(8|16|32), bool)
|
||||
☑ erweiterung von pushr um typcode
|
||||
☑ Simple type checks in Copper
|
||||
☑ Custom types in Copper
|
||||
☑ Native function calls in Copper
|
||||
☑ Bitwise Operations
|
||||
☑ outb und inb
|
||||
☑ NEW/DELETE
|
||||
☑ [TYPE] →
|
||||
☑ ~()
|
||||
☑ hex literals für Copper
|
||||
☑ 'RETURN' für Copper
|
||||
Was noch gemacht werden muss, bis der Tastatur-Treiber schön aussieht:
|
||||
☐ ELSE-IF
|
||||
☐ ARRAYS
|
||||
!#
|
313
scripts/keyboard.cu.spark
Normal file
313
scripts/keyboard.cu.spark
Normal file
|
@ -0,0 +1,313 @@
|
|||
; =============================================
|
||||
; compiled with Copper 1.0
|
||||
; 2015-10-16 13:36:11
|
||||
; =============================================
|
||||
|
||||
.asmtype DRIVER
|
||||
.name KEYBOARDDRIVER
|
||||
; native method: print(…)
|
||||
; native method: outb(…)
|
||||
; native method: inb(…) → UINT8
|
||||
; native method: toInt32(…) → INT32
|
||||
; native method: toUInt16(…) → UINT16
|
||||
.type CpuState {
|
||||
eax : UINT32;
|
||||
ebx : UINT32;
|
||||
ecx : UINT32;
|
||||
}
|
||||
.global e0Code BOOL
|
||||
.global e1Code INT32
|
||||
.global e1Prev UINT16
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; 0, sendCommand
|
||||
sendCommand:
|
||||
pushnil ; return value
|
||||
_private_0:
|
||||
pushi 4 100
|
||||
callnr inb 1
|
||||
pushi 3 2
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
jmp_if_not _private_1
|
||||
jmp _private_0
|
||||
_private_1:
|
||||
|
||||
load -1
|
||||
pushi 2 96
|
||||
callnr toUInt16 1
|
||||
calln outb 2
|
||||
|
||||
ret
|
||||
; end of sendCommand
|
||||
|
||||
; 0, initKeyboard
|
||||
initKeyboard:
|
||||
pushnil ; return value
|
||||
_private_2:
|
||||
pushi 4 100
|
||||
callnr inb 1
|
||||
pushi 3 1
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
jmp_if_not _private_3
|
||||
pushi 4 96
|
||||
calln inb 1
|
||||
|
||||
jmp _private_2
|
||||
_private_3:
|
||||
|
||||
ret
|
||||
; end of initKeyboard
|
||||
|
||||
; 0, handleKeyPress
|
||||
handleKeyPress:
|
||||
pushnil ; return value
|
||||
load -2
|
||||
pushi 6 0
|
||||
op2 5
|
||||
jmp_if_not _private_4
|
||||
pusht "]\n"
|
||||
load -1
|
||||
pusht "[keycode="
|
||||
calln print 3
|
||||
|
||||
_private_4:
|
||||
|
||||
ret
|
||||
; end of handleKeyPress
|
||||
|
||||
; 1, main
|
||||
.export main
|
||||
main:
|
||||
pushnil ; return value
|
||||
pushnil ; i:INT32
|
||||
pusht "Initialize keyboard...\n"
|
||||
calln print 1
|
||||
|
||||
call initKeyboard 0
|
||||
|
||||
ret
|
||||
; end of main
|
||||
|
||||
|
||||
|
||||
|
||||
; 0, translateKeyCode
|
||||
translateKeyCode:
|
||||
pushnil ; return value
|
||||
pusht "]\n"
|
||||
load -2
|
||||
pusht ",scancode="
|
||||
load -1
|
||||
pusht "[extend="
|
||||
calln print 5
|
||||
|
||||
pushi 2 0
|
||||
store 0
|
||||
|
||||
load -1
|
||||
pushi 2 0
|
||||
op2 5
|
||||
jmp_if_not _private_5
|
||||
load -2
|
||||
pushi 2 10
|
||||
op2 5
|
||||
jmp_if_not _private_6
|
||||
pushi 2 1
|
||||
store 0
|
||||
|
||||
load 0
|
||||
retr
|
||||
|
||||
_private_6:
|
||||
|
||||
_private_5:
|
||||
|
||||
load 0
|
||||
retr
|
||||
; end of translateKeyCode
|
||||
|
||||
; 0, handleKeyboardIRQ
|
||||
handleKeyboardIRQ:
|
||||
pushnil ; return value
|
||||
pushnil ; scancode:UINT8
|
||||
pushnil ; keycode:INT32
|
||||
pushnil ; breakcode:BOOL
|
||||
pushi 2 0
|
||||
store 2
|
||||
|
||||
pushi 6 0
|
||||
store 3
|
||||
|
||||
pushi 4 96
|
||||
callnr inb 1
|
||||
store 1
|
||||
|
||||
load 1
|
||||
pushi 3 128
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
loadg e1Code
|
||||
pushi 2 0
|
||||
op2 6
|
||||
load 1
|
||||
pushi 3 225
|
||||
op2 6
|
||||
op2 11
|
||||
loadg e0Code
|
||||
load 1
|
||||
pushi 3 224
|
||||
op2 6
|
||||
op2 11
|
||||
op2 12
|
||||
op2 12
|
||||
jmp_if_not _private_7
|
||||
pushi 6 1
|
||||
store 3
|
||||
|
||||
load 1
|
||||
pushi 3 127
|
||||
op2 12
|
||||
store 1
|
||||
|
||||
_private_7:
|
||||
|
||||
loadg e0Code
|
||||
jmp_if_not _private_8
|
||||
load 1
|
||||
pushi 3 42
|
||||
op2 5
|
||||
load 1
|
||||
pushi 3 54
|
||||
op2 5
|
||||
op2 11
|
||||
jmp_if_not _private_10
|
||||
pushi 6 0
|
||||
storeg e0Code
|
||||
|
||||
ret
|
||||
|
||||
_private_10:
|
||||
|
||||
load 1
|
||||
callnr toInt32 1
|
||||
pushi 2 1
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
pushi 6 0
|
||||
storeg e0Code
|
||||
|
||||
jmp _private_9
|
||||
_private_8:
|
||||
loadg e1Code
|
||||
pushi 2 2
|
||||
op2 5
|
||||
jmp_if_not _private_11
|
||||
loadg e1Prev
|
||||
load 1
|
||||
pushi 3 256
|
||||
op2 2
|
||||
callnr toUInt16 1
|
||||
op2 11
|
||||
storeg e1Prev
|
||||
|
||||
loadg e1Prev
|
||||
callnr toInt32 1
|
||||
pushi 2 2
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
pushi 2 0
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_12
|
||||
_private_11:
|
||||
loadg e1Code
|
||||
pushi 2 1
|
||||
op2 5
|
||||
jmp_if_not _private_13
|
||||
load 1
|
||||
callnr toUInt16 1
|
||||
storeg e1Prev
|
||||
|
||||
pushi 2 2
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_14
|
||||
_private_13:
|
||||
load 1
|
||||
pushi 3 224
|
||||
op2 5
|
||||
jmp_if_not _private_15
|
||||
pushi 6 1
|
||||
storeg e0Code
|
||||
|
||||
jmp _private_16
|
||||
_private_15:
|
||||
load 1
|
||||
pushi 3 225
|
||||
op2 5
|
||||
jmp_if_not _private_17
|
||||
pushi 2 1
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_18
|
||||
_private_17:
|
||||
load 1
|
||||
callnr toInt32 1
|
||||
pushi 2 0
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
_private_18:
|
||||
|
||||
_private_16:
|
||||
|
||||
_private_14:
|
||||
|
||||
_private_12:
|
||||
|
||||
_private_9:
|
||||
|
||||
load 2
|
||||
pushi 2 0
|
||||
op2 6
|
||||
jmp_if_not _private_19
|
||||
load 3
|
||||
load 2
|
||||
call handleKeyPress 2
|
||||
|
||||
_private_19:
|
||||
|
||||
ret
|
||||
; end of handleKeyboardIRQ
|
||||
|
||||
; 1, irq
|
||||
.export irq
|
||||
irq:
|
||||
pushnil ; return value
|
||||
load -1
|
||||
pushi 2 33
|
||||
op2 5
|
||||
jmp_if_not _private_20
|
||||
call handleKeyboardIRQ 0
|
||||
|
||||
_private_20:
|
||||
|
||||
load -2
|
||||
destruct
|
||||
|
||||
ret
|
||||
; end of irq
|
||||
|
157
scripts/main.cu
157
scripts/main.cu
|
@ -2,58 +2,8 @@ NATIVE print(...);
|
|||
|
||||
NATIVE shutdown();
|
||||
|
||||
NATIVE outb(port : UINT16, value : UINT8);
|
||||
NATIVE inb(port : UINT16) → UINT8;
|
||||
|
||||
NATIVE toInt8(…) → INT8;
|
||||
NATIVE toInt16(…) → INT16;
|
||||
NATIVE toInt32(…) → INT32;
|
||||
|
||||
NATIVE toUInt8(…) → UINT8;
|
||||
NATIVE toUInt16(…) → UINT16;
|
||||
NATIVE toUInt32(…) → UINT32;
|
||||
|
||||
# NATIVE toBool(…) → BOOL;
|
||||
# NATIVE toText(…) → TEXT;
|
||||
|
||||
TYPE CpuState IS
|
||||
eax : UINT32;
|
||||
ebx : UINT32;
|
||||
ecx : UINT32;
|
||||
END
|
||||
|
||||
PRI sendCommand(cmd : UINT8)
|
||||
BEGIN
|
||||
# Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist
|
||||
WHILE (inb(100u16) & 2u8) =/= 0u8 DO
|
||||
|
||||
END
|
||||
outb(toUInt16(96), cmd);
|
||||
END
|
||||
|
||||
PRI initKeyboard()
|
||||
BEGIN
|
||||
# Tastaturpuffer leeren
|
||||
WHILE (inb(100u16) & 1u8) =/= 0u8 DO
|
||||
inb(96u16);
|
||||
END
|
||||
|
||||
# Tastatur aktivieren
|
||||
# sendCommand(244u8);
|
||||
END
|
||||
|
||||
PRI handleKeyPress(keycode : INT, released : BOOL)
|
||||
BEGIN
|
||||
IF released = FALSE THEN
|
||||
print("[keycode=", keycode, "]\n");
|
||||
END
|
||||
END
|
||||
|
||||
PUB main() | i : INT
|
||||
BEGIN
|
||||
print("Initialize keyboard...\n");
|
||||
initKeyboard();
|
||||
|
||||
print("Hello World!\n");
|
||||
1 → i;
|
||||
WHILE i <= 5 DO
|
||||
|
@ -61,110 +11,3 @@ BEGIN
|
|||
(i + 1) → i;
|
||||
END
|
||||
END
|
||||
|
||||
# Status-Variablen fuer das Behandeln von e0- und e1-Scancodes
|
||||
VAR e0Code : BOOL;
|
||||
# Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste
|
||||
# Datenbyte gelesen wurde
|
||||
VAR e1Code : INT;
|
||||
VAR e1Prev : UINT16;
|
||||
|
||||
PRI translateKeyCode(extend : INT, scancode : INT) → keycode : INT
|
||||
BEGIN
|
||||
print("[extend=", extend, ",scancode=", scancode, "]\n");
|
||||
0 → keycode;
|
||||
IF extend = 0 THEN
|
||||
# LOTS OF CODE HERE. Maybe optimize this? :P
|
||||
IF scancode = 10 THEN 1 → keycode; RETURN; END
|
||||
END
|
||||
END
|
||||
|
||||
PRI handleKeyboardIRQ() | scancode : UINT8, keycode : INT, breakcode : BOOL
|
||||
BEGIN
|
||||
0 → keycode;
|
||||
FALSE → breakcode;
|
||||
inb(96u16) → scancode;
|
||||
|
||||
# Um einen Breakcode handelt es sich, wenn das oberste Bit gesetzt ist und
|
||||
# es kein e0 oder e1 fuer einen Extended-scancode ist
|
||||
IF ((scancode & 0x80u8) =/= 0u8) & ((e1Code =/= 0) | (scancode =/= 0xE1u8)) & (e0Code | (scancode =/= 0xE0u8)) THEN
|
||||
TRUE → breakcode;
|
||||
(scancode & 127u8) → scancode;
|
||||
END
|
||||
|
||||
IF scancode = 0x01u8 THEN
|
||||
shutdown();
|
||||
RETURN;
|
||||
END
|
||||
|
||||
# print("[scancode=", scancode, ",breakcode=", breakcode, "]");
|
||||
|
||||
IF e0Code THEN
|
||||
# Fake shift abfangen und ignorieren
|
||||
IF (scancode = 0x2Au8) | (scancode = 0x36u8) THEN
|
||||
FALSE → e0Code;
|
||||
RETURN;
|
||||
END
|
||||
|
||||
translateKeyCode(1, toInt32(scancode)) → keycode;
|
||||
FALSE → e0Code;
|
||||
ELSE
|
||||
IF e1Code = 2 THEN
|
||||
# Fertiger e1-Scancode
|
||||
# Zweiten Scancode in hoeherwertiges Byte packen
|
||||
(e1Prev | toUInt16(scancode * 256u8)) → e1Prev;
|
||||
translateKeyCode(2, toInt32(e1Prev)) → keycode;
|
||||
0 → e1Code;
|
||||
ELSE
|
||||
IF e1Code = 1 THEN
|
||||
# Erstes Byte fuer e1-Scancode
|
||||
toUInt16(scancode) → e1Prev;
|
||||
2 → e1Code;
|
||||
ELSE
|
||||
IF scancode = 0xE0u8 THEN
|
||||
TRUE → e0Code;
|
||||
ELSE
|
||||
IF scancode = 0xE1u8 THEN
|
||||
1 → e1Code;
|
||||
ELSE
|
||||
translateKeyCode(0, toInt32(scancode)) → keycode;
|
||||
END
|
||||
END
|
||||
END
|
||||
END
|
||||
END
|
||||
|
||||
IF keycode =/= 0 THEN
|
||||
handleKeyPress(keycode, breakcode);
|
||||
END
|
||||
END
|
||||
|
||||
PUB irq(id : INT, data : CpuState)
|
||||
BEGIN
|
||||
# print("irq:", id, ", ", data.eax, " ", data.ebx, "\n");
|
||||
IF id = 33 THEN
|
||||
handleKeyboardIRQ();
|
||||
END
|
||||
~data;
|
||||
END
|
||||
|
||||
#!
|
||||
Was noch gemacht werden muss, bis der Tastatur-Treiber funktionieren könnte:
|
||||
☑ Support für beliebige Typen in Copper
|
||||
☑ Pushen von Typen != INT
|
||||
☑ erweiterung von pushi um typcode (u?int(8|16|32), bool)
|
||||
☑ erweiterung von pushr um typcode
|
||||
☑ Simple type checks in Copper
|
||||
☑ Custom types in Copper
|
||||
☑ Native function calls in Copper
|
||||
☑ Bitwise Operations
|
||||
☑ outb und inb
|
||||
☑ NEW/DELETE
|
||||
☑ [TYPE] →
|
||||
☑ ~()
|
||||
☑ hex literals für Copper
|
||||
☑ 'RETURN' für Copper
|
||||
Was noch gemacht werden muss, bis der Tastatur-Treiber schön aussieht:
|
||||
☐ ELSE-IF
|
||||
☐ ARRAYS
|
||||
!#
|
||||
|
|
|
@ -1,117 +1,28 @@
|
|||
; =============================================
|
||||
; compiled with Copper 1.0
|
||||
; 2015-10-14 21:08:00
|
||||
; 2015-10-16 13:32:19
|
||||
; =============================================
|
||||
|
||||
; native method: print(…)
|
||||
; native method: shutdown(…)
|
||||
; native method: outb(…)
|
||||
; native method: inb(…) → UINT8
|
||||
; native method: toInt8(…) → INT8
|
||||
; native method: toInt16(…) → INT16
|
||||
; native method: toInt32(…) → INT32
|
||||
; native method: toUInt8(…) → UINT8
|
||||
; native method: toUInt16(…) → UINT16
|
||||
; native method: toUInt32(…) → UINT32
|
||||
.type CpuState {
|
||||
eax : UINT32;
|
||||
ebx : UINT32;
|
||||
ecx : UINT32;
|
||||
}
|
||||
.global e0Code BOOL
|
||||
.global e1Code INT32
|
||||
.global e1Prev UINT16
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; 0, sendCommand
|
||||
sendCommand:
|
||||
pushnil ; return value
|
||||
_private_0:
|
||||
pushi 4 100
|
||||
callnr inb 1
|
||||
pushi 3 2
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
jmp_if_not _private_1
|
||||
jmp _private_0
|
||||
_private_1:
|
||||
|
||||
load -1
|
||||
pushi 2 96
|
||||
callnr toUInt16 1
|
||||
calln outb 2
|
||||
|
||||
ret
|
||||
; end of sendCommand
|
||||
|
||||
; 0, initKeyboard
|
||||
initKeyboard:
|
||||
pushnil ; return value
|
||||
_private_2:
|
||||
pushi 4 100
|
||||
callnr inb 1
|
||||
pushi 3 1
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
jmp_if_not _private_3
|
||||
pushi 4 96
|
||||
calln inb 1
|
||||
|
||||
jmp _private_2
|
||||
_private_3:
|
||||
|
||||
ret
|
||||
; end of initKeyboard
|
||||
|
||||
; 0, handleKeyPress
|
||||
handleKeyPress:
|
||||
pushnil ; return value
|
||||
load -2
|
||||
pushi 6 0
|
||||
op2 5
|
||||
jmp_if_not _private_4
|
||||
pusht "]\n"
|
||||
load -1
|
||||
pusht "[keycode="
|
||||
calln print 3
|
||||
|
||||
_private_4:
|
||||
|
||||
ret
|
||||
; end of handleKeyPress
|
||||
|
||||
; 1, main
|
||||
.export main
|
||||
main:
|
||||
pushnil ; return value
|
||||
pushnil ; i:INT32
|
||||
pusht "Initialize keyboard...\n"
|
||||
calln print 1
|
||||
|
||||
call initKeyboard 0
|
||||
|
||||
pusht "Hello World!\n"
|
||||
calln print 1
|
||||
|
||||
pushi 2 1
|
||||
store 1
|
||||
|
||||
_private_5:
|
||||
_private_0:
|
||||
load 1
|
||||
pushi 2 5
|
||||
op2 8
|
||||
jmp_if_not _private_6
|
||||
jmp_if_not _private_1
|
||||
pusht "\n"
|
||||
load 1
|
||||
calln print 2
|
||||
|
@ -121,232 +32,9 @@ _private_5:
|
|||
op2 0
|
||||
store 1
|
||||
|
||||
jmp _private_5
|
||||
_private_6:
|
||||
jmp _private_0
|
||||
_private_1:
|
||||
|
||||
ret
|
||||
; end of main
|
||||
|
||||
|
||||
|
||||
|
||||
; 0, translateKeyCode
|
||||
translateKeyCode:
|
||||
pushnil ; return value
|
||||
pusht "]\n"
|
||||
load -2
|
||||
pusht ",scancode="
|
||||
load -1
|
||||
pusht "[extend="
|
||||
calln print 5
|
||||
|
||||
pushi 2 0
|
||||
store 0
|
||||
|
||||
load -1
|
||||
pushi 2 0
|
||||
op2 5
|
||||
jmp_if_not _private_7
|
||||
load -2
|
||||
pushi 2 10
|
||||
op2 5
|
||||
jmp_if_not _private_8
|
||||
pushi 2 1
|
||||
store 0
|
||||
|
||||
load 0
|
||||
retr
|
||||
|
||||
_private_8:
|
||||
|
||||
_private_7:
|
||||
|
||||
load 0
|
||||
retr
|
||||
; end of translateKeyCode
|
||||
|
||||
; 0, handleKeyboardIRQ
|
||||
handleKeyboardIRQ:
|
||||
pushnil ; return value
|
||||
pushnil ; scancode:UINT8
|
||||
pushnil ; keycode:INT32
|
||||
pushnil ; breakcode:BOOL
|
||||
pushi 2 0
|
||||
store 2
|
||||
|
||||
pushi 6 0
|
||||
store 3
|
||||
|
||||
pushi 4 96
|
||||
callnr inb 1
|
||||
store 1
|
||||
|
||||
load 1
|
||||
pushi 3 128
|
||||
op2 12
|
||||
pushi 3 0
|
||||
op2 6
|
||||
loadg e1Code
|
||||
pushi 2 0
|
||||
op2 6
|
||||
load 1
|
||||
pushi 3 225
|
||||
op2 6
|
||||
op2 11
|
||||
loadg e0Code
|
||||
load 1
|
||||
pushi 3 224
|
||||
op2 6
|
||||
op2 11
|
||||
op2 12
|
||||
op2 12
|
||||
jmp_if_not _private_9
|
||||
pushi 6 1
|
||||
store 3
|
||||
|
||||
load 1
|
||||
pushi 3 127
|
||||
op2 12
|
||||
store 1
|
||||
|
||||
_private_9:
|
||||
|
||||
load 1
|
||||
pushi 3 1
|
||||
op2 5
|
||||
jmp_if_not _private_10
|
||||
calln shutdown 0
|
||||
|
||||
ret
|
||||
|
||||
_private_10:
|
||||
|
||||
loadg e0Code
|
||||
jmp_if_not _private_11
|
||||
load 1
|
||||
pushi 3 42
|
||||
op2 5
|
||||
load 1
|
||||
pushi 3 54
|
||||
op2 5
|
||||
op2 11
|
||||
jmp_if_not _private_13
|
||||
pushi 6 0
|
||||
storeg e0Code
|
||||
|
||||
ret
|
||||
|
||||
_private_13:
|
||||
|
||||
load 1
|
||||
callnr toInt32 1
|
||||
pushi 2 1
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
pushi 6 0
|
||||
storeg e0Code
|
||||
|
||||
jmp _private_12
|
||||
_private_11:
|
||||
loadg e1Code
|
||||
pushi 2 2
|
||||
op2 5
|
||||
jmp_if_not _private_14
|
||||
loadg e1Prev
|
||||
load 1
|
||||
pushi 3 256
|
||||
op2 2
|
||||
callnr toUInt16 1
|
||||
op2 11
|
||||
storeg e1Prev
|
||||
|
||||
loadg e1Prev
|
||||
callnr toInt32 1
|
||||
pushi 2 2
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
pushi 2 0
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_15
|
||||
_private_14:
|
||||
loadg e1Code
|
||||
pushi 2 1
|
||||
op2 5
|
||||
jmp_if_not _private_16
|
||||
load 1
|
||||
callnr toUInt16 1
|
||||
storeg e1Prev
|
||||
|
||||
pushi 2 2
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_17
|
||||
_private_16:
|
||||
load 1
|
||||
pushi 3 224
|
||||
op2 5
|
||||
jmp_if_not _private_18
|
||||
pushi 6 1
|
||||
storeg e0Code
|
||||
|
||||
jmp _private_19
|
||||
_private_18:
|
||||
load 1
|
||||
pushi 3 225
|
||||
op2 5
|
||||
jmp_if_not _private_20
|
||||
pushi 2 1
|
||||
storeg e1Code
|
||||
|
||||
jmp _private_21
|
||||
_private_20:
|
||||
load 1
|
||||
callnr toInt32 1
|
||||
pushi 2 0
|
||||
callr translateKeyCode 2
|
||||
store 2
|
||||
|
||||
_private_21:
|
||||
|
||||
_private_19:
|
||||
|
||||
_private_17:
|
||||
|
||||
_private_15:
|
||||
|
||||
_private_12:
|
||||
|
||||
load 2
|
||||
pushi 2 0
|
||||
op2 6
|
||||
jmp_if_not _private_22
|
||||
load 3
|
||||
load 2
|
||||
call handleKeyPress 2
|
||||
|
||||
_private_22:
|
||||
|
||||
ret
|
||||
; end of handleKeyboardIRQ
|
||||
|
||||
; 1, irq
|
||||
.export irq
|
||||
irq:
|
||||
pushnil ; return value
|
||||
load -1
|
||||
pushi 2 33
|
||||
op2 5
|
||||
jmp_if_not _private_23
|
||||
call handleKeyboardIRQ 0
|
||||
|
||||
_private_23:
|
||||
|
||||
load -2
|
||||
destruct
|
||||
|
||||
ret
|
||||
; end of irq
|
||||
|
||||
|
|
44
src/init.c
44
src/init.c
|
@ -8,6 +8,13 @@
|
|||
#include <config.h>
|
||||
#include <serial.h>
|
||||
|
||||
static void halt()
|
||||
{
|
||||
while(1) {
|
||||
__asm__ volatile ("cli; hlt;");
|
||||
}
|
||||
}
|
||||
|
||||
void die(const char *msg)
|
||||
{
|
||||
die_extra(msg, "");
|
||||
|
@ -23,10 +30,7 @@ void die_extra(const char *msg, const char *extra)
|
|||
kputs(extra);
|
||||
kputc('\'');
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
__asm__ volatile ("cli; hlt;");
|
||||
}
|
||||
halt();
|
||||
}
|
||||
|
||||
extern size_t mallocCount;
|
||||
|
@ -93,42 +97,42 @@ static void debug_test()
|
|||
|
||||
static void dumpMB(const MultibootStructure *mbHeader)
|
||||
{
|
||||
kputs("Multiboot Information:\n");
|
||||
serial_printf(SERIAL_COM1, "Multiboot Information:\n");
|
||||
if(mbHeader->flags & MB_MEMSIZE)
|
||||
{
|
||||
kprintf("Lower Memory: %d kB\n", mbHeader->memLower);
|
||||
kprintf("Upper Memory: %d kB\n", mbHeader->memUpper);
|
||||
serial_printf(SERIAL_COM1, " Lower Memory: %d kB\n", mbHeader->memLower);
|
||||
serial_printf(SERIAL_COM1, " Upper Memory: %d kB\n", mbHeader->memUpper);
|
||||
}
|
||||
// TODO: MB_BOOTDEVICE
|
||||
if(mbHeader->flags & MB_COMMANDLINE)
|
||||
{
|
||||
kprintf("Commandline: %s\n", (const char*)mbHeader->commandline);
|
||||
serial_printf(SERIAL_COM1, " Commandline: %s\n", (const char*)mbHeader->commandline);
|
||||
}
|
||||
if(mbHeader->flags & MB_MODULES)
|
||||
{
|
||||
const MultibootModule *mod = (const MultibootModule *)mbHeader->modules;
|
||||
for(size_t i = 0; i < mbHeader->moduleCount; i++)
|
||||
{
|
||||
kprintf("Module %s [%d - %d]\n", (const char*)mod[i].name, mod[i].start, mod[i].end);
|
||||
serial_printf(SERIAL_COM1, " Module %s [%d - %d]\n", (const char*)mod[i].name, mod[i].start, mod[i].end);
|
||||
}
|
||||
}
|
||||
if(mbHeader->flags & MB_SYMS_AOUT)
|
||||
{
|
||||
kputs("Kernel File Format: a.out\n");
|
||||
serial_printf(SERIAL_COM1, " Kernel File Format: a.out\n");
|
||||
}
|
||||
if(mbHeader->flags & MB_SYMS_ELF)
|
||||
{
|
||||
kputs("Kernel File Format: ELF\n");
|
||||
serial_printf(SERIAL_COM1, " Kernel File Format: ELF\n");
|
||||
}
|
||||
if(mbHeader->flags & MB_MEMORYMAP)
|
||||
{
|
||||
uintptr_t it = mbHeader->memoryMap;
|
||||
kprintf("Memory Map: %d entries\n", mbHeader->memoryMapLength);
|
||||
serial_printf(SERIAL_COM1, " Memory Map: %d entries\n", mbHeader->memoryMapLength);
|
||||
for(size_t i = 0; i < mbHeader->memoryMapLength; i++)
|
||||
{
|
||||
const MultibootMemoryMap *mmap = (const MultibootMemoryMap *)it;
|
||||
if(mmap->type == 1)
|
||||
kprintf("Memory Map: [%d + %d] %s\n", (uint32_t)mmap->base, (uint32_t)mmap->length, mmap->type == 1 ? "free" : "preserved");
|
||||
serial_printf(SERIAL_COM1, " Memory Map: [%d + %d] %s\n", (uint32_t)mmap->base, (uint32_t)mmap->length, mmap->type == 1 ? "free" : "preserved");
|
||||
it += mmap->entry_size + 4; // Stupid offset :P
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +140,7 @@ static void dumpMB(const MultibootStructure *mbHeader)
|
|||
// TODO: MB_CONFIG_TABLE
|
||||
if(mbHeader->flags & MB_BOOTLOADER_NAME)
|
||||
{
|
||||
kprintf("Bootloader Name: %s\n", (const char*)mbHeader->bootLoaderName);
|
||||
serial_printf(SERIAL_COM1, " Bootloader Name: %s\n", (const char*)mbHeader->bootLoaderName);
|
||||
}
|
||||
// TODO: MB_APS_TABLE
|
||||
}
|
||||
|
@ -152,7 +156,7 @@ void putsuccess()
|
|||
kputs("[success]");
|
||||
}
|
||||
|
||||
extern void vm_start();
|
||||
extern void vm_start(const MultibootStructure *mbHeader);
|
||||
|
||||
void init(const MultibootStructure *mbHeader)
|
||||
{
|
||||
|
@ -166,7 +170,11 @@ void init(const MultibootStructure *mbHeader)
|
|||
serial_init(SERIAL_COM1, 9600, SERIAL_PARITY_NONE, 8);
|
||||
serial_write_str(SERIAL_COM1, "Debug Console Ready\n");
|
||||
|
||||
//dumpMB(mbHeader);
|
||||
dumpMB(mbHeader);
|
||||
|
||||
if(((mbHeader->flags & MB_MODULES) == 0) || (mbHeader->moduleCount == 0)) {
|
||||
die_extra("BootProcessFailed", "No initial OS modules found.");
|
||||
}
|
||||
|
||||
kputs("Initialize physical memory management: ");
|
||||
pmm_init(mbHeader);
|
||||
|
@ -210,7 +218,7 @@ void init(const MultibootStructure *mbHeader)
|
|||
|
||||
kputs("\n");
|
||||
|
||||
vm_start();
|
||||
vm_start(mbHeader);
|
||||
|
||||
irq_disable();
|
||||
|
||||
|
@ -222,7 +230,7 @@ void init(const MultibootStructure *mbHeader)
|
|||
malloc_print_list(0);
|
||||
#endif
|
||||
|
||||
while(1);
|
||||
halt();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
145
src/vm.cpp
145
src/vm.cpp
|
@ -2,6 +2,7 @@
|
|||
#include <timer.h>
|
||||
#include <dynamic.h>
|
||||
#include <console.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
#include <virtualmachine.hpp>
|
||||
#include <vmtype.hpp>
|
||||
|
@ -13,16 +14,6 @@
|
|||
#include "../csl/io.hpp"
|
||||
#include "../csl/casts.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern const char mainscript_start;
|
||||
extern const char mainscript_end;
|
||||
extern const char mainscript_size;
|
||||
|
||||
extern const char firstrun_start;
|
||||
extern const char firstrun_end;
|
||||
extern const char firstrun_size;
|
||||
}
|
||||
|
||||
void printVMValue(const VMValue &value)
|
||||
{
|
||||
switch(value.type().type()) {
|
||||
|
@ -62,15 +53,6 @@ struct dtortest {
|
|||
~dtortest() { free(mem); kprintf("[free]"); }
|
||||
} ;// object;
|
||||
|
||||
|
||||
struct {
|
||||
const char *ptr;
|
||||
uint32_t size;
|
||||
} mainAssembly {
|
||||
&mainscript_start,
|
||||
(uint32_t)&mainscript_size
|
||||
};
|
||||
|
||||
struct IrqList {
|
||||
static const size_t length = 64;
|
||||
volatile uint32_t read;
|
||||
|
@ -127,7 +109,7 @@ ExceptionCode shutdown(VMValue &, const VMArray &)
|
|||
|
||||
int ReferenceCounted::counter = 0;
|
||||
|
||||
extern "C" void vm_start()
|
||||
extern "C" void vm_start(const MultibootStructure *mbHeader)
|
||||
{
|
||||
// intr_set_handler(0x20, vm_handle_interrupt);
|
||||
intr_set_handler(0x21, vm_handle_interrupt);
|
||||
|
@ -148,26 +130,83 @@ extern "C" void vm_start()
|
|||
machine.import("toUInt16") = csl::toUInt16;
|
||||
machine.import("toUInt32") = csl::toUInt32;
|
||||
|
||||
Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size);
|
||||
if(assembly == nullptr) {
|
||||
kprintf("failed to load assembly :(\n");
|
||||
return;
|
||||
using DriverProcess = ker::Pair<Process*,uint32_t>;
|
||||
ker::Vector<DriverProcess> drivers;
|
||||
|
||||
const MultibootModule *mod = (const MultibootModule *)mbHeader->modules;
|
||||
for(size_t i = 0; i < mbHeader->moduleCount; i++)
|
||||
{
|
||||
kprintf("Loading Module '%s'...\n", (const char*)mod[i].name);
|
||||
|
||||
size_t len = mod[i].end - mod[i].start;
|
||||
|
||||
Assembly *assembly = machine.load(reinterpret_cast<void*>(mod[i].start), len);
|
||||
if(assembly == nullptr) {
|
||||
die("Failed to load assembly.");
|
||||
return;
|
||||
}
|
||||
switch(assembly->type())
|
||||
{
|
||||
case AssemblyType::Library:
|
||||
{
|
||||
// Assemblies don't need special treatment
|
||||
break;
|
||||
}
|
||||
case AssemblyType::Executable:
|
||||
{
|
||||
Process *program = machine.createProcess(assembly, false);
|
||||
if(program == nullptr) {
|
||||
die("Failed to create process.");
|
||||
return;
|
||||
}
|
||||
program->release();
|
||||
break;
|
||||
}
|
||||
case AssemblyType::Service:
|
||||
{
|
||||
Process *program = machine.createProcess(assembly, true);
|
||||
if(program == nullptr) {
|
||||
die("Failed to create service process.");
|
||||
return;
|
||||
}
|
||||
program->release();
|
||||
break;
|
||||
}
|
||||
case AssemblyType::Driver:
|
||||
{
|
||||
Process *program = machine.createProcess(assembly, true);
|
||||
if(program == nullptr) {
|
||||
die("Failed to create driver process.");
|
||||
return;
|
||||
}
|
||||
if(assembly->exports().contains("irq")) {
|
||||
drivers.append({ program, assembly->exports()["irq"] });
|
||||
} else {
|
||||
program->release();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
die("OS.UnknownAssemblyType");
|
||||
break;
|
||||
}
|
||||
}
|
||||
assembly->release();
|
||||
}
|
||||
|
||||
Process *irqService = machine.createProcess(assembly, true);
|
||||
if(irqService == nullptr) {
|
||||
kprintf("Failed to create process.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Thread *mainThread = irqService->mainThread();
|
||||
|
||||
uint32_t irqRoutine = irqService->assembly()->exports()["irq"];
|
||||
|
||||
bool osIsFailed = false;
|
||||
|
||||
while((shutdownRequested == false) && machine.step())
|
||||
{
|
||||
// Remove all terminated drivers
|
||||
for(size_t i = 0; i < drivers.length(); ) {
|
||||
if(drivers[i].first->isRunning()) {
|
||||
i++;
|
||||
} else {
|
||||
drivers[i].first->release();
|
||||
drivers.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
// check for IRQ requests
|
||||
do
|
||||
{
|
||||
|
@ -182,14 +221,14 @@ extern "C" void vm_start()
|
|||
|
||||
CpuState *cpu = &irqFiFo.items[irqFiFo.read];
|
||||
|
||||
//*
|
||||
Thread *thread = irqService->createThread(irqRoutine);
|
||||
thread->start({
|
||||
VMValue::Int32(cpu->intr),
|
||||
csl::createCpuState(cpu)
|
||||
});
|
||||
thread->release();
|
||||
// */
|
||||
for(const auto &driver : drivers) {
|
||||
Thread *thread = driver.first->createThread(driver.second);
|
||||
thread->start({
|
||||
VMValue::Int32(cpu->intr),
|
||||
csl::createCpuState(cpu)
|
||||
});
|
||||
thread->release();
|
||||
}
|
||||
irqFiFo.read += 1;
|
||||
|
||||
irq_disable();
|
||||
|
@ -200,25 +239,7 @@ extern "C" void vm_start()
|
|||
}
|
||||
irq_enable();
|
||||
} while(true);
|
||||
|
||||
if(mainThread->isRunning() == false) {
|
||||
if(osIsFailed == false) {
|
||||
osIsFailed = true;
|
||||
|
||||
kprintf("OS failed with: %s\n", execptionName(mainThread->exception()));
|
||||
|
||||
// shutdownRequested = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
mainThread->release();
|
||||
mainThread = nullptr;
|
||||
|
||||
irqService->release();
|
||||
irqService = nullptr;
|
||||
|
||||
assembly->release();
|
||||
assembly = nullptr;
|
||||
}
|
||||
kprintf("\n");
|
||||
kprintf("unreleased objects: %d\n", ReferenceCounted::counter);
|
||||
|
|
|
@ -59,7 +59,8 @@ DISTFILES += \
|
|||
asm/dynamic.S \
|
||||
README.md \
|
||||
scripts/main.spark \
|
||||
scripts/main.cu
|
||||
scripts/main.cu \
|
||||
scripts/keyboard.cu
|
||||
|
||||
INCLUDEPATH += include
|
||||
DEPENDPATH += include
|
||||
|
|
Loading…
Reference in a new issue