So... häng leider immer noch am Multitasking
Hab versucht das Prinzip der Tutorials in meinen Kernel einzubauen, jedoch komm ich mal wieder nicht weiter und wäre froh wenn ihr mir helfen könnt!
Hier ist mein aktueller Stand, vllt. hab ich ja etwas grundlegendes übersehen oder falsch verstanden:
Die ISR:
[GLOBAL _hwint0]
[GLOBAL _hwint1]
[extern _switch_task]
[extern _p]
; this is in our C++ code
[extern _keyboard_int]
; ***************************
_hwint0:
;save all registers
pushad
mov eax,[_p] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
call _switch_task
CLEAR_MASTER_PIC
;restore all registers
mov eax,[_p] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
popad
iret
Der C/C++ Code:
typedef unsigned char uchar_t; // -->Length: 8 bit
typedef unsigned short ushort_t; // -->Length: 16 bit
typedef unsigned int uint_t; // -->Length: 32 bit
typedef unsigned long ulong_t; // -->Length: 64 bit
typedef struct {
uint_t prozess_esp; //actual position of esp
uint_t prozess_ss; //actual stack segment.
uint_t prozess_kstack; //stacktop of kernel stack
uint_t prozess_ustack; //stacktop of user stack
uint_t prozess_cr3;
uint_t prozess_number;
uint_t prozess_parent;
uint_t prozess_owner;
uint_t prozess_group;
uint_t prozess_timetorun;
uint_t prozess_sleep;
uint_t prozess_priority;
uint_t prozess_filehandle;
//console_t *prozess_console;
//memtree_t *vmm_alloc; //memory management info concerning the process
//- all its allocated virtual memory
uchar_t prozess_name[32];
} prozess_t;
typedef void (*entry_t)(void);
extern "C" void switch_task(void);
extern "C" void hwint0();
extern "C" prozess_t *p;
prozess_t *p;
void switch_task(void)
{
kernel->tasks->switch_task();
}
class_multitasking::class_multitasking()
{
p=&prozess[0];
current_p=0;
task_count=1;
}
class_multitasking::~class_multitasking() {}
void class_multitasking::switch_task()
{
++current_p;
if(current_p >= task_count)current_p=0;
p=&prozess[current_p];
//debug
char buffer[32];
itoa(current_p,buffer,10);
std::cout
<< "\nTask: "
<< buffer
<< "\n";
}
prozess_t* class_multitasking::task_anlegen(entry_t entry)
{
++task_count;
//filling in the kstack for start up:
uint_t *stacksetup; //temporary pointer
stacksetup=((uint_t*)malloc(5000))+5000;
*stacksetup--;
*stacksetup--=0x0202;
*stacksetup--=0x08;
*stacksetup--=(uint_t)entry; //This is the adress of the process' entry point (z.b. main());
*stacksetup--=0; //ebp
*stacksetup--=0; //esp
*stacksetup--=0; //edi
*stacksetup--=0; //esi
*stacksetup--=0; //edx
*stacksetup--=0; //ecx
*stacksetup--=0; //ebx
*stacksetup--=0; //eax
//filling in the struct.
prozess[task_count-1].prozess_esp=(uint_t)stacksetup;
}
Der Code für das Task-switching (::switch_task() usw.) ist nicht besonders intelligent gemacht^^
soll ja aber auch nur zum test dienen und zumindest prinzipiell funktionieren;-)
Das Ergebnis:
Nach dem Start des Kernels wird natürlich dauerhaft "Task: 0" ausgegeben... funzt also soweit! wenn ich nun einen neuen Task anlege mit: kernel->tasks->task_anlegen(test_task);
Dann sehe ich auch noch einmal "Task: 1" danach kommt es zu:
"Virutal machine kernel stack fault (hardware reset"
"The virtual machine just suffered a stack fault in kernel mode. On a real computer, this would amount to reset of the processor...."
Wie ich schon glaube rausgefunden zu haben geschieht dies genau nach dem IRET also wenn der Code des neuen Tasks ausgeführt werden soll!
Der neue Task:
void test_task();
void test_task()
{
std::cout << "XXXXXXXXXXXX-NEWTASK-XXXXXXXXXXXXXXX";
}
Achja wenn es euch lieber ist dass ich für dieses Prob. ein eigenes Thema eröffne sagt es bitte