Switching ring 0 <--> ring 3?

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
junkoi
Member
Member
Posts: 63
Joined: Wed Jan 23, 2008 8:55 pm

Switching ring 0 <--> ring 3?

Post by junkoi »

Hi,

I am looking for a tutorial that deals with switching from ring 0 to ring 3 (and back). Anybody knows if there is any tutorial like that around?

Many thanks,
Jun
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi,

This sort of gives me a kick to start work on the documentation for my user mode tutorial. I'll do some writing now - the link to the download of documented code (tutorial style) is here.

Cheers,

James
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi,

After a few hours writing, draft version is now online here. I'm not fully happy with it as yet and I will add some spit and polish to it - there are also a few errata which magically appear fixed in this tutorial but have not been backported to the old ones yet - I need to do that.

Hope it helps, do give me a shout if you have any questions!

Cheers,

James
junkoi
Member
Member
Posts: 63
Joined: Wed Jan 23, 2008 8:55 pm

Post by junkoi »

James, excellent tutorial!!! Seriously, have you ever considered writting a book? You have a great ability, that is explain things in easy way. Believe me, not everybody can do that!

I spot some typos in the below code (syscall_handler() function)

.....
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
" : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location));

You must intend to pop %ecx, %edx, %esi, %edi here.

Keep up the good work. Your tutorials is excellent!!!

Thanks,
Jun
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

junkoi wrote:James, excellent tutorial!!! Seriously, have you ever considered writting a book? You have a great ability, that is explain things in easy way. Believe me, not everybody can do that!

I spot some typos in the below code (syscall_handler() function)

.....
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
" : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location));

You must intend to pop %ecx, %edx, %esi, %edi here.

Keep up the good work. Your tutorials is excellent!!!

Thanks,
Jun
Hi,

Thanks very much! :oops:

Actually, it doesn't matter what registers we pop to there as long as we pop to somewhere! The important thing is removing the items from the stack. Their values we no longer care about.

Cheers,

James
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

looks good, i'll read it properly at some point.

I implemented this in my OS in a similar (but probably less efficiant) way to you, so i may have a go at using some of your ideas :)
~ Lukem95 [ Cake ]
Release: 0.08b
Image
junkoi
Member
Member
Posts: 63
Joined: Wed Jan 23, 2008 8:55 pm

Post by junkoi »

JamesM wrote:
junkoi wrote:James, excellent tutorial!!! Seriously, have you ever considered writting a book? You have a great ability, that is explain things in easy way. Believe me, not everybody can do that!

I spot some typos in the below code (syscall_handler() function)

.....
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
" : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location));

You must intend to pop %ecx, %edx, %esi, %edi here.

Keep up the good work. Your tutorials is excellent!!!

Thanks,
Jun
Hi,

Thanks very much! :oops:

Actually, it doesn't matter what registers we pop to there as long as we pop to somewhere! The important thing is removing the items from the stack. Their values we no longer care about.
James
That is true. I missed that we have no output from the inline code, except %eax.

A question: your code switch from ring 0 to ring 3 using IRET. I wonder if Linux uses the same way to switch from ring 0 to ring 3? Maybe that is how they execute /sbin/init to give control to ring 3?

Cant wait for your next tutorials!

Thanks,
Jun
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Post by piranha »

A question: your code switch from ring 0 to ring 3 using IRET. I wonder if Linux uses the same way to switch from ring 0 to ring 3? Maybe that is how they execute /sbin/init to give control to ring 3?
......The init program deals with runlevels, not rings. Those are 2 completely different subjects.

Runlevels are just what stuff is started.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

junkoi wrote: A question: your code switch from ring 0 to ring 3 using IRET. I wonder if Linux uses the same way to switch from ring 0 to ring 3? Maybe that is how they execute /sbin/init to give control to ring 3?
Hi,

IRET is the only way on x86 to change to ring 3. As piranha pointed out, INIT deals with runlevels which are linux specific.

Cheers,

James
junkoi
Member
Member
Posts: 63
Joined: Wed Jan 23, 2008 8:55 pm

Post by junkoi »

You missed my point. No, I dont mistake ring and level stuffs. My question is "Is this technique (IRET to return to ring 3 from ring 0) the way Linux gives control to /sbin/init, which is the first ring 3 process?"

Thanks,
Jun
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

junkoi wrote:You missed my point. No, I dont mistake ring and level stuffs. My question is "Is this technique (IRET to return to ring 3 from ring 0) the way Linux gives control to /sbin/init, which is the first ring 3 process?"

Thanks,
Jun
Hi,

Yes. IRET is the only method of switching from ring0 to 3 on x86.

Cheers,

James
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

JamesM wrote:IRET is the only method of switching from ring0 to 3 on x86.
I expected a bit better from you - there are many more alternatives. IRET is the most used one though:
  • IRET
  • Sysret
  • Sysexit
  • Far jump/far call using TSS
  • SMM, VM extensions, Loadall etc.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Combuster wrote:
JamesM wrote:IRET is the only method of switching from ring0 to 3 on x86.
I expected a bit better from you - there are many more alternatives. IRET is the most used one though:
  • IRET
  • Sysret
  • Sysexit
  • Far jump/far call using TSS
  • SMM, VM extensions, Loadall etc.
Point taken - I've never investigated SMM etc. But I purposely avoided using sysexit as it's not available on all systems, and sysret is only on x86_64...
junkoi
Member
Member
Posts: 63
Joined: Wed Jan 23, 2008 8:55 pm

Post by junkoi »

Combuster wrote:
JamesM wrote:IRET is the only method of switching from ring0 to 3 on x86.
I expected a bit better from you - there are many more alternatives. IRET is the most used one though:
  • IRET
  • Sysret
  • Sysexit
  • Far jump/far call using TSS
  • SMM, VM extensions, Loadall etc.
Interesting! Can you elaborate about the "Far jmp/call using TSS"?

Thanks,
Jun
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

This is basically hardware task switching (which is covered in the Intel Manuals in some depth). You do a far jump using the TSS descriptor as your segment selector. e.g. If you jump to PMode, you probably do:

Code: Select all

jmp 0x08:PModeFunction
Whereas here, if the TSS is your 5th GDT entry, you do:

Code: Select all

jmp 0x28:0x00000000
The offset is ignored by the CPU.

Cheers,
Adam
Post Reply