mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:27:45 +00:00
A userspace process can now GPF and the OS goes on!
This is really rickety, but it kinda sorta works for my test GPF!
This commit is contained in:
parent
77299cf54d
commit
56c1f9db8e
8 changed files with 96 additions and 42 deletions
|
@ -3,25 +3,6 @@
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include "Syscall.h"
|
#include "Syscall.h"
|
||||||
|
|
||||||
struct RegisterDump {
|
|
||||||
WORD gs;
|
|
||||||
WORD fs;
|
|
||||||
WORD es;
|
|
||||||
WORD ds;
|
|
||||||
DWORD edi;
|
|
||||||
DWORD esi;
|
|
||||||
DWORD ebp;
|
|
||||||
DWORD esp;
|
|
||||||
DWORD ebx;
|
|
||||||
DWORD edx;
|
|
||||||
DWORD ecx;
|
|
||||||
DWORD eax;
|
|
||||||
DWORD eip;
|
|
||||||
WORD cs;
|
|
||||||
WORD __csPadding;
|
|
||||||
DWORD eflags;
|
|
||||||
} PACKED;
|
|
||||||
|
|
||||||
extern "C" void syscall_entry();
|
extern "C" void syscall_entry();
|
||||||
extern "C" void syscall_ISR();
|
extern "C" void syscall_ISR();
|
||||||
extern volatile RegisterDump* syscallRegDump;
|
extern volatile RegisterDump* syscallRegDump;
|
||||||
|
|
|
@ -185,11 +185,15 @@ void yield()
|
||||||
if (!scheduleNewTask())
|
if (!scheduleNewTask())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//kprintf("yield() jumping to new task: %x (%s)\n", current->farPtr().selector, current->name().characters());
|
||||||
|
switchNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void switchNow()
|
||||||
|
{
|
||||||
Descriptor& descriptor = getGDTEntry(current->selector());
|
Descriptor& descriptor = getGDTEntry(current->selector());
|
||||||
descriptor.type = 9;
|
descriptor.type = 9;
|
||||||
flushGDT();
|
flushGDT();
|
||||||
|
|
||||||
//kprintf("yield() jumping to new task: %x (%s)\n", current->farPtr().selector, current->name().characters());
|
|
||||||
asm(
|
asm(
|
||||||
"ljmp *(%%eax)\n"
|
"ljmp *(%%eax)\n"
|
||||||
::"a"(¤t->farPtr())
|
::"a"(¤t->farPtr())
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
BlockedSend = 4,
|
BlockedSend = 4,
|
||||||
BlockedSleep = 5,
|
BlockedSleep = 5,
|
||||||
Terminated = 6,
|
Terminated = 6,
|
||||||
|
Crashing = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RingLevel {
|
enum RingLevel {
|
||||||
|
@ -121,6 +122,7 @@ private:
|
||||||
extern void task_init();
|
extern void task_init();
|
||||||
extern void yield();
|
extern void yield();
|
||||||
extern bool scheduleNewTask();
|
extern bool scheduleNewTask();
|
||||||
|
extern void switchNow();
|
||||||
extern void block(Task::State);
|
extern void block(Task::State);
|
||||||
extern void sleep(DWORD ticks);
|
extern void sleep(DWORD ticks);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,10 @@ int kprintfInternal(PutChFunc putch, char* buffer, const char*& fmt, char*& ap)
|
||||||
ret += printHex(putch, bufptr, va_arg(ap, DWORD), 8);
|
ret += printHex(putch, bufptr, va_arg(ap, DWORD), 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
ret += printHex(putch, bufptr, va_arg(ap, int), 4);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
ret += printHex(putch, bufptr, va_arg(ap, int), 2);
|
ret += printHex(putch, bufptr, va_arg(ap, int), 2);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -26,6 +26,68 @@ WORD allocateGDTEntry()
|
||||||
return newGDTEntry;
|
return newGDTEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern volatile dword exception_state_dump;
|
||||||
|
extern volatile word exception_code;
|
||||||
|
asm(
|
||||||
|
".globl exception_state_dump\n"
|
||||||
|
"exception_state_dump:\n"
|
||||||
|
".long 0\n"
|
||||||
|
".globl exception_code\n"
|
||||||
|
"exception_code:\n"
|
||||||
|
".short 0\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
#define EH_ENTRY(ec) \
|
||||||
|
extern "C" void exception_ ## ec ## _handler(); \
|
||||||
|
extern "C" void exception_ ## ec ## _entry(); \
|
||||||
|
asm( \
|
||||||
|
".globl exception_" # ec "_entry\n" \
|
||||||
|
"exception_" # ec "_entry: \n" \
|
||||||
|
" pop exception_code\n" \
|
||||||
|
" pusha\n" \
|
||||||
|
" pushw %ds\n" \
|
||||||
|
" pushw %es\n" \
|
||||||
|
" pushw %fs\n" \
|
||||||
|
" pushw %gs\n" \
|
||||||
|
" pushw %ss\n" \
|
||||||
|
" pushw %ss\n" \
|
||||||
|
" pushw %ss\n" \
|
||||||
|
" pushw %ss\n" \
|
||||||
|
" popw %ds\n" \
|
||||||
|
" popw %es\n" \
|
||||||
|
" popw %fs\n" \
|
||||||
|
" popw %gs\n" \
|
||||||
|
" mov %esp, exception_state_dump\n" \
|
||||||
|
" call exception_" # ec "_handler\n" \
|
||||||
|
" popw %gs\n" \
|
||||||
|
" popw %fs\n" \
|
||||||
|
" popw %es\n" \
|
||||||
|
" popw %ds\n" \
|
||||||
|
" popa\n" \
|
||||||
|
" iret\n" \
|
||||||
|
);
|
||||||
|
|
||||||
|
EH_ENTRY(13)
|
||||||
|
|
||||||
|
void exception_13_handler()
|
||||||
|
{
|
||||||
|
auto& regs = *reinterpret_cast<RegisterDump*>(exception_state_dump);
|
||||||
|
kprintf("Process crash: %u(%s)\n", current->pid(), current->name().characters());
|
||||||
|
|
||||||
|
kprintf("exception code: %w\n", exception_code);
|
||||||
|
kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
|
||||||
|
kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
|
||||||
|
kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, regs.esp, regs.esi, regs.edi);
|
||||||
|
|
||||||
|
current->setState(Task::Crashing);
|
||||||
|
if (!scheduleNewTask()) {
|
||||||
|
kprintf("Failed to schedule a new task :(\n");
|
||||||
|
HANG;
|
||||||
|
}
|
||||||
|
|
||||||
|
switchNow();
|
||||||
|
}
|
||||||
|
|
||||||
#define EH(i, msg) \
|
#define EH(i, msg) \
|
||||||
static void _exception ## i () \
|
static void _exception ## i () \
|
||||||
{ \
|
{ \
|
||||||
|
@ -164,7 +226,7 @@ void idt_init()
|
||||||
registerInterruptHandler(0x0a, _exception10);
|
registerInterruptHandler(0x0a, _exception10);
|
||||||
registerInterruptHandler(0x0b, _exception11);
|
registerInterruptHandler(0x0b, _exception11);
|
||||||
registerInterruptHandler(0x0c, _exception12);
|
registerInterruptHandler(0x0c, _exception12);
|
||||||
registerInterruptHandler(0x0d, _exception13);
|
registerInterruptHandler(0x0d, exception_13_entry);
|
||||||
registerInterruptHandler(0x0e, _exception14);
|
registerInterruptHandler(0x0e, _exception14);
|
||||||
registerInterruptHandler(0x0f, _exception15);
|
registerInterruptHandler(0x0f, _exception15);
|
||||||
registerInterruptHandler(0x10, _exception16);
|
registerInterruptHandler(0x10, _exception16);
|
||||||
|
|
|
@ -75,3 +75,23 @@ void writeGDTEntry(WORD selector, Descriptor&);
|
||||||
|
|
||||||
/* Map IRQ0-15 @ ISR 0x50-0x5F */
|
/* Map IRQ0-15 @ ISR 0x50-0x5F */
|
||||||
#define IRQ_VECTOR_BASE 0x50
|
#define IRQ_VECTOR_BASE 0x50
|
||||||
|
|
||||||
|
struct RegisterDump {
|
||||||
|
WORD gs;
|
||||||
|
WORD fs;
|
||||||
|
WORD es;
|
||||||
|
WORD ds;
|
||||||
|
DWORD edi;
|
||||||
|
DWORD esi;
|
||||||
|
DWORD ebp;
|
||||||
|
DWORD esp;
|
||||||
|
DWORD ebx;
|
||||||
|
DWORD edx;
|
||||||
|
DWORD ecx;
|
||||||
|
DWORD eax;
|
||||||
|
DWORD eip;
|
||||||
|
WORD cs;
|
||||||
|
WORD __csPadding;
|
||||||
|
DWORD eflags;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
|
|
@ -63,25 +63,6 @@ asm(
|
||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
#define BASE_FREQUENCY 1193182
|
#define BASE_FREQUENCY 1193182
|
||||||
|
|
||||||
struct RegisterDump {
|
|
||||||
WORD gs;
|
|
||||||
WORD fs;
|
|
||||||
WORD es;
|
|
||||||
WORD ds;
|
|
||||||
DWORD edi;
|
|
||||||
DWORD esi;
|
|
||||||
DWORD ebp;
|
|
||||||
DWORD esp;
|
|
||||||
DWORD ebx;
|
|
||||||
DWORD edx;
|
|
||||||
DWORD ecx;
|
|
||||||
DWORD eax;
|
|
||||||
DWORD eip;
|
|
||||||
WORD cs;
|
|
||||||
WORD __csPadding;
|
|
||||||
DWORD eflags;
|
|
||||||
} PACKED;
|
|
||||||
|
|
||||||
void clock_handle()
|
void clock_handle()
|
||||||
{
|
{
|
||||||
IRQHandlerScope scope(IRQ_TIMER);
|
IRQHandlerScope scope(IRQ_TIMER);
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void user_main()
|
||||||
// Crash ourselves!
|
// Crash ourselves!
|
||||||
char* x = reinterpret_cast<char*>(0xbeefbabe);
|
char* x = reinterpret_cast<char*>(0xbeefbabe);
|
||||||
//*x = 1;
|
//*x = 1;
|
||||||
//HANG;
|
HANG;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// nothing?
|
// nothing?
|
||||||
Userspace::sleep(1 * TICKS_PER_SECOND);
|
Userspace::sleep(1 * TICKS_PER_SECOND);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue