OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 13, 2021 2:52 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 67 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject:
PostPosted: Fri Jun 01, 2007 4:52 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...
Now I've changed my code a little bit my multitasking consists of two tasks
main() and task() and both they are PL0.
when I enabled the VM bit in EFLAGS I didn't get any exceptions, but
when I made a long call "lcall" to the selector of the virtual task
unfortunately I got general protection fault...
here's my code and an IMG, also please note paging isn't enabled.


Thanx.


Attachments:
File comment: IMG
a.tar.gz [46.97 KiB]
Downloaded 21 times
File comment: kernel
knl.tar.gz [15.03 KiB]
Downloaded 22 times
Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 01, 2007 5:44 pm 
Offline
Member
Member

Joined: Sun Jan 14, 2007 9:15 pm
Posts: 2566
Location: Sydney, Australia (I come from a land down under!)
First of all - get a debugger.

Second - GPFs in Virtual Mode occur on privileged instructions. Read the intel manuals on virtual mode and you can see what you need to emulate as a virtual mode monitor.

Edit: Downloaded your image, running it works alright, apart from the GPF. I have a few questions: is your task under the 1MB mark? Do you have a mode monitor that emulates privileged instructions (read the Intel manual, and search Google). You can't expect us to upload fixed code. You have to do this yourself.

It took me a month. It's worth doing it yourself.

As I type, this is what I notice in my Bochs log:
Code:
call_protected: EIP not within CS limits


You cannot switch tasks via a long call in virtual mode (read the manuals). Why can't you use preemptive tasking, whereby a timer tick allows a reschedule to occur. What you're doing now looks to me like cooperative tasking.

_________________
Pedigree | GitHub | Twitter | LinkedIn


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 12:47 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...

Quote:
is your task under the 1MB mark


how can I make sure that my task is 1MB mark?

Quote:
You can't expect us to upload fixed code.


I'm not, I just need your opinion and experience to explain to me why
my virtual task doesn't work.

Thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 4:36 pm 
Offline
Member
Member

Joined: Sun Jan 14, 2007 9:15 pm
Posts: 2566
Location: Sydney, Australia (I come from a land down under!)
When I was testing virtual mode, this is what I did:

Code:
char* data = (char*) 0x1000; // pointer to location < 1MB
*dat++ = 0xCD;
*dat++ = 0x03; // int 0x03
*dat++ = 0xEB;
*dat++ = 0xFE; // jmp $
/** create task, set base to 0x1000 **/


If you are using a C function, you just need to get the pointer to the function and copy enough of it's code to a location under 1 MB to be able to have it run... something like
Code:
memcpy( (void*) 0x1000, &task1, 1024 ); // you could also run until you found 'ret' (is it C3, or C9? keep getting Z80 opcodes mixed up...)


Good luck!

_________________
Pedigree | GitHub | Twitter | LinkedIn


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 5:22 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...
unfortunately it didn't work I got general protection fault again.
I'm starting to pull my hair up......I'm so confused,I don't know
what the wrong I'm doing?????? now I believe enabling virtual mode
harder than brain surgery. :( :( :(
So now I'm sure that my virtual task is marked 1MB,what else should
I take care of?
guys I really need your help.

Thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 6:58 pm 
Offline
Member
Member

Joined: Sun Jan 14, 2007 9:15 pm
Posts: 2566
Location: Sydney, Australia (I come from a land down under!)
As I've said so many times, GPF comes from a privileged instruction!

Find out whether you're in virtual mode on a GPF, then read in the opcode from the CS:EIP that the fault occurred at. Handle the opcodes that Intel says are privileged. Return (after incrementing EIP).

In the least, make your GPF handler print out CPU state before the crash and the opcodes at the last executed location.

_________________
Pedigree | GitHub | Twitter | LinkedIn


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 4:37 am 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...
First of all @pcmattman thank you for your help.
Now my task doesn't have any instructions just an infinit loop.
but as soon as I make the call to the selector of the virtual task
I get general protection fault.
Also Intel manual says:

Quote:
Task switch when the VM flag is set to 1 in the EFLAGS register image stored in the TSS
for the task. Here the task switch can be initiated in either of two ways:
— A CALL or JMP instruction.
— An IRET instruction, where the NT flag in the EFLAGS image is set to 1.


I'm using CALL instruction so this should be fine,my EFLAGS value is 0x23202L
so the VM bit is set,my task is 1MB marked,Also I'm sure about my multitasking.
what's wrong with my code....

Thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 7:00 am 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
While debugging your code in bochs I have noticed that it throws the gpf right at the switch to the task, not after trying to execute any code. So the problem must be in the values that you are putting in the tss. Also, all code that is going to be run in virtual mode must be below the 1mb mark. Not at it not above it. Since your whole kernel is at the 1mb mark the function you are trying to call must be above the 1mb mark. Have you tried what pcmattman says about using memcpy to get the code below the 1mb mark?

Question for someone who knows, Aren't the values entered into the TSS for segment descriptors supposed to be real mode values and not segment descriptors?

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 8:42 am 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...

Quote:
I have noticed that it throws the gpf right at the switch to the task

This means it throws the gpf when I do the long call "lcall" to the
selector of my virtual task

Quote:
So the problem must be in the values that you are putting in the tss.


here are my values:
Code:
i=0;
for(i;i<max_tasks;i++)
  {
   tss[i].trace=0;
   tss[i].io_map_addr=sizeof(TSS);
   tss[i].ldtr=0;
   if (i) {
   tss[i].fs=tss[i].gs=0;
   tss[i].ds=tss[i].es=tss[i].ss=0x10;
   tss[i].cs=0x8;
   tss[i].eflags=0x23202L ;      //VM=1 ,IOPL=3, interrupts are enabled
   tss[i].esp=(dword)&task_stack[i];   // sp points to task stack top /
   tss[i].ss0=0x10;
   tss[i].esp0=(dword)&pl0_stack[i];   //stack for kernel
   }
  }
tss[1].eip=(dword)&task;      //my virtual task

memcpy( (void*) 0x1000, &task, 1024 );

ltr(0x28);            //selector of the main()


Have you tried what pcmattman says about using memcpy to get the code below the 1mb mark?
Yes,I did.

Thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 9:50 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
abuashraf wrote:
Code:
tss[1].eip=(dword)&task;      //my virtual task

memcpy( (void*) 0x1000, &task, 1024 );


frank wrote:
Have you tried what pcmattman says about using memcpy to get the code below the 1mb mark?

Yes,I did.


I think he also meant: copy it there _and_ set the eip in the task structure to point to the new address of the task's code.

Code:
tss[1].eip = 0x1000;


and link your 'task' program to run at 0x1000?

Regards,
John.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 10:38 am 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...

I tried tss[1].eip = 0x1000;
but this time I got Invalid opcode exception. :( :( :( :(
I'm so grateful for your help guys,
this my EIP=00100fc2 after the exception , using QEMU monitor.
here's an updated IMG file it might help,I don't know

:?: :?: :?: :?:

Thanx.


Attachments:
File comment: IMG
a.tar.gz [47.49 KiB]
Downloaded 19 times
Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 11:16 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
Okay, so I just tested it.

Your code successfully jumps to 0x1000 with VM set.

Unfortunately, the contents at 0x1000 are a NOP followed by lots of zeros? Does your memcpy work? Is the location you're copying from correct?

Regards,
John.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 12:37 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...

Quote:
Does your memcpy work?


Here's my memcpy:

Code:
unsigned char *memcpy(unsigned char *dest,unsigned char *src,int count)
{
const char *s = (const char *)src;
char *d = (char *)dest;
for(; count!=0; count--) *d++ = *s++;
return dest;
}


Quote:
Is the location you're copying from correct?


Yes,I think so,the *src is &task "address of my virtual task"
Would you please take a look at init_task it may has some bugs
Code:
void init_task()
{
disable();
unsigned int i=0;
for(i;i<max_tasks;i++)
  {
   tss[i].trace=0;
   tss[i].io_map_addr=sizeof(TSS);
   tss[i].ldtr=0;
   if (i) {
   tss[i].fs=tss[i].gs=0;
   tss[i].ds=tss[i].es=tss[i].ss=0x10;
   tss[i].cs=0x8;
   tss[i].eflags=0x23202L ;      //VM=1,IOPL=3,interrupts are enabled
   tss[i].esp=(dword)&task_stack[i];   //points to task() stack top
   tss[i].ss0=0x10;
   tss[i].esp0=(dword)&pl0_stack[i];   //stack for kernel
   }
  }
memcpy( (void*) 0x1000, &task, 1024 );
tss[1].eip=0x1000;
ltr(0x28);
enable();
}


Thanx


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 2:48 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
You are supposed to use real mode values for the segment descriptors. Right now you are using 0x8 for cs. When you do real mode addressing the final address ends up being 0x1080 (0x8 * 16 + 0x1000). Try it with 0 as the value you enter for all of the segment registers cs, ds, es, fs, gs, and ss. That will fix the problem.

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 3:53 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 29, 2006 8:59 am
Posts: 397
Hi...

Once again it didn't work Bochs gave me a panic message:
interrupt(): SS selector null
Also QEMU just halt, I couldn't dump any values ... :( :(
so here's another updated IMG ,guys we are so close
I'm really grateful for your help.


Thanx.


Attachments:
File comment: IMG
a.tar.gz [47.48 KiB]
Downloaded 21 times
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 67 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group