flat assembler
Message board for the users of flat assembler.

Index > OS Construction > About protected mode and memory

Author
Thread Post new topic Reply to topic
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 15 Sep 2012, 13:55
Please help me...

I am constructing a simple operating system, but I do not know how to switch to protected mode nor how to use EMS or XMS. Can anyone help me?
Post 15 Sep 2012, 13:55
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 15 Sep 2012, 15:06
Normally protected mode is 32 or 64 bit; EMS and XMS are 16bit real mode extensions. For simplicity, I'd recommend you go for 32bit protected mode, since you can use memory without the need to set up page tables. This requires you enable A20, create a valid GDT and perform the switch with correct descriptors and stack setup. After that it should be easy to add other functionality as you go.
Post 15 Sep 2012, 15:06
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 15 Sep 2012, 17:52
Okay, but how can I do this? Please write a sample code... And how can I access RAM memory in a large scale. Question Rolling Eyes
Post 15 Sep 2012, 17:52
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 15 Sep 2012, 18:39
Below is a cut down version of an old snapshot from my 32bit OS boot loader.

INCLUDES:
Code:
; ./hardware/gdt.ash
        GDT_COUNT                                       equ 0x2000
        GDT_SIZE                                        equ (sizeof.GDT_ENTRY   * GDT_COUNT)

        ; GDT Selector Rings
        GDT_RPL_RING0                                   equ 0x0000
        GDT_RPL_RING1                                   equ 0x0001
        GDT_RPL_RING2                                   equ 0x0002
        GDT_RPL_RING3                                   equ 0x0003
        GDT_RPL_MASK                                    equ 0x0003

        ; GDTENTRY.Access
        GDT_PRESENT                                     equ 0x80

        GDT_RING0                                       equ 0x00
        GDT_RING1                                       equ 0x20
        GDT_RING2                                       equ 0x40
        GDT_RING3                                       equ 0x60

        GDT_CODE                                        equ 0x10
        GDT_CODE_EXECUTE                                equ 0x08
        GDT_CODE_READ                                   equ 0x02

        GDT_DATA                                        equ 0x10
        GDT_DATA_WRITE                                  equ 0x02
        GDT_DATA_READ                                   equ 0x00

        GDT_STACK                                       equ 0x10
        GDT_STACK_WRITE                                 equ 0x02
        GDT_STACK_READ                                  equ 0x00
        GDT_STACK_EXPANDDOWN                            equ 0x04
        GDT_STACK_EXPANDUP                              equ 0x00

        GDT_SYSTEM                                      equ 0x00

        ; GDTENTRY.Flags
        GDT_GRANULARITY_BYTES                           equ 0x00
        GDT_GRANULARITY_PAGES                           equ 0x80

        GDT_16BIT                                       equ 0x00
        GDT_32BIT                                       equ 0x40
        GDT_USER                                        equ 0x10


        GDT_ACCESS_MASK                                 equ (GDT_PRESENT or GDT_RING3 or GDT_DATA or GDT_CODE_EXECUTE or GDT_STACK_EXPANDDOWN or GDT_DATA_WRITE)
        GDT_FLAGS_MASK                                  equ (GDT_GRANULARITY_PAGES or GDT_32BIT or GDT_USER)
        GDT_LIMITHI_MASK                                equ 0x0F


        struc GDTENTRY b,l,f,a
         {
                .LimitLo        dw (l and 0xFFFF)
                .BaseLo         dw (b and 0xFFFF)
                .BaseMi         db ((b shr 16) and 0xFF)
                .Access         db (a and GDT_ACCESS_MASK)
                .Flags_LimitHi  db ((f and GDT_FLAGS_MASK) or ((l shr 16) and GDT_LIMITHI_MASK))
                .BaseHi         db (b shr 24)
         }

        struc GDTR32ENTRY b,e
         {
                .Size           dw (e - b - 1)
                .Address        dd (b)
         }
;====
; ./hardware/i804x.ash
        ; Port Designations
        i804x_PORT_READ                                         equ 0x0060      ; R
        i804x_PORT_WRITE                                        equ 0x0060      ; W
        i804x_PORT_STATUS                                       equ 0x0064      ; R
        i804x_PORT_COMMAND                                      equ 0x0064      ; RW


        ; Input Flags
        i804X_INPUT_KEYBOARDENABLED                             equ 0x80
        i804X_INPUT_COLOUR                                      equ 0x40
        i804x_INPUT_MANUFACTURER                                equ 0x20
        i804x_INPUT_EXTERNALRAM                                 equ 0x10
        i804x_INPUT_MOUSEDATA                                   equ 0x02
        i804x_INPUT_KEYBOARDDATA                                equ 0x01

        ; Output Flags
        i804x_OUTPUT_KEYBOARDDATA                               equ 0x80
        i804x_OUTPUT_KEYBOARDCLOCK                              equ 0x40
        i804x_OUTPUT_IRQ12                                      equ 0x20
        i804x_OUTPUT_IRQ01                                      equ 0x10
        i804x_OUTPUT_MOUSECLOCK                                 equ 0x08
        i804x_OUTPUT_MOUSEDATA                                  equ 0x04
        i804x_OUTPUT_A20                                        equ 0x02
        i804x_OUTPUT_SYSTEM                                     equ 0x01

        ; Test Flags
        i804x_TEST_MOUSECLOCK                                   equ 0x02
        i804x_TEST_KEYBOARDCLOCK                                equ 0x01


        ; Status Register (Read i804x_PORT_STATUS)
        i804x_STATUS_PARITYERROR                                equ 0x80
        i804x_STATUS_TIMEOUT                                    equ 0x40
        i804x_STATUS_MOUSEOUPUTBUFFERFULL                       equ 0x20
        i804x_STATUS_INHIBIT                                    equ 0x10
        i804x_STATUS_A2                                         equ 0x08
        i804x_STATUS_SYSTEM                                     equ 0x04
        i804x_STATUS_INPUTBUFFERFULL                            equ 0x02
        i804x_STATUS_OUTPUTBUFFERFULL                           equ 0x01

        ; Command Register (Write i804x_PORT_COMMAND)
        i804x_COMMAND_TRANSLATE                                 equ 0x40
        i804x_COMMAND_DISABLEMOUSE                              equ 0x20
        i804x_COMMAND_DISABLEKEYBOARD                           equ 0x10
        i804x_COMMAND_SYSTEM                                    equ 0x04
        i804x_COMMAND_IRQ12                                     equ 0x02
        i804x_COMMAND_IRQ01                                     equ 0x01


        ; Command List (Write i804x_PORT_COMMAND)
        i804x_COMMAND_READCOMMAND                               equ 0x20        ; ?
        i804x_COMMAND_WRITECOMMAND                              equ 0x60        ; ?

        i804x_COMMAND_READINPUT                                 equ 0xC0        ; Read i804x_INPUT_xxxx from i804x_PORT_READ
                i804x_INHIBIT                           equ 0x00
                i804x_ENABLE                            equ 0x80
                i804x_MONO                              equ 0x40
                i804x_COLOR                             equ 0x00
                i804x_JUMPER                            equ 0x20
                i804x_RAM                               equ 0x10
        i804x_COMMAND_WRITEINPUTLO                              equ 0xC1        ; PS2 only; Write i804x_INPUT_xxxx to i804x_PORT_WRITE
        i804x_COMMAND_WRITEINPUTHI                              equ 0xC2        ; PS2 only; Write i804x_INPUT_xxxxto i804x_PORT_WRITE
        i804x_COMMAND_READOUTPUT                                equ 0xD0        ; Read i804x_OUTPUT_xxxx from i804x_PORT_READ
        i804x_COMMAND_WRITEOUTPUT                               equ 0xD1        ; Write i804x_OUTPUT_xxxx to i804x_PORT_WRITE
                i804x_KEYBOARDDATA                      equ 0x80
                i804x_KEYBOARDCLOCK                     equ 0x40
                i804x_INPUTBUFFEREMPTY                  equ 0x20
                i804x_OUTPUTBUFFERFULL                  equ 0x10
                i804x_A20                               equ 0x02
                i804x_RESET                             equ 0x01
        i804x_COMMAND_WRITEKEYBOARD                             equ 0xD2        ; Emulates keyboard signal
        i804x_COMMAND_WRITEMOUSE                                equ 0xD4        ; Emulates mouse signal
        i804x_COMMAND_RESET                                     equ 0xFF        ; ?

        i804x_ACK                                               equ 0xFA    
CODE:
Code:
;====
; ./boot/boot.asm
        use16
        org 0x7C00
;====
; ./loader/loader.asm
        call a20.enable

        cli

        lgdt [gdtr32]

        mov eax,cr0
        or eax,1
        mov cr0,eax

        jmp pword 0x0008:pmode

a20:

    .enable:

        cli
        call a20.enable_i804x
        call a20.test
        sti

        ret

    .enable_i804x:
        push ax

        mov al,i804x_COMMAND_READOUTPUT
        out i804x_PORT_COMMAND,al
        call .enable_i804x_wait

        in al,i804x_PORT_READ
        or al,(i804x_OUTPUT_IRQ01 or i804x_OUTPUT_A20)
        mov ah,al
        call .enable_i804x_wait

        mov al,i804x_COMMAND_WRITEOUTPUT
        out i804x_PORT_COMMAND,al
        call .enable_i804x_wait

        mov al,ah
        out i804x_PORT_WRITE,al
        call .enable_i804x_wait

        mov al,i804x_COMMAND_RESET
        out i804x_PORT_COMMAND,al
        call .enable_i804x_wait

        pop ax
        ret

    .enable_i804x_wait:
        push ax

    @@:

        in al,i804x_PORT_STATUS
        and al,i804x_STATUS_INPUTBUFFERFULL
        jnz @b

        pop ax
        ret

    .test:
        push fs gs

        xor ax,ax
        mov fs,ax
        not ax
        mov gs,ax

        mov al,byte [fs:0x0000]
        mov ah,al
        not al
        xchg al,byte [gs:0x0010]

        clc

        cmp ah,byte [fs:0x0000]
        mov byte [gs:0x0010],al
        je @f

        stc

    @@:

        pop gs fs
        ret


        use32
        align 16

    pmode:

        mov eax,0x0010
        mov ds,ax
        mov es,ax
        mov fs,ax
        mov gs,ax
        mov ss,ax
        mov esp,0x00100000

    @@:

        hlt

        jmp @b


        gdtr32                  GDTR32ENTRY gdt32.start,gdt32.end

        gdt32:
        .start:
        .null                   GDTENTRY 0x00000000,0x00000000,0x00,0x00
        .code                   GDTENTRY 0x00000000,0x000FFFFF,(GDT_GRANULARITY_PAGES or GDT_32BIT),(GDT_PRESENT or GDT_RING0 or GDT_CODE or GDT_CODE_READ or GDT_CODE_EXECUTE)
        .data                   GDTENTRY 0x00000000,0x000FFFFF,(GDT_GRANULARITY_PAGES or GDT_32BIT),(GDT_PRESENT or GDT_RING0 or GDT_DATA or GDT_DATA_READ or GDT_DATA_WRITE)
        .end:

                                dw 0
        .signature              dw 0xAA55
;====    
EDIT: Fixed typo and removed bonus code; EDIT2: Split code


Last edited by cod3b453 on 17 Sep 2012, 17:10; edited 3 times in total
Post 15 Sep 2012, 18:39
View user's profile Send private message Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 15 Sep 2012, 18:39
A$M wrote:
Okay, but how can I do this? Please write a sample code... And how can I access RAM memory in a large scale. Question Rolling Eyes

This sub-forum is full of examples - just enter pm or protected mode and press "search: button.

Keep in mind that in some cases you can get away with flat mode instead of protected mode. This applies to cases when you don't need memory protection and/or paging but would like to escape data segmentation. A variation on flat mode allowing to have 32bit code adders space has been discussed here too - just search for unreal mode.

However keep in mind that if you don't know nothing about how memory management works, what a descriptor or IDT is, any sample code will be more like black magic to you than something useful. You first need to graps some theory to understand example code.
Post 15 Sep 2012, 18:39
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 15 Sep 2012, 19:08
You can type a simpler example? I did not understand much. Confused
Post 15 Sep 2012, 19:08
View user's profile Send private message Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 16 Sep 2012, 10:21
A$M wrote:
You can type a simpler example? I did not understand much. Confused


You haven't read my post have you? First learn what PM is, than start to read code.
Post 16 Sep 2012, 10:21
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 17 Sep 2012, 17:36
I found a PDF document that tells you how to enter the protected mode and so I wrote this code:

Code:
  org 7c00h
   use16

start:
     xor ax, ax
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  mov sp, 7c00h

   mov ah, 24h
 int 15h

 cli
 lgdt [gdtr]

     mov eax, cr0
        or eax, 1
   mov cr0, eax

    jmp 10h:protected

use32
protected:
        sti
 ; Continue code here...

gdt      dw 0x0000, 0x0000, 0x0000, 0x0000
sys_data dw 0xffff, 0x0000, 0x9200, 0x00cf
sys_code dw 0xffff, 0x0000, 0x9800, 0x00cf
gdt_end:

gdtr     dw gdt_end-gdt-1
         dd gdt

times 510- ($-start)  db 0   
dw 0xaa55    


I understood everything. Except the GDT. Can you explain me? What are these values? What is GDT? This code is right? (In theory)


Last edited by A$M on 17 Sep 2012, 17:42; edited 1 time in total
Post 17 Sep 2012, 17:36
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 17 Sep 2012, 17:42
Tidied my previous post a little.

It's a good idea to get copies of the Intel and AMD manuals; these also have their own examples and explanations. The A20 code is derived from stuff I read online a long time ago, so I can't give you a concrete reference for that.

You shouldn't do sti until you have loaded valid selectors into ds,es and ss and loader a valid IDTR/IDT.
Post 17 Sep 2012, 17:42
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 17 Sep 2012, 17:47
But this code works?
I will try soon. But can you try for me?
Post 17 Sep 2012, 17:47
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 17 Sep 2012, 17:50
Okay, but what is IDTR/IDT?
Post 17 Sep 2012, 17:50
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 17 Sep 2012, 19:01
A$M wrote:
Okay, but what is IDTR/IDT?
http://wiki.osdev.org/Interrupt_Descriptor_Table - familiarize yourself with that WiKi. Also, grab the Intel and AMD CPU manuals, and dig through them - most of your questions will be answered there. If you aren't willing to do a little basic research yourself, you'll never end up getting anything done.

_________________
Image - carpe noctem
Post 17 Sep 2012, 19:01
View user's profile Send private message Visit poster's website Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 17 Sep 2012, 19:17
Oh! IDT = Interrupt Descriptor Table... Sorry! I did not understand the acronym... But now I understand. As I'm distracted... Embarassed
Post 17 Sep 2012, 19:17
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 17 Sep 2012, 19:57
What values ​​should I put in the GDT? What is it?
Post 17 Sep 2012, 19:57
View user's profile Send private message Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 19 Sep 2012, 23:56
I discovered what I did not know about the GDT. I "googled". That left little doubt. But if someone wants to add information or a question about Protected Mode or about memory management, feel free. Very Happy
Post 19 Sep 2012, 23:56
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 20 Sep 2012, 19:25
There's already a lot of information on these things around - both beginner and more advanced stuff, both on this messageboard and other places (osdev.org isn't the only place). You really should familiarize yourself with the basics before asking a ton of questions that already have answers.

Of course if you spend some time researching but have trouble understanding parts of it, or can't get code working, don't hesitate to ask - but your posts seem kinda of the "OK-I've-done-this-tell-me-what-the-next-step-is" type Smile
Post 20 Sep 2012, 19:25
View user's profile Send private message Visit poster's website Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M 21 Sep 2012, 13:36
f0dder wrote:
There's already a lot of information on these things around - both beginner and more advanced stuff, both on this messageboard and other places (osdev.org isn't the only place). You really should familiarize yourself with the basics before asking a ton of questions that already have answers.

Of course if you spend some time researching but have trouble understanding parts of it, or can't get code working, don't hesitate to ask - but your posts seem kinda of the "OK-I've-done-this-tell-me-what-the-next-step-is" type Smile


If you say... Who am I to contradict? Wink
Post 21 Sep 2012, 13:36
View user's profile Send private message 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.