diff --git a/Makefile b/Makefile index a9e8f793..6dee455c 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ endif REMOTE=192.168.2.6 REMOTEUSER=sortie REMOTECOPYDIR:=/home/$(REMOTEUSER)/Desktop/MaxsiOS -MODULES=libmaxsi hello pong mkinitrd sortix +MODULES=libmaxsi hello pong mkinitrd utils sortix VERSION=0.4 DEBNAME:=sortix_$(VERSION)_$(CPU) @@ -103,7 +103,7 @@ iso: all debsource mkdir -p $(INITRDDIR) cp hello/hello $(INITRDDIR) cp pong/pong $(INITRDDIR) - cp $(INITRDDIR)/hello $(INITRDDIR)/init + for F in init cat sh mxsh clear; do cp utils/$$F $(INITRDDIR); done (cd $(INITRDDIR) && ../mkinitrd/mkinitrd * -o ../$(ISODIR)/boot/sortix.initrd) rm -rf $(INITRDDIR) cp builds/$(DEBSRCNAME)-src.tar.gz $(ISODIR) diff --git a/libmaxsi/hsrc/keyboard.h b/libmaxsi/hsrc/keyboard.h index e3d4ac2d..f41c0b99 100644 --- a/libmaxsi/hsrc/keyboard.h +++ b/libmaxsi/hsrc/keyboard.h @@ -62,6 +62,7 @@ namespace Maxsi const uint32_t NONE = 0x40000000 + 30; const uint32_t ALTGR = 0x40000000 + 31; const uint32_t NUMLCK = 0x40000000 + 32; + const uint32_t SIGINT = 0x40000000 + 33; const uint32_t DEPRESSED = (1<<31); } } diff --git a/libmaxsi/start.s b/libmaxsi/start.s index 60dc499c..a199fd3b 100644 --- a/libmaxsi/start.s +++ b/libmaxsi/start.s @@ -36,8 +36,18 @@ _start: push $0 # argc call main + # HACK: Just restart the shell! + mov $10, %eax + mov $SH, %ebx + int $0x80 + # Now return mains result when exiting the process mov %eax, %ebx mov $1, %eax mov $0x0, %ebx # TODO: This syscall exits a thread, not a process! int $0x80 + +.section .data +SH: + .asciz "sh" + diff --git a/sortix/isr.cpp b/sortix/isr.cpp index 008a1c91..c09676fb 100644 --- a/sortix/isr.cpp +++ b/sortix/isr.cpp @@ -34,6 +34,8 @@ const char* exceptions[] = { "Divide by zero", "Debug", "Non maskable interrupt" if ( Regs->int_no < 32 ) { const char* message = ( Regs->int_no < numknownexceptions ) ? exceptions[Regs->int_no] : "Unknown"; + //Sortix::Log::PrintF("eax=0x%x\tebx=0x%x\tecx=0x%x\tedx=0x%x\tesi=0x%x\tedi=0x%x\tesp=0x%x\tuseresp=0x%x\tebp=0x%x\teip=0x%x\n", Regs->eax, Regs->ebx, Regs->ecx, Regs->edx, Regs->esi, Regs->edi, Regs->esp, Regs->useresp, Regs->ebp, Regs->eip); + Sortix::PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx (cr2=0x%p, err_code=0x%p)", Regs->int_no, message, Regs->eip, Regs->cr2, Regs->err_code); } diff --git a/sortix/keyboard.cpp b/sortix/keyboard.cpp index 170baca0..d0524e7e 100644 --- a/sortix/keyboard.cpp +++ b/sortix/keyboard.cpp @@ -30,6 +30,8 @@ #include "panic.h" #include "keyboard.h" #include "isr.h" +#include "process.h" +#include "scheduler.h" #include "pong.h" @@ -578,6 +580,7 @@ namespace Sortix nat Mask = 0; nat LockMask = 0; + bool control; const nat Shift = (1<<0); const nat AltGr = (1<<1); @@ -600,6 +603,7 @@ namespace Sortix if ( CodePoint == LSHFT ) { Mask &= ~Shift; } if ( CodePoint == ALTGR ) { Mask &= ~AltGr; } if ( CodePoint == SCRLCK ) { Mask &= ~ScrLck; } + if ( CodePoint == CTRL ) { control = false; } } else { @@ -607,6 +611,12 @@ namespace Sortix if ( CodePoint == ALTGR ) { Mask |= AltGr; } if ( CodePoint == SCRLCK ) { Mask |= ScrLck; } if ( CodePoint == CAPS ) { LockMask ^= Shift; SetLEDs(LEDCapsLck); } + if ( CodePoint == CTRL ) { control = true; } + } + + if ( control && ( CodePoint == 'c' || CodePoint == 'C' ) ) + { + CodePoint = SIGINT; } return CodePoint; @@ -666,6 +676,12 @@ namespace Sortix uint32_t CodePoint = Layouts::GetCodePoint(Scancode); + if ( CodePoint == SIGINT ) + { + SigInt(); + return; + } + bool KeyUp = (Scancode & 0x80); if ( KeyUp ) { CodePoint |= DEPRESSED; } diff --git a/sortix/process.cpp b/sortix/process.cpp index ce851bd9..407c2744 100644 --- a/sortix/process.cpp +++ b/sortix/process.cpp @@ -52,6 +52,7 @@ namespace Sortix _addrspace = addrspace; _endcodesection = 0x400000UL; segments = NULL; + sigint = false; } Process::~Process() @@ -81,6 +82,7 @@ namespace Sortix void SysExecute(CPU::InterruptRegisters* R) { const char* programname = (const char*) R->ebx; + size_t programsize = 0; byte* program = InitRD::Open(programname, &programsize); if ( program == NULL ) { R->eax = -1; return; } @@ -93,5 +95,6 @@ namespace Sortix // This is a hacky way to set up the thread! R->eip = entry; R->useresp = 0x80000000UL; + R->ebp = 0x80000000UL; } } diff --git a/sortix/process.h b/sortix/process.h index e4168be9..8860408d 100644 --- a/sortix/process.h +++ b/sortix/process.h @@ -62,6 +62,9 @@ namespace Sortix DescriptorTable descriptors; ProcessSegment* segments; + public: + bool sigint; + public: addr_t _endcodesection; // HACK diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index 2c52b49e..f94e20bc 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -183,11 +183,16 @@ namespace Sortix SetState(UNRUNNABLE); } + bool sigintpending = false; + void SigInt() { sigintpending = true; } + namespace Scheduler { // Initializes the scheduling subsystem. void Init() { + sigintpending = false; + currentThread = NULL; firstRunnableThread = NULL; firstUnrunnableThread = NULL; @@ -332,6 +337,15 @@ namespace Sortix { //Log::PrintF("Scheduling while at eip=0x%p...", R->eip); + if ( currentThread != NoopThread && currentThread->GetProcess() && sigintpending ) + { + const char* programname = "sh"; + R->ebx = (uint32_t) programname; + SysExecute(R); + sigintpending = false; + Log::Print("^C\n"); + } + WakeSleeping(TimePassed); // Find the next thread to be run. diff --git a/sortix/scheduler.h b/sortix/scheduler.h index 25946a0f..e30dbd00 100644 --- a/sortix/scheduler.h +++ b/sortix/scheduler.h @@ -115,6 +115,9 @@ namespace Sortix // Scheduling Thread* CurrentThread(); + + // HACK + void SigInt(); } #endif diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 00000000..6511e64f --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,23 @@ +# Set up variables such that we can easily cross-compile. +OSROOT=.. +include ../crosscompilemakefile.mak + +BINARIES:=\ +init \ +cat \ +sh \ +mxsh \ +clear \ + +all: $(BINARIES) + +%: %.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -O2 -c $< -o $@.o + $(LD) $(LDFLAGS) $@.o -o $@ $(LIBS) + +sh: mxsh + cp mxsh sh + +clean: + rm -f $(BINARIES) *.o + diff --git a/utils/cat.cpp b/utils/cat.cpp new file mode 100644 index 00000000..7eef22c5 --- /dev/null +++ b/utils/cat.cpp @@ -0,0 +1,30 @@ +#include +#include + +int main(int argc, char* argv[]) +{ + bool lastwasesc = false; + + while (true) + { + unsigned method = System::Keyboard::POLL; + uint32_t codepoint = System::Keyboard::ReceieveKeystroke(method); + + if ( codepoint == 0 ) { continue; } + if ( codepoint & Maxsi::Keyboard::DEPRESSED ) { continue; } + if ( codepoint == Maxsi::Keyboard::UP ) { printf("\e[A"); continue; } + if ( codepoint == Maxsi::Keyboard::DOWN ) { printf("\e[B"); continue; } + if ( codepoint == Maxsi::Keyboard::RIGHT ) { printf("\e[C"); continue; } + if ( codepoint == Maxsi::Keyboard::LEFT ) { printf("\e[D"); continue; } + if ( codepoint == Maxsi::Keyboard::ESC ) { printf("\e["); lastwasesc = true; continue; } + if ( lastwasesc && codepoint == '[' ) { continue; } + if ( codepoint >= 0x80 ) { continue; } + + char msg[2]; msg[0] = codepoint; msg[1] = '\0'; + printf(msg); + lastwasesc = false; + } + + return 0; +} + diff --git a/utils/clear.cpp b/utils/clear.cpp new file mode 100644 index 00000000..27024f5e --- /dev/null +++ b/utils/clear.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char* argv[]) +{ + printf("\e[H\e[2J"); + return 0; +} diff --git a/utils/init.cpp b/utils/init.cpp new file mode 100644 index 00000000..687a9b38 --- /dev/null +++ b/utils/init.cpp @@ -0,0 +1,15 @@ +#include +#include + +int main(int argc, char* argv[]) +{ + // Reset the terminal's color and the rest of it. + printf("\e[m\e[J"); + + const char* programname = "sh"; + const char* newargv[] = { programname }; + + Maxsi::Process::Execute(programname, 1, newargv); + + return 1; +} diff --git a/utils/mxsh.cpp b/utils/mxsh.cpp new file mode 100644 index 00000000..61dd614d --- /dev/null +++ b/utils/mxsh.cpp @@ -0,0 +1,53 @@ +#include +#include +#include + +using namespace Maxsi; + +void command() +{ + printf("root@sortix / # "); + + const size_t commandsize = 128; + char command[commandsize + 1]; + size_t commandused = 0; + + while (true) + { + unsigned method = System::Keyboard::POLL; + uint32_t codepoint = System::Keyboard::ReceieveKeystroke(method); + + if ( codepoint == 0 ) { continue; } + if ( codepoint & Maxsi::Keyboard::DEPRESSED ) { continue; } + if ( codepoint >= 0x80 ) { continue; } + + if ( codepoint == '\b' ) + { + if ( 0 < commandused ) { printf("\b"); commandused--; } + continue; + } + + if ( commandsize <= commandused && codepoint != '\n' ) { continue; } + + char msg[2]; msg[0] = codepoint; msg[1] = '\0'; + printf(msg); + + if ( codepoint == '\n' ) { command[commandused] = '\0'; break; } + + command[commandused++] = codepoint; + } + + if ( command[0] == '\0' ) { return; } + + // Replace the current process with another process image. + Process::Execute(command, 0, NULL); + + // This is clever. This only happens if the program didn't change. + printf("%s: command not found\n", command); +} + +int main(int argc, char* argv[]) +{ + while ( true ) { command(); } +} + diff --git a/utils/uname.cpp b/utils/uname.cpp new file mode 100644 index 00000000..607ebe49 --- /dev/null +++ b/utils/uname.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char* argv[]) +{ + printf("Sortix\n"); + return 0; +}