flat assembler
Message board for the users of flat assembler.

Index > DOS > How to switch to pmode?

Author
Thread Post new topic Reply to topic
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 02 Oct 2018, 07:07
I'm trying to create a VERY simple program, with a minimal amount of code, to just switch the x86 CPU into 32bit protected mode, and then jump to some to the code segment and execute some 32bit code

So far I have this. Please let me know if there's any errors in the code. I'm getting unexpected results with Bochs debugger, so I think there must be some error, but if somebody could analyze the code and let me know what's wrong exactly, that would be helpful.

Code:
org 0x100
start: use16
        jmp start ;Lock up the program so that you have time to push ctrl+c in debugger
                  ;to pause execution. Then in the debugger you can manually set the execution
                  ;pointer to the next instruction.
        cli ;disable interrupts

        ;BIOS interrupt method to enable A20
        ;mov ax,2401h
        ;int 15h
        ;I'm not using this method because it makes trouble in the Bochs debugger I'm using.

        ;IO port method to enable A20
        in al, 0x92
        or al, 2
        and al,0xFE
        out 0x92, al

        lgdt [GDTHeader] ;load GDT header into GDT register, so the CPU can find the GDT entries

        ;enable protected mode
        mov eax,cr0
        or eax,1
        mov cr0,eax

        jmp 8:start_32bits ;jump to start of 32bit protected mode segment

GDTHeader: ;This header describesthe GDT itself
        dw 31 ;GDT limit is 31, which means its size is 32 bytes
        dd GDTEntries+0x11C70 ;GDT flat memory address is the flat memory address of the start
                              ;program (0x11C70, as determined in Bochs debugger) + the offset
                              ;into the program at which which the actual GDT entries are stored
GDTEntries: ;memory blocks are 4kB in size, and the first block in memory is block 0
        dq 0x0000000000000000 ;blank entry
        dq 0x00C09A0010000008 ;code segment, start of segment is block 1, and is 8 blocks in size
        dq 0x00C0920090000008 ;data segment, start of segment is block 9, and is 8 blocks in size
        dq 0x00C0960110000008 ;stack segment, start of segment is block 17, and is 8 blocks in size


start_32bits: use32
        ;initialize the segment registers with indecies into the GDT
        mov ax,2
        mov ds,ax
        mov ax,3
        mov ss,ax

main: use32
        ;run a simple loop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        jmp main    
Post 02 Oct 2018, 07:07
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 02 Oct 2018, 07:55
(N.B. Your message subjects are horribly generic and not descriptive of what you're trying to do. It won't attract the right amount of attention because it's too vague.)

Pmode is possibly too complicated for you right now (while you're trying to figure out everything and the kitchen sink at once). I would recommend sticking with real mode (albeit with 386 instructions) until you get a grasp on the other details. (Hey, I don't personally grok pmode anyways!)

If you insist on using 386 pmode, use an extender, e.g. WDOSX. It makes things much easier. Here's a very stupid example that I whipped up years ago. And you can use its debugger, too! BTW, unlike CWSDPMI (ring 3), WDOSX is ring 0!
Post 02 Oct 2018, 07:55
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 02 Oct 2018, 08:25
At the very least you have wrong offsets for your labels. And, no offsense, but rugxulo is right: you don’t seem to be experienced enough to dive into the topic and judging from the questions you’ve asked recently you’re trying to learn everything at once without actually going into deeper details. Assembly is not Java, learning it by mimicking someone else’s code and joining pieces you’ve found on the internet just doesn’t work.
Post 02 Oct 2018, 08:25
View user's profile Send private message Visit poster's website Reply with quote
alexfru



Joined: 23 Mar 2014
Posts: 80
alexfru 02 Oct 2018, 08:30
rugxulo wrote:
BTW, unlike CWSDPMI (ring 3), WDOSX is ring 0!

CWSDPMI has an option (or a separate version) for ring 0.
Post 02 Oct 2018, 08:30
View user's profile Send private message Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 02 Oct 2018, 20:22
So it's possible to run WDOSX in ring0 mode, so your programs still have access to the IN, OUT, and INT instructions? How does set the interrupts though? I know that OSes or OS extenders in 32bit mode though usually use an IDT to set different interrupts from the default ones (like INT 0x10 switching video mode). So there's no guaranty (unless I'm writing a program that sets up the 32bit mode myself) that the default interrupts will remain the same interrupts in 32bit mode. So I really do prefer to set up my own 32bit mode within my own program, once I figure out how to do it.
Post 02 Oct 2018, 20:22
View user's profile Send private message Reply with quote
Ben321



Joined: 07 Dec 2017
Posts: 70
Ben321 02 Oct 2018, 20:28
I'm not even sure if the bytes are arranged correctly within the GDT entries. It would be nice if somebody here could point me to a "GDT Validator" type program, who's sole purpose was to allow you to paste the hexadecimal bytes of a GDT entry into a text box, and then it would tell you if it's a valid GDT, and display the value set for each field. That way I could be sure if my bytes for the GDT are arranged correctly.
Post 02 Oct 2018, 20:28
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 02 Oct 2018, 20:52
If you look at the source code of fasm, in SOURCE/DOS/MODES.INC it contains a code that sets up 32-bit unreal mode. It does it by switching to protected mode and back, and you can find there an example of GDT.

A similar GDT is also present in my example of setting up long mode: https://board.flatassembler.net/topic.php?t=6206

Note that this example switches to protected mode very quickly, in just a couple of instructions, and then proceeds to set up 64-bit long mode, which is a bit more advanced matter.
Post 02 Oct 2018, 20:52
View user's profile Send private message Visit poster's website 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.