flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Privilege level change in long mode...

Author
Thread Post new topic Reply to topic
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
I have a question for people who have more experience in AMD64 architecture than me Smile,

First of all, this is my running environment and an example of what I want to do:

I have a 64-bit CODE segment descriptor with DPL0, and another 64-bit CODE segment descriptor with DPL3.

Now, I have some code loaded at for example, address 0x300000 (identity mapped, executable, user mode, read/write access).
The processor is running in CPL0 at this time, but what I want to do is to do a JMP or CALL to address 0x300000 but using the DPL3 descriptor to turn the processor into CPL3. As far as I know, far pointers in the form of SELECTOR:OFFSET are not allowed/valid in long mode, (I´m using Yasm and it doesn´t allow me to do that when writing 64-bit code).
I also tried

Code:
mov  ax, 0x20 ;; 64-bit DPL3 code segment selector.
push ax
push 0x300000
retf
    


but throws me a GP# fault.

Is there any way to jump directly to a different privileged level without using TSS descriptors or something like that?. And if not posible, Is there anywhere a simple code example of long mode multitasking and privilege level change?.

I Have the AMD64 manuals but are not very clear, It would be better for me to see a code example, I have also an example of multitasking with RING 0 and 3 tasks but is only for protected mode.

I would really appreciate if someone can help me with this.
Thanks in advance.
Post 12 Apr 2007, 14:44
View user's profile Send private message MSN Messenger Reply with quote
Hayden



Joined: 06 Oct 2005
Posts: 132
Hayden
Is the decriptor in the GDT or the LDT? Could we have a code snipet?
Post 12 Apr 2007, 16:04
View user's profile Send private message Reply with quote
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
Both descriptors are in the GDT, I´m posting from another computer now but I´ll post the code later, I promise.
Post 12 Apr 2007, 16:39
View user's profile Send private message MSN Messenger Reply with quote
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
Code:
      .
   .
   .
GDT:
       CREATE_GDT_DESCRIPTOR null, 0, 0, 0, 0, 0, 0
        
    ;; 0x08
     CREATE_GDT_DESCRIPTOR kernel_code32, GDT_LIMIT_4GB_015, 0, 0, \
            GDT_CODE | GDT_SEG_APP | GDT_DPL0 | GDT_SEG_PRESENT, \
             GDT_LIMIT_4GB_1619 | GDT_SEG_32BIT | GDT_LIMIT_IN_PAGES, 0
  ;; 0x10
     CREATE_GDT_DESCRIPTOR kernel_data32, GDT_LIMIT_4GB_015, 0, 0, \
            GDT_DATA | GDT_DAT_READ_WRIT | GDT_SEG_APP | GDT_DPL0 | GDT_SEG_PRESENT, \
         GDT_LIMIT_4GB_1619 | GDT_SEG_32BIT | GDT_LIMIT_IN_PAGES, 0

      ;; 64bit descriptors.
       ;;;;;;;;;;;;;;;;;;;;;
       ;; 0x18
     CREATE_GDT_DESCRIPTOR kernel_code64_dpl0, GDT_LIMIT_4GB_015, 0, 0, \
               GDT_CODE | GDT_SEG_APP | GDT_DPL0 | GDT_SEG_PRESENT, \
             GDT_LIMIT_4GB_1619 | GDT_LONG_MODE | GDT_LIMIT_IN_PAGES, 0
  ;; 0x20
     CREATE_GDT_DESCRIPTOR kernel_code64_dpl3, GDT_LIMIT_4GB_015, 0, 0, \
               GDT_CODE | GDT_SEG_APP | GDT_DPL3 | GDT_SEG_PRESENT, \
             GDT_LIMIT_4GB_1619 | GDT_LONG_MODE | GDT_LIMIT_IN_PAGES, 0
GDT_end:

      .
   .
   .

bits 64

        .
   .
   .

       mov     r8, 0x300000 ;; Physical address.
   mov     r9, 0x300000 ;; Virtual address.
    mov     r10, (PAG_PRESENT | PAG_READ_WRIT | PAG_USER | PAG_EXECUTABLE) ;; Attributes.
       call    K_Map_Page_Frame
    INVALIDATE_TLBS ;; Macro to invalidate TLBs content cause we modified the memory map.
       
    mov     rsi, some_code
      mov     rdi, 0x300000
       mov     rcx, some_code_end - some_code
      rep     movsb
       ;; mov  rax, 0x300000
       ;; jmp  0x20:rax --> THIS IS NOT ALLOWED BY YASM, I DON´T KNOW EXACTLY WHY...
       ;; So I try:
    mov     ax, 0x20
    push    ax
  push    0x300000
    retf
        ;; But this generates a General Protection Fault with error code 0x20, the selector
 ;; where I´m trying to jump... Sad 

some_code:
   jmp $
some_code_end:
    


Any idea?, Thanks...
Post 12 Apr 2007, 18:48
View user's profile Send private message MSN Messenger Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 977
Location: Czechoslovakia
MazeGen
BTW, there is no instruction like "jmp 0x20:rax". In 64-bit mode, you can't even use "jmp 0x20:0x0000000000300000". But you can still use something like
Code:
jmpf [far_jump_address]

far_jump_address:
dq 0x0000000000300000
dw 0x20
    
Post 12 Apr 2007, 20:43
View user's profile Send private message Visit poster's website Reply with quote
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
Yeah MazeGen, sorry about the misconception in "jmp 0x20:rax".

btw, ´jmpf´ doesn´t exist in Yasm language but I think it can be replaced by ´jmp far´. Anyway, this doesn´t work either resulting in a GP# with error code 0. I´m starting to believe that there is no way to do a direct intersegment call or jmp at least in long mode, I don´t know if it is posible in protected mode. I´d really appreciate if you can tell me the differences between task switching in protected mode and long mode using a TSS. The AMD64 manual states that in long mode there is no support for Hardware Multitasking, that there is only Software Multitasking, but at least one TSS has to be initialized for the OS task. If there is only one TSS, How do you switch to another task with different privilege level? The long mode TSS is also completely different from the protected mode one. This is not clear to me at all and is driving me crazy Shocked
I really don´t what to do because THERE IS NO CODE EXAMPLES for this architecture on the net, I´ve searched for hours. Crying or Very sad
Post 12 Apr 2007, 21:33
View user's profile Send private message MSN Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
AMD64 doesn't support 80-bit far jumps/calls http://board.flatassembler.net/topic.php?t=4267
Post 12 Apr 2007, 21:50
View user's profile Send private message Reply with quote
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
Well, I know that now and thanks, but I still don't understand how to switch the procesor into CPL3 in long mode. How do you set up a RING 3 task for execution? Is there any example or some info that could be useful? Sorry for insisting in this too much. Thanks again.
Post 13 Apr 2007, 00:10
View user's profile Send private message MSN Messenger Reply with quote
Chewy509



Joined: 19 Jun 2003
Posts: 297
Location: Bris-vegas, Australia
Chewy509
Adan wrote:
Well, I know that now and thanks, but I still don't understand how to switch the procesor into CPL3 in long mode. How do you set up a RING 3 task for execution? Is there any example or some info that could be useful? Sorry for insisting in this too much. Thanks again.

iret is your answer...

simply push ss, rsp, cs, rip and eflags onto the stack and issue an iret.

It'll perform all the privilege level changes and load at the correct stack for you at the same time...

PS. There is no difference between 32bit and 64bit modes if utilising a pure flat memory model...
Post 13 Apr 2007, 02:52
View user's profile Send private message Visit poster's website Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 977
Location: Czechoslovakia
MazeGen
LocoDelAssembly wrote:
AMD64 doesn't support 80-bit far jumps/calls http://board.flatassembler.net/topic.php?t=4267

Many thanks, I overlooked this fact!
Post 13 Apr 2007, 06:16
View user's profile Send private message Visit poster's website Reply with quote
Adan



Joined: 30 Mar 2007
Posts: 17
Adan
No, I´m sorry but the IRET thingy didn´t work (or I´m doing something wrong). But what I´m looking for in fact is how to do a control transfer through a TSS DESCRIPTOR. I´ve seen a protected mode example in which you have one TSS and one TSS DESCRIPTOR for each task. But, I´ve read somewhere too that you can perform multitasking in PM with ONLY ONE TSS. How do you acomplish that? Is there in fact MULTIPLE TSS but ONLY ONE TSS DESCRIPTOR and the descriptor base address is patched with every task switch? Where do you save the state of the more than one tasks suspended if you have only one TSS as I´ve read?

Is this applicable to the x86-64 where hardware multitasking doesn´t exist? All this is really confusing to me.

What about SYSCALL/SYSRET interface and STAR, LSTAR and SFMASK? Is it posible to use SYSRET to jump "out of the kernel" (I mean, from CPL0 to CPL3) for the first time?

Could anybody help me with this?

Returning to the IRET method, Chewy509, I really thank you for sharing it, but could you give me some example with real values? Just to know if I´m doing things correctly. Sorry but I´m not completely sure that this method can be used in long mode. Thank you all people for your attention.
Post 13 Apr 2007, 18:20
View user's profile Send private message MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.