basic pmode program 
Author Message
 basic pmode program

Hi,
    I created a simple protected mode program. All it does is jump into
the 32-bit code segment once it enters protected mode and prints a
message before going into an infinite loop. It only sets up a GDT for
now. The problem? It doesn't work right. It doesn't print the message
which leads me to believe I have messed up with the
descriptors/selectors.
    I used a hard-coded jump to jump into the segment code32 (which has
a selector that points to the descriptor for it, the selector is called
select_code32.)

    mov  eax, cr0
     or   al, 1                  ; toggle pm bit
     mov  cr0, eax
     db   0eah
     dw   start32
     dw   select_code32  ; jump into 32-bit code!!

However for now the selector_code32 is in the code32 segment. Also whan
I use the lgdt instruction to load the memory area gdt_reg into the gdt
register the operand I used is located in a different segment. I don't
know which segments should contain what! My program doesn't work. It
should be fine. It uses a routine called assemble_gdt to build each
descriptor in the gdt. I don't think its the problem though. Anyhow, if
anyone could point me to a good tutorial or documentation or take a look
at my source code at http://www.*-*-*.com/ ~trzy/pmode.asm I would
really appreciate it!

Thanks,

Bart Tzynadlowski



Fri, 14 Dec 2001 03:00:00 GMT  
 basic pmode program

Quote:

> at my source code at http://www.powernet.net/~trzy/pmode.asm
>>     mov  sp, [stack+64]

  64 isn't big enough for a safe stack for BIOS interrupts;  But,
much more important, your syntax is wrong.  You want the address
stack+64, not the contents of that address.  Drop the [].

Quote:
>>     mov  ax, code16     ; find physical address by doing seg<<4
...
>>     mov  cl, 0100b      ; G=0,D/B=1,0=0,AVL=0

  You don't want B=1 for your code16

Quote:
>>    mov  dl, 1001010b   ; P=1,DPL=00,type=1010 (code read/execute)

  You missed a bit.  Try 10011010b.  All the later dl values have
similar eroors.  Try checking them bit-for-bit against bits 47-40
of my table at

http://www.csoft.net/~johnfine/descript.htm#attr_table

Quote:
>>     shr  cx, 8          ; move all of cl into ch

  Your shift is backwards.

Quote:
>>    mov  cl, bl         ; move segment limit 16-19 into cl
>>    ror  ecx, 4         ; rotate 4 bits of segment limit to bits 28-31 of ecx
>>    shr  cl, 4          ; move p, dpl, s, and type all the way into cl
>>    rol  ecx, 4         ; lower 12 bits of ecx = g d/b 0 avl seg19:16 p dpl s
>>                        ; and type
>>    mov  [si+6], cx     ; place into descriptor. 4 extra bits from cx over-
>>                        ; wrote bits 24-31 of base address in descriptor
>>    mov  [si+7], ah     ; load bits 24-31 of base address into descriptor

  I'm not patient enough to try to figure out what all that is intended
to do,
but I'm fairly sure it doesn't do it.

Quote:
>>     gdt_reg        db gdt_size, 0, 0

  I searched for the code that overwrites [gdt_reg+2] with the actual
(linear) address of the gdt.  I didn't find it.  It is required.
--
http://www.erols.com/johnfine/
http://www.geocities.com/SiliconValley/Peaks/8600/


Fri, 14 Dec 2001 03:00:00 GMT  
 basic pmode program

Quote:
> Hi,
>     I created a simple protected mode program. All it does is jump
into
> the 32-bit code segment once it enters protected mode and prints a
> message before going into an infinite loop. It only sets up a GDT for
> now. The problem? It doesn't work right. It doesn't print the message
> which leads me to believe I have messed up with the
> descriptors/selectors.
>     I used a hard-coded jump to jump into the segment code32 (which
has
> a selector that points to the descriptor for it, the selector is
called
> select_code32.)

>     mov  eax, cr0
>      or   al, 1                  ; toggle pm bit
>      mov  cr0, eax
>      db   0eah
>      dw   start32
>      dw   select_code32  ; jump into 32-bit code!!

> However for now the selector_code32 is in the code32 segment. Also
whan
> I use the lgdt instruction to load the memory area gdt_reg into the
gdt
> register the operand I used is located in a different segment. I don't
> know which segments should contain what! My program doesn't work. It
> should be fine. It uses a routine called assemble_gdt to build each
> descriptor in the gdt. I don't think its the problem though. Anyhow,
if
> anyone could point me to a good tutorial or documentation or take a
look
> at my source code at http://www.powernet.net/~trzy/pmode.asm I would
> really appreciate it!

   I'll try to avoid massive reposts of your source, only as much as
necessary to make context clear.

<<
     ; gdt register data
     gdt_reg        db gdt_size, 0, 0

   Must be gdt_ptr DW gdt_size, 0, 0

<<
mov     ss, ax          ; set up stack
mov  sp, [stack+64]     (*)
sti

* This must be LEA SP, [stack+64] or MOV SP, stack + 64.

<<
     call build_gdt      ; built gdt

     lgdt [gdt_reg]

   At this point your GDT base address field still contains 0s. It must
be linear address of GDT (code32 << 4 + gdt_dummy).

<<
build_gdt:
...
     xor  eax, eax
     mov  ax, code16     ; find physical address by doing seg<<4
     shl  ax, 4 (*)

* Must be SHL EAX, 4.

<<
assemble_gdt:
...
     shr  bx, 16         ; now lower nibble of bl contains segment
limit 16-19
     shr  cx, 8          ; move all of cl into ch (*)
     mov  cl, bl         ; move segment limit 16-19 into cl
     ror  ecx, 4         ; rotate 4 bits of segment limit to bits 28-31
of ecx
     shr  cl, 4          ; move p, dpl, s, and type all the way into cl
     rol  ecx, 4         ; lower 12 bits of ecx = g d/b 0 avl seg19:16
p dpl s
                         ; and type

* Should be SHL CX, 8. After this change you will store correct byte in
GDT but IMO the following variant is more clear:

shl cl, 4
and bl, 0Fh
and cl, 0F0h
or cl, bl
mov [si+6], cl

<<
check_rmode:
push    eax
mov     eax, cr0        ; get control register 0 (*)

* This is a privilieged instruction. If you execute it in V86 mode,
your program will generate a GPF and most likely be closed. Use SMSW AX
instead.

-- Sclerosis cannot be healed but can be forgotten --

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.



Fri, 14 Dec 2001 03:00:00 GMT  
 basic pmode program

I made all the modifications you suggested and I rewrote the assemble_gdt
routine, its a bit more clear. I don't think the problem lies in the
assemble_gdt routine although I am probably wrong =) All I can make of it
is that it isn't jumping into the protected mode code correctly. The
descriptors aren't set up right but I can't find what is causing the
trouble. The new code is at http://www.powernet.net/~trzy/pmode.asm (you
may have to capitalize PMODE.ASM if it doesn't work at first.) I do
believe that I have the format for the descriptors down correctly, I
checked them bit for bit against your descriptions and I also looked at
the representation in Volume 3 of the Intel Architecture Software
Developer's Manual.

Thanks,

Bart Trzynadlowski

Quote:


> > at my source code at http://www.powernet.net/~trzy/pmode.asm

> >>     mov  sp, [stack+64]

>   64 isn't big enough for a safe stack for BIOS interrupts;  But,
> much more important, your syntax is wrong.  You want the address
> stack+64, not the contents of that address.  Drop the [].

> >>     mov  ax, code16     ; find physical address by doing seg<<4
> ...
> >>     mov  cl, 0100b      ; G=0,D/B=1,0=0,AVL=0

>   You don't want B=1 for your code16

> >>    mov  dl, 1001010b   ; P=1,DPL=00,type=1010 (code read/execute)

>   You missed a bit.  Try 10011010b.  All the later dl values have
> similar eroors.  Try checking them bit-for-bit against bits 47-40
> of my table at

> http://www.csoft.net/~johnfine/descript.htm#attr_table

> >>     shr  cx, 8          ; move all of cl into ch

>   Your shift is backwards.

> >>    mov  cl, bl         ; move segment limit 16-19 into cl
> >>    ror  ecx, 4         ; rotate 4 bits of segment limit to bits 28-31 of ecx
> >>    shr  cl, 4          ; move p, dpl, s, and type all the way into cl
> >>    rol  ecx, 4         ; lower 12 bits of ecx = g d/b 0 avl seg19:16 p dpl s
> >>                        ; and type
> >>    mov  [si+6], cx     ; place into descriptor. 4 extra bits from cx over-
> >>                        ; wrote bits 24-31 of base address in descriptor
> >>    mov  [si+7], ah     ; load bits 24-31 of base address into descriptor

>   I'm not patient enough to try to figure out what all that is intended
> to do,
> but I'm fairly sure it doesn't do it.

> >>     gdt_reg        db gdt_size, 0, 0

>   I searched for the code that overwrites [gdt_reg+2] with the actual
> (linear) address of the gdt.  I didn't find it.  It is required.
> --
> http://www.erols.com/johnfine/
> http://www.geocities.com/SiliconValley/Peaks/8600/



Tue, 18 Dec 2001 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. basic pmode program

2. Two basic PMode questions

3. Two basic PMode questions

4. Pmode switching - pmode.asm (0/1)

5. Pmode switching - pmode.asm (0/1)

6. self-booting pmode program written in assembler written in sh

7. How to program PMode

8. V86 task from PMode program

9. Pmode programming

10. programming APIC / custom interrupts / PMode...

11. VGA programming in Pmode

12. OS and pmode programming

 

 
Powered by phpBB® Forum Software