Software Multitasking
Hi Lukem,
Could you please post some code? When exactly does the computer hang? Does bochs tell you *where* it hangs? How do you set up current_directory?
Cheers,
James
*PS: I haven't started the documentation just as yet, I have a million and one things to do atm, and haven't been able to get round to it! It'll get done eventually though!
Could you please post some code? When exactly does the computer hang? Does bochs tell you *where* it hangs? How do you set up current_directory?
Cheers,
James
*PS: I haven't started the documentation just as yet, I have a million and one things to do atm, and haven't been able to get round to it! It'll get done eventually though!
Mine is working now.. I used almost the same code JamesM posted earlyer:
I'm at work right now, but if someone wants it, i can post the source here
Code: Select all
void start_task(void (*func)(void*), void *arg)
{
if (fork() == 0)
{
func(arg);
kill_task();
for(;;);
}
}
sure, i set it up the same as you in paging.c
I took it out of the function so that i could analyse it line-by-line to see exactly where it was hanging.
Bochs reboots when i executes this, bochs dbg build pauses. I get this from the log file:
according to that CR3 is never being filled with the correct tablesPhysical value, as i dump this in the debugging screen. My OS reports it as: 0xc024b000
Code: Select all
printf("cloning directory:\n");
#endif
current_directory = clone_directory(kernel_directory);
#ifdef DEBUG
printf("cloning directory...ok!\n");
printf("switching to current_directory...");
#endif
#ifdef DEBUG
printf("updating cr3...");
#endif
/* This line is where it hangs */
__asm__ __volatile__("mov %0, %%cr3":: "r"(current_directory->tablesPhysical));
#ifdef DEBUG
printf("ok!\n");
#endif
unsigned int cr0;
__asm__ __volatile__("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
__asm__ __volatile__("mov %0, %%cr0":: "r"(cr0));
#ifdef DEBUG
printf("ok!\n");
#endif
I took it out of the function so that i could analyse it line-by-line to see exactly where it was hanging.
Bochs reboots when i executes this, bochs dbg build pauses. I get this from the log file:
Code: Select all
00026255628i[CPU0 ] protected mode
00026255628i[CPU0 ] CS.d_b = 32 bit
00026255628i[CPU0 ] SS.d_b = 32 bit
00026255628i[CPU0 ] | EAX=c0083000 EBX=00245000 ECX=000003d4 EDX=000003d5
00026255628i[CPU0 ] | ESP=00138e68 EBP=00101fbe ESI=00000012 EDI=0013f000
00026255628i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf SF zf af PF cf
00026255628i[CPU0 ] | SEG selector base limit G D
00026255628i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00026255628i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00026255628i[CPU0 ] | EIP=001024a9 (001024a9)
00026255628i[CPU0 ] | CR0=0x80000011 CR1=0 CR2=0x0013a070
00026255628i[CPU0 ] | CR3=0xc0083000 CR4=0x00000000
00026255628i[CPU0 ] >> push 0x0000000f : 6A0F
00026255628e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00026255628i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00026255628i[APIC0] local apic in CPU 0 initializing
00026255628e[CPU0 ] CPU_LOOP bx_guard.interrupt_requested=1
- Attachments
-
- Debugging printf's
- mutlitaskingerrorz.jpg (71.85 KiB) Viewed 2224 times
Hi,
Some food for thought:
CR3, is, as you may have guessed, a *physical* address. Therefore addresses like (both) 0xc0083000 and 0xc024b000 are both really quite wrong (unless bochs is emulating ~3GB of RAM!!).
That's because you used the address of tablesPhysical. tablesPhysical is an array that exists in virtual memory that details how the page tables exist in physical memory. current_directory->physicalAddr should give the physical address of tablesPhysical, so that is what should be loaded into cr3!
If that's still not working, could you post your modified code and also the clone_directory function if you have made any changes at all.
Cheers,
James
Some food for thought:
CR3, is, as you may have guessed, a *physical* address. Therefore addresses like (both) 0xc0083000 and 0xc024b000 are both really quite wrong (unless bochs is emulating ~3GB of RAM!!).
That's because you used the address of tablesPhysical. tablesPhysical is an array that exists in virtual memory that details how the page tables exist in physical memory. current_directory->physicalAddr should give the physical address of tablesPhysical, so that is what should be loaded into cr3!
If that's still not working, could you post your modified code and also the clone_directory function if you have made any changes at all.
Cheers,
James
ah, that makes perfect sense.
one of these days i hope to get out of the noobdom that lets these things slip by me.
i havn't changed the clone_directory code no, i have only ported everything so far, as theres no point fiddling until it works huh?
However the address i have was from this (clone_directory()):
So surely that should've given an accurate physical location, not something around the 3 gig mark.
EDIT: i have gotten what i believe to be the actual address of the directory by prefixing phys with &, this gives me: 0x13ce50
but this still hangs in exactly the same place =\[/code]
one of these days i hope to get out of the noobdom that lets these things slip by me.
i havn't changed the clone_directory code no, i have only ported everything so far, as theres no point fiddling until it works huh?
However the address i have was from this (clone_directory()):
Code: Select all
// Get the offset of tablesPhysical from the start of the page_directory_t structure.
unsigned int offset = (unsigned int)dir->tablesPhysical - (unsigned int)dir;
// Then the physical address of dir->tablesPhysical is:
dir->physicalAddr = phys + offset;
#ifdef DEBUG
printf("Physical address: 0x%x\n",dir->physicalAddr);
#endif
EDIT: i have gotten what i believe to be the actual address of the directory by prefixing phys with &, this gives me: 0x13ce50
but this still hangs in exactly the same place =\[/code]
I still have no idea what is going wrong here, iv seperated out each individual part of the process and debugged and analysed exactly whats going on, and i havn't made any progress.
All i know is that it hangs when you try to switch to the current_directory.
also... at one point it adds:
getting 0x67d40 + 0x1000. This should surely be 0x8d40? it gives 0x6bd40.
i have tried hardcoding this but it makes no difference, still hangs. so i have no idea what the problem is.
All i know is that it hangs when you try to switch to the current_directory.
also... at one point it adds:
Code: Select all
unsigned int offset = (unsigned int)current_directory->tablesPhysical - (unsigned int)current_directory;
i have tried hardcoding this but it makes no difference, still hangs. so i have no idea what the problem is.
i finally got it working, it took a lot of rejigging my kernel, but its very easy to customise, and im implementing my second scheduler now.
I was wondering if anybody has a link to some information on virtual8086 tasks using software multitasking?
Also, on a slightly different note, how do people stop user programs accessing hardwear directly, or stop it executing say CLI, as then my multitasking would die.
I was wondering if anybody has a link to some information on virtual8086 tasks using software multitasking?
Also, on a slightly different note, how do people stop user programs accessing hardwear directly, or stop it executing say CLI, as then my multitasking would die.
That would be processor ring levels. Load your apps in Ring 3 and you won't have that problemlukem_95 wrote:Also, on a slightly different note, how do people stop user programs accessing hardwear directly, or stop it executing say CLI, as then my multitasking would die.
The cake is a lie | rackbits.com
-
- Member
- Posts: 89
- Joined: Tue Feb 26, 2008 10:47 am
- Location: Sweden
I get someting simmilar to razor-x error.
The tasks switch allright and I can call other functions after switching, but when I try to return from the fork() function, the child process generates a fault.
Any ideas?
I don't have my code here, right now, nor the actual error, but I'll post it as soon as I get home.
/Thomas
The tasks switch allright and I can call other functions after switching, but when I try to return from the fork() function, the child process generates a fault.
Any ideas?
I don't have my code here, right now, nor the actual error, but I'll post it as soon as I get home.
/Thomas
-
- Member
- Posts: 89
- Joined: Tue Feb 26, 2008 10:47 am
- Location: Sweden
Sorry for not having this before.
Here is my code for switching task and fork-ing.
And here is how it is called from main.
It prints the "!-returning" message, but then it stops with a page fault at 0xE040DC0C with EIP 0x1F82. Neither of which has anything to do with anything I am doing.
To me it doesn't realy seem like the problem lukem_95 was having.
Note also that even using the same page table for both processes (not changeing it) gives the same error.
/Thomas
Here is my code for switching task and fork-ing.
Code: Select all
void switch_task()
{
k_puts("Switching");
if (!current_task)
return;
unsigned int esp, ebp, eip;
asm volatile("mov %%esp, %0" : "=r" (esp));
asm volatile("mov %%ebp, %0" : "=r" (ebp));
eip = read_eip();
if (eip == 0x12345)
{
return;
}
current_task->eip = eip;
current_task->esp = esp;
current_task->ebp = ebp;
current_task = current_task->next;
if (!current_task) current_task = ready_queue;
eip = current_task->eip;
esp = current_task->esp;
ebp = current_task->ebp;
current_directory = current_task->page_directory;
asm volatile("cli");
asm volatile(" \
mov %0, %%ecx; \
mov %1, %%esp; \
mov %2, %%ebp; \
mov $0x12345, %%eax; \
jmp *%%ecx; " : : "r" (eip), "r"(esp), "r"(ebp));
switch_page_directory(current_directory);
asm volatile("sti");
/**/
}
int fork()
{
asm volatile("cli");
task_t *parent_task = (task_t*)current_task;
page_directory_t *directory = clone_directory(current_directory);
task_t *new_task = (task_t*)kmalloc(sizeof(task_t));
new_task->id = next_pid++;
new_task->esp = new_task->ebp = 0;
new_task->eip = 0;
new_task->page_directory = directory;
new_task->next = 0;
task_t *tmp_task = (task_t*)ready_queue;
while(tmp_task->next)
tmp_task = tmp_task->next;
tmp_task->next = new_task;
unsigned int eip = read_eip();
unsigned int esp; asm volatile("mov %%esp, %0" : "=r" (esp));
unsigned int ebp; asm volatile("mov %%ebp, %0" : "=r" (ebp));
if (current_task == parent_task)
{
new_task->esp = esp;
new_task->ebp = ebp;
new_task->eip = eip;
asm volatile("sti");
return new_task->id;
} else {
k_printf("!-returning!",cursor_y, cursor_x);
return 0;
}
}
Code: Select all
if (fork()== 0)
{
k_puts("FORKED!");
for(;;);
}
To me it doesn't realy seem like the problem lukem_95 was having.
Note also that even using the same page table for both processes (not changeing it) gives the same error.
/Thomas