pmode prob setting up 4G data segment... 
Author Message
 pmode prob setting up 4G data segment...

Hi all

I never thought before I started working on my cpu detection routine
that it could help me learn as much as it is. I've given up on
figuring out my eflags problem for now, but now I'm having a problem
setting pmode. I'm only trying to set it for a few cycles, so I can
read the value at the processor reset vector (ie 0xFFFFFFF0) and also
that at 0xFFEFFFF0, in order to compare the values after returning to
real mode. I had expected it to be trivial (after all, I ahve a lot of
code examples to get guidance from, and plenty of texts, etc).

I'm guessing that I'm doing something wrong in how I'm setting up the
gdt, although I'm not sure.

If anyone can point out what I'm doing wrong, I'd be grateful. Here's
the relevant parts of the code (nasm syntax):

<---- start of code ---->

; Background:
;       I'm in graphics mode 3 (video segment B800)
;       All the routines which are not shown have been thoroughly
;               tested, and all work.
;

        call    EnableA20       ; Try to enable A20
        jnz     .err1           ; If it failed, exit with error

        call    InitGDT         ; initialise the GDT

        lgdt    [GDT_Sel_]      ; load GDT

        mov     bp,pmode_on
        mov     cx,pmode_on.end - pmode_on
        call    prints

        mov     eax,cr0         ; get control register
        or      al,1            ; set PE
        mov     cr0,eax         ; in protected mode

        jmp     $+2             ; flush prefetch queue

        mov     bx,Flat_DS
        mov     gs,bx           ; set up 4G segment in GS

        mov     word [gs:0x000B8000],"AA"
                                ; should print "AA" over whatever is
                                ; on the top left of the screen, but
                                ; it doesn't

        mov     esi,0FFFFFFF0h  ; 4G - 16 bytes
        mov     edi,0FFEFFFF0h  ; 4G - 1M - 16 bytes

        mov     ecx,[gs:esi]    ; data at reset vector
        mov     edx,[gs:edi]    ; data at reset vector - 1M

        mov     bx,RM_DS
        mov     gs,bx           ; set GS to RM data segment

        mov     eax,cr0         ; get control register
        and     al,-1           ; clear PE
        mov     cr0,eax         ; back in real mode

        jmp     $+2             ; flush prefetch queue

        mov     bp,pmode_off
        mov     cx,pmode_off.end - pmode_off
        call    prints          ; if we got here, it would print a
                                ; message to say we have left pmode

<snip irrelevant code>

InitGDT:
        mov     eax,ds
        shl     eax,4
        add     eax,GDT_Sel_
        mov     [GDT_Sel_ + Base_A15_A00],ax    ; set up GDT pointer
        shr     eax,10h                         ;
        mov     [GDT_Sel_ + Base_A23_A16],al    ;

        mov     eax,ds                          ; Get DS
        shl     eax,4
        mov     [RM_DS_ + Base_A15_A00],ax      ; set up RM_DS base
        shr     eax,10h                         ;
        mov     [RM_DS_ + Base_A23_A16],al      ;

        ret

; The GDT

GDT_Sel         equ     0               ; used for a pointer to self

GDT_Sel_:       ISTRUC  descript

        at Seg_limit,           dw GDT_Len-1    ; GDT limit
        at Access_rights,       db 0
        at GDLimit_A19_A16,     db 0
        at Base_A31_A24,        db 0

                IEND

RM_DS           equ     $-Reset_GDT

RM_DS_:         ISTRUC  descript        ; real mode data segment

        at Seg_limit,           dw 0FFFFh       ; 64K limit
        at Access_rights,       db 093h         ; Present, data, R/W,
                                                ; accessed
        at GDLimit_A19_A16,     db 0
        at Base_A31_A24,        db 0

                IEND

Flat_DS         equ     $-Reset_GDT

Flat_DS_:       ISTRUC  descript

        at Seg_limit,           dw 0FFFFh       ; 64K limit
        at Base_A15_A00,        dw 0
        at Base_A23_A16,        db 0
        at Access_rights,       db 093h         ; Present, data, R/W,
                                                ; accessed
        at GDLimit_A19_A16,     db 0CFh         ; Granularity = 4K,
                                                ; limit = 4G
        at Base_A31_A24,        db 0

                IEND

GDT_Len         equ     $-Reset_GDT

; The definition of the "descript" structure:

STRUC   descript

    Seg_limit           resw    1       ; Segment limit[15-0]
    Base_A15_A00        resw    1       ; Base address[15-0]
    Base_A23_A16        resb    1       ; Base address[23-16]
    Access_rights       resb    1       ; Segment access rights
    GDLimit_A19_A16     resb    1       ; Granularity, Op-size,
                                        ; Limit[19-16]
    Base_A31_A24        resb    1       ; Base address[31-24]

ENDSTRUC

<---- end of code ---->

It executes the code to initialise the GDT fine, but I have no idea
whether it is setting the correct values in the right places (it all
looks right to me, based on how I'm reading the docs and other source
code I've seen, but this is the first time I've tried it...).

On a Pentium 60, it locks before it can write "AA" to the screen
buffer. On a 486SX33 it triple faults (at least, I assume that's why
it reboots...).

Can anyone see what I am doing wrong here?

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Thu, 04 Nov 2004 05:56:01 GMT  
 pmode prob setting up 4G data segment...
Quote:

> If anyone can point out what I'm doing wrong, I'd be grateful. Here's
> the relevant parts of the code (nasm syntax):

several things I spotted:

Quote:
> <---- start of code ---->

> ; Background:
> ;     I'm in graphics mode 3 (video segment B800)
> ;     All the routines which are not shown have been thoroughly
> ;             tested, and all work.
> ;

> call  EnableA20       ; Try to enable A20
> jnz   .err1           ; If it failed, exit with error

> call  InitGDT         ; initialise the GDT

> lgdt  [GDT_Sel_]      ; load GDT

> mov   bp,pmode_on
> mov   cx,pmode_on.end - pmode_on
> call  prints

be sure to clear ints...

Quote:
> mov   eax,cr0         ; get control register
> or    al,1            ; set PE
> mov   cr0,eax         ; in protected mode

> jmp   $+2             ; flush prefetch queue

> mov   bx,Flat_DS
> mov   gs,bx           ; set up 4G segment in GS

> mov   word [gs:0x000B8000],"AA"
> ; should print "AA" over whatever is
> ; on the top left of the screen, but
> ; it doesn't

not quite, as remember each character on screen is 2 bytes, you should
have: a single blinking blue 'A'.

Quote:

> mov   esi,0FFFFFFF0h  ; 4G - 16 bytes
> mov   edi,0FFEFFFF0h  ; 4G - 1M - 16 bytes

> mov   ecx,[gs:esi]    ; data at reset vector
> mov   edx,[gs:edi]    ; data at reset vector - 1M

> mov   bx,RM_DS
> mov   gs,bx           ; set GS to RM data segment

> mov   eax,cr0         ; get control register
> and   al,-1           ; clear PE

ok, this is a problem, try:
and al, 0xfe
or:
and al, -2
as: -1=0xff

- Show quoted text -

Quote:
> mov   cr0,eax         ; back in real mode

> jmp   $+2             ; flush prefetch queue

> mov   bp,pmode_off
> mov   cx,pmode_off.end - pmode_off
> call  prints          ; if we got here, it would print a
> ; message to say we have left pmode

> <snip irrelevant code>

> InitGDT:
> mov   eax,ds
> shl   eax,4
> add   eax,GDT_Sel_
> mov   [GDT_Sel_ + Base_A15_A00],ax    ; set up GDT pointer
> shr   eax,10h                         ;
> mov   [GDT_Sel_ + Base_A23_A16],al    ;

the gdt origin is 32bits, shouldn't be a problem

Quote:
> mov   eax,ds                          ; Get DS
> shl   eax,4
> mov   [RM_DS_ + Base_A15_A00],ax      ; set up RM_DS base
> shr   eax,10h                         ;
> mov   [RM_DS_ + Base_A23_A16],al      ;

> ret

> ; The GDT

> GDT_Sel               equ     0               ; used for a pointer to self

Reset_GDT should be defined about here

I may be wrong as I don't know of "ISTRUC".

Quote:
> GDT_Sel_:     ISTRUC  descript

> at Seg_limit,         dw GDT_Len-1    ; GDT limit
> at Access_rights,     db 0
> at GDLimit_A19_A16,   db 0
> at Base_A31_A24,      db 0

this is the null descriptor which seems to have been also used to indicate
the location of the gdt.
maybe:
dw 0
dw GDT_Len-1
dd GDT_Sel_

Quote:
> IEND

> RM_DS         equ     $-Reset_GDT

where is Reset_GDT defined
Quote:

> RM_DS_:               ISTRUC  descript        ; real mode data segment

> at Seg_limit,         dw 0FFFFh       ; 64K limit
> at Access_rights,     db 093h         ; Present, data, R/W,
> ; accessed
> at GDLimit_A19_A16,   db 0
> at Base_A31_A24,      db 0

> IEND

also looks like the wrong size.

Quote:
> Flat_DS               equ     $-Reset_GDT

> Flat_DS_:     ISTRUC  descript

> at Seg_limit,         dw 0FFFFh       ; 64K limit
> at Base_A15_A00,      dw 0
> at Base_A23_A16,      db 0
> at Access_rights,     db 093h         ; Present, data, R/W,
> ; accessed
> at GDLimit_A19_A16,   db 0CFh         ; Granularity = 4K,
> ; limit = 4G
> at Base_A31_A24,      db 0

> IEND

looks like right size

- Show quoted text -

Quote:

> GDT_Len               equ     $-Reset_GDT

> ; The definition of the "descript" structure:

> STRUC descript

>     Seg_limit         resw    1       ; Segment limit[15-0]
>     Base_A15_A00      resw    1       ; Base address[15-0]
>     Base_A23_A16      resb    1       ; Base address[23-16]
>     Access_rights     resb    1       ; Segment access rights
>     GDLimit_A19_A16   resb    1       ; Granularity, Op-size,
> ; Limit[19-16]
>     Base_A31_A24      resb    1       ; Base address[31-24]

> ENDSTRUC

funny, I don't remember nasm ever having struct features...

I may have missed something...

--



Thu, 04 Nov 2004 11:44:26 GMT  
 pmode prob setting up 4G data segment...
The main problem is that the AND instruction used to return to RM
uses -1 instead of -2.  Actually, this is the point at which I get on
my soapbox and say that you should always use records and strucs, but
you probably already know that.

A secondary problem (although harmless in this case) is that the
purpose of a JMP instruction after entering/exiting PM is to set the
Limit and Access Rights byte for CS, not to flush the PIQ.  Hence,
the JMP must be FAR, such as JMP 10:xxxx after entering (which also
changes the value of CS from zzzz (a RM segment) to a selector).
Similarly, upon returning to RM, JMP zzzz:xxxx sets the limit back to
FFFF and the A/R byte to something appropriate for RM.

In this case, because you don't reference CS explicitly (as in a far
call which would push the RM value of CS as part of the return
address), there's no problem.

Quote:

> Hi all

> I never thought before I started working on my cpu detection routine
> that it could help me learn as much as it is. I've given up on
> figuring out my eflags problem for now, but now I'm having a problem
> setting pmode. I'm only trying to set it for a few cycles, so I can
> read the value at the processor reset vector (ie 0xFFFFFFF0) and also
> that at 0xFFEFFFF0, in order to compare the values after returning to
> real mode. I had expected it to be trivial (after all, I ahve a lot of
> code examples to get guidance from, and plenty of texts, etc).

> I'm guessing that I'm doing something wrong in how I'm setting up the
> gdt, although I'm not sure.

> If anyone can point out what I'm doing wrong, I'd be grateful. Here's
> the relevant parts of the code (nasm syntax):

> <---- start of code ---->

> ; Background:
> ;  I'm in graphics mode 3 (video segment B800)
> ;  All the routines which are not shown have been thoroughly
> ;          tested, and all work.
> ;

>    call    EnableA20       ; Try to enable A20
>    jnz     .err1           ; If it failed, exit with error

>    call    InitGDT         ; initialise the GDT

>    lgdt    [GDT_Sel_]      ; load GDT

>    mov     bp,pmode_on
>    mov     cx,pmode_on.end - pmode_on
>    call    prints

>    mov     eax,cr0         ; get control register
>    or      al,1            ; set PE
>    mov     cr0,eax         ; in protected mode

>    jmp     $+2             ; flush prefetch queue

>    mov     bx,Flat_DS
>    mov     gs,bx           ; set up 4G segment in GS

>    mov     word [gs:0x000B8000],"AA"
>                            ; should print "AA" over whatever is
>                            ; on the top left of the screen, but
>                            ; it doesn't

>    mov     esi,0FFFFFFF0h  ; 4G - 16 bytes
>    mov     edi,0FFEFFFF0h  ; 4G - 1M - 16 bytes

>    mov     ecx,[gs:esi]    ; data at reset vector
>    mov     edx,[gs:edi]    ; data at reset vector - 1M

>    mov     bx,RM_DS
>    mov     gs,bx           ; set GS to RM data segment

>    mov     eax,cr0         ; get control register
>    and     al,-1           ; clear PE
>    mov     cr0,eax         ; back in real mode

>    jmp     $+2             ; flush prefetch queue

>    mov     bp,pmode_off
>    mov     cx,pmode_off.end - pmode_off
>    call    prints          ; if we got here, it would print a
>                            ; message to say we have left pmode

> <snip irrelevant code>

> InitGDT:
>    mov     eax,ds
>    shl     eax,4
>    add     eax,GDT_Sel_
>    mov     [GDT_Sel_ + Base_A15_A00],ax    ; set up GDT pointer
>    shr     eax,10h                         ;
>    mov     [GDT_Sel_ + Base_A23_A16],al    ;

>    mov     eax,ds                          ; Get DS
>    shl     eax,4
>    mov     [RM_DS_ + Base_A15_A00],ax      ; set up RM_DS base
>    shr     eax,10h                         ;
>    mov     [RM_DS_ + Base_A23_A16],al      ;

>    ret

> ; The GDT

> GDT_Sel            equ     0               ; used for a pointer to self

> GDT_Sel_:  ISTRUC  descript

>    at Seg_limit,           dw GDT_Len-1    ; GDT limit
>    at Access_rights,       db 0
>    at GDLimit_A19_A16,     db 0
>    at Base_A31_A24,        db 0

>            IEND

> RM_DS              equ     $-Reset_GDT

> RM_DS_:            ISTRUC  descript        ; real mode data segment

>    at Seg_limit,           dw 0FFFFh       ; 64K limit
>    at Access_rights,       db 093h         ; Present, data, R/W,
>                                            ; accessed
>    at GDLimit_A19_A16,     db 0
>    at Base_A31_A24,        db 0

>            IEND

> Flat_DS            equ     $-Reset_GDT

> Flat_DS_:  ISTRUC  descript

>    at Seg_limit,           dw 0FFFFh       ; 64K limit
>    at Base_A15_A00,        dw 0
>    at Base_A23_A16,        db 0
>    at Access_rights,       db 093h         ; Present, data, R/W,
>                                            ; accessed
>    at GDLimit_A19_A16,     db 0CFh         ; Granularity = 4K,
>                                            ; limit = 4G
>    at Base_A31_A24,        db 0

>            IEND

> GDT_Len            equ     $-Reset_GDT

> ; The definition of the "descript" structure:

> STRUC      descript

>     Seg_limit              resw    1       ; Segment limit[15-0]
>     Base_A15_A00   resw    1       ; Base address[15-0]
>     Base_A23_A16   resb    1       ; Base address[23-16]
>     Access_rights  resb    1       ; Segment access rights
>     GDLimit_A19_A16        resb    1       ; Granularity, Op-size,
>                                    ; Limit[19-16]
>     Base_A31_A24   resb    1       ; Base address[31-24]

> ENDSTRUC

> <---- end of code ---->

> It executes the code to initialise the GDT fine, but I have no idea
> whether it is setting the correct values in the right places (it all
> looks right to me, based on how I'm reading the docs and other source
> code I've seen, but this is the first time I've tried it...).

> On a Pentium 60, it locks before it can write "AA" to the screen
> buffer. On a 486SX33 it triple faults (at least, I assume that's why
> it reboots...).

> Can anyone see what I am doing wrong here?

> --
> Debs

> ----
> You have the right to remain silent. Anything you say will be misquoted and used against you.

_________________________________________


I've been getting a lot of junk e-mail lately,
so to reply to me directly, delete "despam".
_



Thu, 04 Nov 2004 13:08:15 GMT  
 pmode prob setting up 4G data segment...
Maybe it is a good idea to hardcode the GDT as constant array?
Flat-mode OSes usually do this, and Linux even hard-codes the loader
pagetables.

    Max


Quote:
> Hi all

> I never thought before I started working on my cpu detection routine
> that it could help me learn as much as it is. I've given up on
> figuring out my eflags problem for now, but now I'm having a problem
> setting pmode. I'm only trying to set it for a few cycles, so I can
> read the value at the processor reset vector (ie 0xFFFFFFF0) and
also
> that at 0xFFEFFFF0, in order to compare the values after returning
to
> real mode. I had expected it to be trivial (after all, I ahve a lot
of
> code examples to get guidance from, and plenty of texts, etc).

> I'm guessing that I'm doing something wrong in how I'm setting up
the
> gdt, although I'm not sure.

> If anyone can point out what I'm doing wrong, I'd be grateful.
Here's
> the relevant parts of the code (nasm syntax):

> <---- start of code ---->

> ; Background:
> ; I'm in graphics mode 3 (video segment B800)
> ; All the routines which are not shown have been thoroughly
> ; tested, and all work.
> ;

> call EnableA20 ; Try to enable A20
> jnz .err1 ; If it failed, exit with error

> call InitGDT ; initialise the GDT

> lgdt [GDT_Sel_] ; load GDT

> mov bp,pmode_on
> mov cx,pmode_on.end - pmode_on
> call prints

> mov eax,cr0 ; get control register
> or al,1 ; set PE
> mov cr0,eax ; in protected mode

> jmp $+2 ; flush prefetch queue

> mov bx,Flat_DS
> mov gs,bx ; set up 4G segment in GS

> mov word [gs:0x000B8000],"AA"
> ; should print "AA" over whatever is
> ; on the top left of the screen, but
> ; it doesn't

> mov esi,0FFFFFFF0h ; 4G - 16 bytes
> mov edi,0FFEFFFF0h ; 4G - 1M - 16 bytes

> mov ecx,[gs:esi] ; data at reset vector
> mov edx,[gs:edi] ; data at reset vector - 1M

> mov bx,RM_DS
> mov gs,bx ; set GS to RM data segment

> mov eax,cr0 ; get control register
> and al,-1 ; clear PE
> mov cr0,eax ; back in real mode

> jmp $+2 ; flush prefetch queue

> mov bp,pmode_off
> mov cx,pmode_off.end - pmode_off
> call prints ; if we got here, it would print a
> ; message to say we have left pmode

> <snip irrelevant code>

> InitGDT:
> mov eax,ds
> shl eax,4
> add eax,GDT_Sel_
> mov [GDT_Sel_ + Base_A15_A00],ax ; set up GDT pointer
> shr eax,10h ;
> mov [GDT_Sel_ + Base_A23_A16],al ;

> mov eax,ds ; Get DS
> shl eax,4
> mov [RM_DS_ + Base_A15_A00],ax ; set up RM_DS base
> shr eax,10h ;
> mov [RM_DS_ + Base_A23_A16],al ;

> ret

> ; The GDT

> GDT_Sel equ 0 ; used for a pointer to self

> GDT_Sel_: ISTRUC descript

> at Seg_limit, dw GDT_Len-1 ; GDT limit
> at Access_rights, db 0
> at GDLimit_A19_A16, db 0
> at Base_A31_A24, db 0

> IEND

> RM_DS equ $-Reset_GDT

> RM_DS_: ISTRUC descript ; real mode data segment

> at Seg_limit, dw 0FFFFh ; 64K limit
> at Access_rights, db 093h ; Present, data, R/W,
> ; accessed
> at GDLimit_A19_A16, db 0
> at Base_A31_A24, db 0

> IEND

> Flat_DS equ $-Reset_GDT

> Flat_DS_: ISTRUC descript

> at Seg_limit, dw 0FFFFh ; 64K limit
> at Base_A15_A00, dw 0
> at Base_A23_A16, db 0
> at Access_rights, db 093h ; Present, data, R/W,
> ; accessed
> at GDLimit_A19_A16, db 0CFh ; Granularity = 4K,
> ; limit = 4G
> at Base_A31_A24, db 0

> IEND

> GDT_Len equ $-Reset_GDT

> ; The definition of the "descript" structure:

> STRUC descript

>     Seg_limit resw 1 ; Segment limit[15-0]
>     Base_A15_A00 resw 1 ; Base address[15-0]
>     Base_A23_A16 resb 1 ; Base address[23-16]
>     Access_rights resb 1 ; Segment access rights
>     GDLimit_A19_A16 resb 1 ; Granularity, Op-size,
> ; Limit[19-16]
>     Base_A31_A24 resb 1 ; Base address[31-24]

> ENDSTRUC

> <---- end of code ---->

> It executes the code to initialise the GDT fine, but I have no idea
> whether it is setting the correct values in the right places (it all
> looks right to me, based on how I'm reading the docs and other
source
> code I've seen, but this is the first time I've tried it...).

> On a Pentium 60, it locks before it can write "AA" to the screen
> buffer. On a 486SX33 it triple faults (at least, I assume that's why
> it reboots...).

> Can anyone see what I am doing wrong here?

> --
> Debs

> ----
> You have the right to remain silent. Anything you say will be

misquoted and used against you.

- Show quoted text -



Thu, 04 Nov 2004 16:55:58 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 03:44:26 +0000 (UTC), cr88192 spake thus:

Quote:

>> If anyone can point out what I'm doing wrong, I'd be grateful. Here's
>> the relevant parts of the code (nasm syntax):

>several things I spotted:

Thanks. A few notes...

Quote:

>be sure to clear ints...

OK, I've tried that (it's at the top of the "reset_test" routine now).

Quote:

>> mov   eax,cr0         ; get control register
>> or    al,1            ; set PE
>> mov   cr0,eax         ; in protected mode

This is where it fails. If I remove the "or al,1", it runs and
executes a later piece of code to display text. With that line, it
locks up and doesn't display any following text.

Quote:

>> jmp   $+2             ; flush prefetch queue

>> mov   bx,Flat_DS
>> mov   gs,bx           ; set up 4G segment in GS

>> mov   word [gs:0x000B8000],"AA"
>> ; should print "AA" over whatever is
>> ; on the top left of the screen, but
>> ; it doesn't
>not quite, as remember each character on screen is 2 bytes, you should
>have: a single blinking blue 'A'.

Hmm. Oh well, it doesn't do that either :(

Quote:

>> mov   eax,cr0         ; get control register
>> and   al,-1           ; clear PE
>ok, this is a problem, try:
>and al, 0xfe

OK, I've changed that. It's not the problem in this case (as I hadn't
got that far) but it would ahve been a problem later (when I am able
to enter pmode, it will be good to know I can leave it as well...).

Quote:
>> GDT_Sel               equ     0               ; used for a pointer to self

>Reset_GDT should be defined about here

Yes, I missed out two relevant lines f code when I posted it. There is
an "align 8" and a "Reset_GDT:" label above the GDT_Sel line.

Quote:

>I may be wrong as I don't know of "ISTRUC".

>funny, I don't remember nasm ever having struct features...

>I may have missed something...

Struc and Istruc have both been available and documented since at
least 0.98 - I know they are placing the correct code in the correct
places as I had tested previously using code that did work, and I have
checked the values in the relevant memory positions in a de{*filter*}.

All the changes that were needed from your post ahve been integrated
into my code (most were there already, but a couple of small changes
were needed). Unfortunately it still freezes as soon as it tries to
enter pmode :(

The following snippet is a minimal snippet that displays the problem
on my systems.

        cli
        push    bp

        call    EnableA20       ; Try to enable A20
        jnz     .err1           ; If it failed, exit with error

        call    InitGDT         ; initialise the GDT

        lgdt    [GDT_Sel_]      ; load GDT

        mov     bp,pmode_on
        mov     cx,pmode_on.end - pmode_on
        call    prints

; The "pmode_on" message displays fine

        mov     eax,cr0         ; get control register
        or      al,1            ; set PE
        mov     cr0,eax         ; in protected mode

        jmp     $+2             ; flush prefetch queue

        mov     eax,cr0         ; get control register
        and     al,0FEh         ; clear PE
        mov     cr0,eax         ; back in real mode

        jmp     $+2             ; flush prefetch queue

        mov     bp,pmode_off
        mov     cx,pmode_off.end - pmode_off
        call    prints

; this message only displays if I remove the line that reads:
;       or      al,1            ; set PE
;
; if I leave that line in, it freezes and the "pmode_off" text is
; not displayed.

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Thu, 04 Nov 2004 19:56:04 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 08:55:58 +0000 (UTC), Maxim S. Shatskih spake
thus:

Quote:
>Maybe it is a good idea to hardcode the GDT as constant array?
>Flat-mode OSes usually do this, and Linux even hard-codes the loader
>pagetables.

When I write code to actually enter pmode for the purpose of having my
OS in pmode, I'll be doing that (flat segments are simple to
define...). For the moment though, this is just a simple GDT to enable
me to access two separate areas of high memory for the purpose of
testing what is at each memory position. This is to check whether a
processor reset can be used on an older processor to get the processor
ID.

As such, it's not possible to hard code the base addresses of the real
mode segments, as they will be needed in order to set the environment
correctly after the reset (and after the reset test). They have to be
set up according to the currect segment values. At a later stage, I
guess I could set it up at build time, as it will be part of my loader
and will ahve a fixed address, but some of my testing is in
environments where I can't control the address the code is loaded at
(eg, de{*filter*}s, DOS, etc).

I'm starting to see more and more reason for downlaoding bochs - a
shame, as I'll only ever want to use it for testing the pmode setup
code.

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Thu, 04 Nov 2004 19:56:05 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 05:08:15 +0000 (UTC), Bob Smith spake thus:

Quote:
>The main problem is that the AND instruction used to return to RM
>uses -1 instead of -2.

Actually that's not the main problem. If I removed the "or al,1" (ie I
remove the line of code that enables pmode), any following code is
executed (as shown by a series of debug messages I use). So it's the
entering pmode that is the problem at the moment. I ahve corrected the
AND line though - thank you, it would have been a problem later.

Quote:
> Actually, this is the point at which I get on
>my soapbox and say that you should always use records and strucs, but
>you probably already know that.

yeah. At this stage, I ahve a lot of my defines set up in an include
file, but for the purpose of testing and showing an example it made
mroe sense to show a minimal snippet than to have all defines and
stuff... I'm using structs and defines as much as possible, so that
when a structure or a constant value needs to be changed it is only
necessary in one place, and not everywhere.

Quote:

>A secondary problem (although harmless in this case) is that the
>purpose of a JMP instruction after entering/exiting PM is to set the
>Limit and Access Rights byte for CS, not to flush the PIQ.  Hence,
>the JMP must be FAR, such as JMP 10:xxxx after entering (which also
>changes the value of CS from zzzz (a RM segment) to a selector).
>Similarly, upon returning to RM, JMP zzzz:xxxx sets the limit back to
>FFFF and the A/R byte to something appropriate for RM.

yeah. In this case, I'm using the jmp as the code may be executed on
the slowest of 386 systems 9at some stage...), so I need to make sure
that I have set up pmode fully before I try executing any code that
makes use of it. It may not be necessary, but it's a precaution I
observed in some other code, and it only uses 2 bytes :)

Anyway, thanks for your comments. I just can't figure out why the
actual entering pmode is causing a problem - I'm not sure if it's when
I enter pmode or when I load and use GS that I'm triple faulting (and
not all systems are acting the same - on two test systems, one
freezes, the other reboots).

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Thu, 04 Nov 2004 19:56:11 GMT  
 pmode prob setting up 4G data segment...
Hi all

I sorted out the problem. It was actually a piece of code that I had
thought was totally unrelated that was breaking it.

While checking for the presence of a 386 and later processor, I had
been altering the flags, but hadn't saved the original values. I had
set the NT flag to 1 and IOPL to 3, and that appears to ahve been the
problem. When I restored the flags as they were when the code received
control, the code works fine.

One thing that I found odd though

        mov     dword [gs:0x0B8000],"0000"

didn't work, but

        mov     esi,0x0B8000
        mov     [gs:esi],"0000"

does work! Still, better that it works with a minor hack than not at
all, at least I was able to ensure that I have a 32-bit data segment
set up :)

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Thu, 04 Nov 2004 21:55:59 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 13:55:59 +0000 (UTC), Debs spake thus:

Quote:
>One thing that I found odd though

>    mov     dword [gs:0x0B8000],"0000"

>didn't work, but

After a bit of experimenting, I found that this is a bug (or is that
feature?) in nasm. If I change the above to:

        mov     dword [dword gs:0x0B8000],"0000"

it assembles correctly. Without the "dword" on the address size, nasm
des not realise that 0xB8000 is dword sized, and it is assembled as
0x8000. Checking with older versions of nasm, I found that it has
always been like that, so I don't know whether it would be considered
a bug (as it is not assembling the offset as supplied) or a feature
(as soem folk may already be relying on it to remain how it has been
for years).

Quote:

>    mov     esi,0x0B8000
>    mov     [gs:esi],"0000"

>does work! Still, better that it works with a minor hack than not at
>all, at least I was able to ensure that I have a 32-bit data segment
>set up :)

Fortuantely I don't have to use that ugly hack any more. It saves
space as well to hard code the address (it's not like I'm going to
write loads of data at that point - it's just a small debug routine to
make sure I had properly set up the 32-bit data segment...).

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Fri, 05 Nov 2004 00:56:04 GMT  
 pmode prob setting up 4G data segment...
This is a bug in NASM -- I've seen the same problem with 32-bit
constants in MASM (hey, they're compatible!).  Check the .OBJ file
and you'll see that NASM truncates the first constant to 8000h.

BTW, with a few more lines of code, you can debug this whole program
within PM using my de{*filter*}, 386SWAT (you will need to allocate room
for a PM IDT and a few more GDT entries).  See my clax86 message "Re:
Problems entering V86 mode" 5/15/02 12:55 (sn-us comp.lang.asm.x86
108165).

Quote:

> Hi all

> I sorted out the problem. It was actually a piece of code that I had
> thought was totally unrelated that was breaking it.

> While checking for the presence of a 386 and later processor, I had
> been altering the flags, but hadn't saved the original values. I had
> set the NT flag to 1 and IOPL to 3, and that appears to ahve been the
> problem. When I restored the flags as they were when the code received
> control, the code works fine.

> One thing that I found odd though

>    mov     dword [gs:0x0B8000],"0000"

> didn't work, but

>    mov     esi,0x0B8000
>    mov     [gs:esi],"0000"

> does work! Still, better that it works with a minor hack than not at
> all, at least I was able to ensure that I have a 32-bit data segment
> set up :)

_________________________________________


I've been getting a lot of junk e-mail lately,
so to reply to me directly, delete "despam".



Fri, 05 Nov 2004 00:56:06 GMT  
 pmode prob setting up 4G data segment...
Quote:

> After a bit of experimenting, I found that this is a bug (or is that
> feature?) in nasm. If I change the above to:

> mov   dword [dword gs:0x0B8000],"0000"

> it assembles correctly. Without the "dword" on the address size, nasm
> des not realise that 0xB8000 is dword sized, and it is assembled as
> 0x8000. Checking with older versions of nasm, I found that it has
> always been like that, so I don't know whether it would be considered
> a bug (as it is not assembling the offset as supplied) or a feature
> (as soem folk may already be relying on it to remain how it has been
> for years).

and it gives you 2 0's with a white background and black foreground...
if you use "3333" it should be unreadable...

ok, in each character cell there are 2 bytes, first is the character,
second is the color...
the second byte is layed out as
BlBrBgBbFiFrFgFb

where Bl is blinking and Fi is intensity. B* is background and F* is
foreground.

RGB values are:
0=black; 1=blue; 2=green; 3=cyan; 4=red; 5=purple; 6=brown/yellow;
7=white/grey.
so if you want bright yellow letters you do 0x0e, or for black on white it
is 0x70.

or did you allready know this... I just perfer to use more
"normal"/non-arbitrary colors for text....

--



Fri, 05 Nov 2004 03:51:15 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 19:51:15 +0000 (UTC), cr88192 spake thus:

Quote:
>and it gives you 2 0's with a white background and black foreground...
>if you use "3333" it should be unreadable...

yeah, I experimented with a few values so I could be sure that it was
working properly. The main thing was to display acouple of characters
so I could make sure i ahd properly set up the 32-bit data segment, in
order to be sure that I am readig values from the address I expected
in the following couple of lines of code...

Quote:

>ok, in each character cell there are 2 bytes, first is the character,
>second is the color...
>the second byte is layed out as
>BlBrBgBbFiFrFgFb

Yeah, I usually look up the colours in RBIL when I need to know them
:) Thanks for posting them anyway, it's always good to know people
will post info just in case I (or anyone else) ahven't got it, it
means that posts aren't jsut going into the void :)

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Fri, 05 Nov 2004 09:55:54 GMT  
 pmode prob setting up 4G data segment...
Hello {*filter*}folk!

On Sun, 19 May 2002 16:56:06 +0000 (UTC), Bob Smith spake thus:

Quote:
>This is a bug in NASM -- I've seen the same problem with 32-bit
>constants in MASM (hey, they're compatible!).  Check the .OBJ file
>and you'll see that NASM truncates the first constant to 8000h

I asked the other nasm developers about this, so I could be sure. It
seems that, as I'm assembling in 16-bit mode, I have to explicitly
state that I want to use a 32-bit offset (by using "dword" for the
address). I'm adding that to the docs, so it will be clear, as it
isn't properly documented as such.

Quote:

>BTW, with a few more lines of code, you can debug this whole program
>within PM using my de{*filter*}, 386SWAT (you will need to allocate room
>for a PM IDT and a few more GDT entries).  See my clax86 message "Re:
>Problems entering V86 mode" 5/15/02 12:55 (sn-us comp.lang.asm.x86
>108165).

I'll take a look at that. It's not going to help for this code 9as it
is mostly real mode code), but when I write the code to go into pmode
and need to test that, it will be useful to compare the various
debugging environments that are available to test before I get it to a
state that is useable on real machines.

--
Debs

----
You have the right to remain silent. Anything you say will be misquoted and used against you.



Fri, 05 Nov 2004 09:55:55 GMT  
 
 [ 23 post ]  Go to page: [1] [2]

 Relevant Pages 

1. pmode prob setting up 4G data segment...

2. data segment vs code segment

3. segment prob

4. Watcom PMODE segment registers question

5. pmode: aligning code segment on 4k boundary

6. USPS/UPS/etc shipping rate raw data...

7. yTex for MIT Prob Sets

8. Setting Pmode in DOS

9. Prob sharing MODULE data between DLLs

10. "data segment" in bootable program

11. "data segment" missing

 

 
Powered by phpBB® Forum Software