Userland tasks..

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
worldsapart
Member
Member
Posts: 36
Joined: Sat Jan 03, 2009 4:12 am

Userland tasks..

Post by worldsapart »

Hi,

I have rite now successfully started all the APs and and have got the BSP to send IPIs to the APs and they acknowledge the BSP with another interrupt. That'll b useful later.

Now I was trying look up some stuff on setting up user level tasks. I really didnt get much from the manuals or from the WIKI. Right now I am in ring 0 so how do I go about setting up a task that runs in ring 3? Hope you guys can help. I have the TSS set up and have loaded the task register for each CPU. Now I want to run a task at user-level on each CPU. So how do i jump from Ring 0 to Ring 3?

Thanks.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Userland tasks..

Post by System123 »

Once your TSS is setup switching is quite easy. All you need to do is create a procedure that makes the cpu think you have just been interrupted. This is done so that you can set the CS register and jump back to the exectution point with the correct CS, and DS register values.

Code: Select all

[Global UserMode]

UserMode:
pop ecx          ; pop the eip value from the stack for use later
cli                

mov ax, 0x23  ; Load registers with the correct GDT segments values
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax


push 0x23        ; push the DS value to the stack
push esp          ; push the current esp value to the stack
pushf                ; push flags to the stack

pop eax                 ; enable interrupts by ORing the flags
or eax, 0x200
push eax

push 0x1B          ; Push CS value to the stack
push ecx            ; Push EIP value to the stack
iret                      ; Return from 'interrupt' into User Mode (Ring 3)
Gizmic OS
Currently - Busy with FAT12 driver and VFS
worldsapart
Member
Member
Posts: 36
Joined: Sat Jan 03, 2009 4:12 am

Re: Userland tasks..

Post by worldsapart »

Hey,

Thanks for that reply. I think I understand what's going on. But just to be sure... the 0x23 value... if my gdt is as below:

Code: Select all

gdt:
	.long 0 /* null */
	.long 0
	.long 0x0000FFFF /* kernel code */
	.long 0x00CF9A00
	.long 0x0000FFFF /* kernel data */
	.long 0x00CF9200
        .long 0x0000FFFF /* user code */
        .long 0x00CBFA00
        .long 0x0000FFFF /* user data */
        .long 0x00CBF200
	.long 0x400000FF /* TSS x16 */
	.long 0x00008901
	.long 0x410000FF
	.long 0x00008901
	.long 0x420000FF
	.long 0x00008901
	.long 0x430000FF
	.long 0x00008901
	.long 0x440000FF
	.long 0x00008901
	.long 0x450000FF
	.long 0x00008901
	.long 0x460000FF
	.long 0x00008901
	.long 0x470000FF
	.long 0x00008901
	.long 0x480000FF
	.long 0x00008901
	.long 0x490000FF
	.long 0x00008901
	.long 0x4A0000FF
	.long 0x00008901
	.long 0x4B0000FF
	.long 0x00008901
	.long 0x4C0000FF
	.long 0x00008901
	.long 0x4D0000FF
	.long 0x00008901
	.long 0x4E0000FF
	.long 0x00008901
	.long 0x4F0000FF
	.long 0x00008901
What is the corresponding value that I must be entering? Am sorry for the trouble. Thanks again.

David.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Userland tasks..

Post by xenos »

worldsapart wrote:

Code: Select all

gdt:
	.long 0 /* null */
	.long 0
	.long 0x0000FFFF /* kernel code */
	.long 0x00CF9A00
	.long 0x0000FFFF /* kernel data */
	.long 0x00CF9200
        .long 0x0000FFFF /* user code */
        .long 0x00CBFA00
        .long 0x0000FFFF /* user data */
...
Since your user data selector is 0x20, you have to push 0x23 (selector 0x20 with RPL = 3) on the stack, too.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
worldsapart
Member
Member
Posts: 36
Joined: Sat Jan 03, 2009 4:12 am

Re: Userland tasks..

Post by worldsapart »

Thanks for clearing that up. Let me just try and see if I got this...

I am coding in C mostly except for the bootloaders and interrupt handlers. So basically if I have the above assembly code ( the UserMode handler ) and I do a call from Ring 0 like shown below:

Code: Select all

void task()
{
     UserMode();
     while(1);
}

/* Somewhere in my kernel ring 0 code */
task();

So after the return from UserMode() the while loop runs in Ring 3?? Did I get this right? Thanks again for the help.
Post Reply