flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > [SOLVED] Switching from ring 0 to ring 3 |
Author |
|
ManOfSteel 21 Dec 2008, 10:31
PM is very strict. It could be anything anywhere in your code.
First, try ORing your stack and code selectors with 11b for ring 3 RPL (pushd 0xXX or 3). |
|||
21 Dec 2008, 10:31 |
|
calpol2004 21 Dec 2008, 16:19
It could quite possibly be a wrongly flipped bit in my GDT, but is what im doing the right method?
is setting up a TSS required to switch from 0 to 3? is using iret with the stack frame im using a valid way of switching? From what i can tell i need to set up a TSS. Because when you ring switch, the cpu will try and use one if you have one or not for some things. For example when switching from ring 3 to ring 0 (not sure if this is the case for sysenter) the cpu will look into the selector stored in TR and then load esp and ss from the structure the selector points to. I'm curious to whether i need a valid Task selector and TSS struct setup before i can switch from ring 0 to ring 3? All help appreciated (now checking my selectors bit bit...). Cheers, Cal. Last edited by calpol2004 on 21 Dec 2008, 17:11; edited 5 times in total |
|||
21 Dec 2008, 16:19 |
|
calpol2004 21 Dec 2008, 16:37
Okay i setup from what i can tell is a valid TSS:
TSS Selector: Code: ;0x0067 is Size of TSS structure - 1 ;im using using lower 16 bits of base address but *for now* the the TSSData is being stored under the first 64kb of memory. TSS dw 0x0067,TSSData,0x8900,0x0040 ;0x28 TSS structure (only iomap, esp0 and ss0 are set): Code: ;Only used to switch stack pointer when switching ring 3 -> 0 TSSData: dw 0 ;link dw 0 ;link_h dd STACK_LOCATION+STACK_SIZE ;SET - esp to load on ring switch to 0 dw 0x10,0 ;SET - ss to load on ring switch to 0 dd 0 ;esp1 dw 0,0 ;ss1,ss1_h dd 0 ;esp2 dw 0,0 ;ss2,ss2_h dd 0 ;cr3 dd 0 ;eip dd 0 ;eflags dd 0 ;eax dd 0 ;ecx dd 0 ;edx dd 0 ;ebx dd 0 ;esp dd 0 ;ebp dd 0 ;esi dd 0 ;edi dw 0,0 ;es,es_h dw 0,0 ;cs,cs_h dw 0,0 ;ss,ss_h dw 0,0 ;ds,ds_h dw 0,0 ;fs,fs_h dw 0,0 ;gs,gs_h dw 0,0 ;ldt,ldt_h dw 0 ;trap dw 104 ;iomap ;SET - An offset from start of tss to a iomap - i set io map outside of tss so if you try and use I/O the cpu will check this and cause the GPF because it points outside. Load TR register: Code: mov eax,0x28 ;load task register with task selector (only used for stack-switch) ltr ax Still can't switch. Is there something im missing here? |
|||
21 Dec 2008, 16:37 |
|
Japheth 21 Dec 2008, 16:53
calpol2004 wrote:
IIRC no. However, without a TSS and TR loaded with a valid descriptor you won't be able to switch back to ring 0. So interrupts must remain disabled in ring 3. Best is to make a TSS and load TR. Just the values for SS:ESP for ring 0 must be set in the TSS. calpol2004 wrote:
Yes. You can use IRET or RETF (with RETF, there is no value for the EFLAGS register expected onto the stack). Did you try ManOfSteels hint? It's important that CS (and IIRC also SS) is loaded with a selector with RPL=3. |
|||
21 Dec 2008, 16:53 |
|
calpol2004 22 Dec 2008, 03:08
Checked my GDT Entries, nothing wrong with them. My ring 3 selectors are simply my ring 0 selectors but with bits 45 and 46 set (RPL bits). The ring 0 selectors work, im able to enter protected mode with them.
Code: KernelCode dq 0000000011001111100110100000000000000000000000001111111111111111b KernelData dq 0000000011001111100100100000000000000000000000001111111111111111b UserCode dq 0000000011001111111110100000000000000000000000001111111111111111b UserData dq 0000000011001111111100100000000000000000000000001111111111111111b Ive made a little "demo" (below) with the minimun code needed to do the ring switch. Im totally stumped. If all thats required is to change the RPL bits to 3 then my GDT entries are definetly correct, in which case switching into PMODE successfuly and doing the ring switch almost directly after should work. I just know its got to be something stupidly obvious that perhaps you assumed id done or a really hard to find small error thats doing this. Driving me insane, i can't make any progress at all until i can switch to ring 3, someone must have a snippet of code from their OS which switches to ring 3 or a user level GDT entry i could test. Really need your help. Cal. Code: ;##########################################################; ; Initialize ; ;##########################################################; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 16bit Segments ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use16 org 0x7E00 cli xor eax,eax ;setup segments mov ds,ax mov es,ax mov ax,0x90000/16 ;what sp counts down too, divide by 16 as segments are always *16 when absolute mov ss,ax mov sp,0xFFFF ;sp is offset from ss, gets closer to ss as you push more stuff sti ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Enable A20 Gate ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov al,0xD0 ;send read output port command out 0x64,al @@: ;wait for keyboard in al,0x64 test eax,2 jnz @B in al,0x60 ;read input buffer and store on stack. This is the data read from the output port push eax @@: ;wait for keyboard in al,0x64 test eax,2 jnz @B mov eax,0xD1 ;send write output port command out 0x64,al @@: ;wait for keyboard in al,0x64 test eax,2 jnz @B pop eax ;pop the output port data from stack and set bit 1 (A20) to enable or eax,2 out 0x60,al ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;PMODE & Disable Interrupts ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cli lgdt [GDTR] ;load Global Descriptor Table mov eax,cr0 or eax,1 mov cr0,eax ;set protected mode bit jmp 0x8:@F ;far jump to set cs @@: use32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set Kernel Selectors ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov eax,0x10 ;kernel data selector mov ds,ax mov ss,ax mov es,ax mov esp,0x9FFFF ;start counting down from top of stack, no limits ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Jump to ring 3 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pushd 0x20 pushd 0x9FFFF pushd 0 ;interrupts are off pushd 0x18 pushd @F iret @@: mov ah,7 mov al,'a' mov [0xB8000],ax jmp $ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;GDT ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GDTR: dw GDT_End-GDT-1 dd GDT GDT: Null dq 0000000000000000000000000000000000000000000000000000000000000000b KernelCode dq 0000000011001111100110100000000000000000000000001111111111111111b KernelData dq 0000000011001111100100100000000000000000000000001111111111111111b UserCode dq 0000000011001111111110100000000000000000000000001111111111111111b UserData dq 0000000011001111111100100000000000000000000000001111111111111111b GDT_End: Last edited by calpol2004 on 22 Dec 2008, 03:27; edited 1 time in total |
|||
22 Dec 2008, 03:08 |
|
Japheth 22 Dec 2008, 03:24
calpol2004 wrote: Checked my GDT Entries, nothing wrong with them. My ring 3 selectors are simply my ring 0 selectors but with bits 45 and 46 set (RPL bits). The ring 0 selectors work, im able to enter protected mode with them. RPL are bits 0-1 of the value loaded into CS/SS, not the bits in the descriptor (IIRC those bits are called DPL). |
|||
22 Dec 2008, 03:24 |
|
calpol2004 22 Dec 2008, 03:35
I totally misunderstood (i thought you meant the DPL in the descriptor, never even knew about this), thankyou!
I simply changed ss to 0x23 and cs to 0x1B (add 3) and it worked. What a perculiar way to set the privelege level, you'd think that setting it in the descriptor would be enough d'ya think? i suppose it's so iret/retf can know about it before it checks the descriptor. Learn something new everyday. Thankyou very much japheth and manofsteel. You only had to tell me 3 times XD. Cal. |
|||
22 Dec 2008, 03:35 |
|
asmmsa 10 Feb 2010, 23:17
bullshit, doesnt work.
you missed something. |
|||
10 Feb 2010, 23:17 |
|
Coddy41 10 Feb 2010, 23:29
@asmmsa: You bumped up a topic this old just to say that? What is wrong with it?
_________________ Want hosting for free for your asm project? You can PM me. (*.fasm4u.net) |
|||
10 Feb 2010, 23:29 |
|
asmmsa 11 Feb 2010, 10:28
its exactly same issue i had.
everything is fine, GPF isnt switch related, but access to screenbuffer is made using null selector. |
|||
11 Feb 2010, 10:28 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.