Page 1 of 2

problem getting into pmode

Posted: Wed Feb 11, 2004 6:53 am
by bubach
Hello!
I have tried to set Pmode in my kernel loader, 'loader.sys'.
Bochs says something about CPU panic nr 13 (general protection error?).

The code i based it on works just fine (but it?s from a bootsector). I have almost the exact same code, but mine dosn?t work! My code looks like this:

-----------------------------------
Code:

Code: Select all

;..........here i set the A20-gate and lots of other stuff.... 

     ; Code to enter Protected Mode. 
     ;------------------------------- 
          mov     si, msgSetPmode                     ; Print 
          call    DisplayMessage                      ; message. 

          cli                                         ; Disable interrupts, we want to be alone 

          xor     ax, ax 
          mov     ds, ax                              ; Set DS-register to 0 - used by lgdt 

          lgdt    [gdt_desc]                          ; Load the GDT descriptor 

          mov     eax, cr0                            ; Copy the contents of CR0 into EAX 
          or      eax, 1                              ; Set bit 0 
          mov     cr0, eax                            ; Copy the contents of EAX into CR0 

          jmp     CODE_SEL:start32                    ; Jump to code segment, offset 32start 

     ;************************************************************************* 


     [BITS 32] 
     start32: 

     ; Fix segments. 
     ;--------------- 

          mov     ax, DATA_SEL                        ; Save data segment identifyer 
          mov     ds, ax                              ; Move a valid data segment into the data segment register 
          mov     ss, ax                              ; Move a valid data segment into the stack segment register 
          mov     esp, 090000h                        ; Move the stack pointer to 090000h 



     ; Load 'kernel.sys' from the FAT12 floppy and go to it. 
     ; (Right now i will just print 'Pmode' and hang.) 
     ;------------------------------------------------------- 


     ; Write a 'Pmode' at upper left corner. 
     ;--------------------------------------- 
          mov     byte [ds:0xB8000], 'P' 
          mov     byte [ds:0xB8001], 1Bh              ; Assign a color code 
          mov     byte [ds:0xB8002], 'm' 
          mov     byte [ds:0xB8003], 1Bh              ; Assign a color code 
          mov     byte [ds:0xB8004], 'o' 
          mov     byte [ds:0xB8005], 1Bh              ; Assign a color code 
          mov     byte [ds:0xB8006], 'd' 
          mov     byte [ds:0xB8007], 1Bh              ; Assign a color code 
          mov     byte [ds:0xB8008], 'e' 
          mov     byte [ds:0xB8009], 1Bh              ; Assign a color code 

     ; Hang. 
     ;------- 
     hang: 
          jmp hang                                    ; Loop, self-jump 



     ;  Global Descriptor Table (GDT). 
     ;--------------------------------- 
     gdt:                                             ; Address for the GDT 

     gdt_null:                                        ; Null Segment 
          dd     0 
          dd     0 

     CODE_SEL     equ $-gdt 
     gdt_code:                                        ; Code segment, read/execute, nonconforming 
          dw     0FFFFh 
          dw     0 
          db     0 
          db     10011010b 
          db     11001111b 
          db     0 

     DATA_SEL     equ $-gdt 
     gdt_data:                                        ; Data segment, read/write, expand down 
          dw     0FFFFh 
          dw     0 
          db     0 
          db     10010010b 
          db     11001111b 
          db     0 

     gdt_end:                                         ; Used to calculate the size of the GDT 

     gdt_desc:                                        ; The GDT descriptor 
          dw     gdt_end - gdt - 1                    ; Limit (size) 
          dd     gdt                                  ; Address of the GDT 

     ;************************************************************************* 
-------------------------------

I have tested all sorts of things, but i just can?t get it to work. It seems that it need that [ORG 07c00] to work correctly...
Sorry for this big posting...

Thanks in advance

/ Christoffer

Re:problem getting into pmode

Posted: Wed Feb 11, 2004 7:42 am
by Pype.Clicker
the code you're based on expects that it runs with CS=0. If you know where your code will be loaded, you should have a corresponding [ORG xxx] statement so that the assembler knows what offset it should give to your variables in memory.

You should stick with CS=0 as GDTR.base expects to be given an absolute address (not an offset within a segment)

Re:problem getting into pmode

Posted: Wed Feb 11, 2004 8:00 am
by bubach
I am using [ORG 0] and after start: i set upp the registers to point to 0x0500 where my 'loader.sys' is..
But i am almost sure that i have tested to do [ORG 0500] (or something) instead, and it still dosn?t work..

Hmm.. what should i do...

/ Christoffer

Re:problem getting into pmode

Posted: Wed Feb 11, 2004 8:05 am
by Pype.Clicker
show me your 'jmp' statement and the load address (segment:offset) for your .SYS stuff ... then i'll see what can be done ;p

Re:problem getting into pmode

Posted: Wed Feb 11, 2004 8:18 am
by bubach
i am in school now but maybe later..
it?s a standard fat12 bootsector that loads my 'loader.sys' at:
0x0000:0x0500
and in my 'loader.sys' file it is something like this:

[BITS 16]
[ORG 0]

jmp start

;data & functions

start:
mov ax, 0500h
mov cs, ax
mov ds, ax
mov fs, ax
mov gs, ax

; checking for v86, enable A20
; enter pmode ( almost :-( )
Not sure if it is exactly like this, but...

i can post the exact source at home later..

/ Christoffer

Re:problem getting into pmode

Posted: Wed Feb 11, 2004 12:02 pm
by bubach
ok this is the top of the file loader.asm

Code: Select all

     [BITS 16]
          [ORG 0x0500]  ; 0
          jmp     START

;data


     START:                                           ; Jump here.


     ; Code located at 0500:0000, adjust segment registers.
     ;------------------------------------------------------
      ;    cli
      ;    mov     ax, 0x0500
      ;    mov     ds, ax
      ;    mov     es, ax
      ;    mov     fs, ax
      ;    mov     gs, ax

     ; Create stack.
     ;---------------
      ;    mov     ax, 0x9000
      ;    mov     ss, ax
      ;    mov     sp, 0x2000
      ;    sti

;   ^
; / | \
;   |
;   L______   The old "set up segment code"

Ok, and the Fat12 bootsektor, sets up some segments to point to 0500:0000 and then does a 'retf'

Thats about it... Can u help me?

Re:problem getting into pmode

Posted: Thu Feb 12, 2004 4:27 am
by Pype.Clicker
your bootloader should enter loader.sys with "jmp 0x0000:0x500" rather than with "jmp 0x050:0x0000" ... if not, make sure you have "jmp 0000:start" in loader.sys.

also make sure DS, ES and friends are initialized with 0 in realmode so that they match with the "org 0x500" you have ...

btw, once you're talking about 0x500:0, other times about 0:0x500 ... you know for sure that they are *not* the same.

Re:problem getting into pmode

Posted: Thu Feb 12, 2004 12:20 pm
by bubach
this is from i real mode memory tutorial i have read:
0x0000:0x7C00, or using this Address: 0x07C0:0x0000 - Both of these Addresses point to the Same Absoloute Address
hmm....

i set cs to 0 and now it worked. but then i saw this:

Code: Select all

00024771000p[WGUI ] >>PANIC<< POWER button turned off.
00024771000i[SYS  ] Last time is 1076604706
00024771000i[CPU  ] real mode
00024771000i[CPU  ] CS.d_b = 16 bit
00024771000i[CPU  ] SS.d_b = 16 bit
00024771000i[CPU  ] | EAX=0011ff0a  EBX=000000b6  ECX=00110004  EDX=00000fff
00024771000i[CPU  ] | ESP=00001f5e  EBP=00000000  ESI=0000013d  EDI=00000500
00024771000i[CPU  ] | IOPL=0 NV UP DI PL NZ NA PE NC
00024771000i[CPU  ] | SEG selector     base    limit G D
00024771000i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00024771000i[CPU  ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00024771000i[CPU  ] |  ES:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00024771000i[CPU  ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00024771000i[CPU  ] |  GS:ffff( 0000| 0|  0) 000ffff0 0000ffff 0 0
00024771000i[CPU  ] |  SS:0007( 0000| 0|  0) 00000070 0000ffff 0 0
00024771000i[CPU  ] |  CS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00024771000i[CPU  ] | EIP=00005009 (00005009)
00024771000i[CPU  ] | CR0=0x60000010 CR1=0x00000000 CR2=0x00000000
00024771000i[CPU  ] | CR3=0x00000000 CR4=0x00000000
00024771000i[     ] restoring default signal behavior
00024771000i[CTRL ] quit_sim called with exit code 1
so i guess that i am not getting into pmode after all...
i will attach my source as a zip..
i have been trying to get into pmode for a month now....!
i think i am going to cry soon...

/ Christoffer

[attachment deleted by admin]

Re:problem getting into pmode

Posted: Thu Feb 12, 2004 12:25 pm
by bubach
oh, i forgot so say that the reason i want the "loader" to be on that address is this:
0x0000:0x0000 -> 0x0000:0x03FF = IVT (Interrupt Vector Table)
0x0000:0x0400 -> 0x0000:0x04FF = BDA (BIOS Data Area)

0x0000:0x0500 -> 0x0000:0x7BFF = Free Useable Memory!

0x0000:0x7C00 -> 0x0000:0x7DFF = Operating System BootSector - This is where the BIOS
Loads your Operating System's BootSector at Boot Time (You can use this Memory, as long as
your BootSector isn't executing and you don't need your BootSector anymore!)

0x0000:0x7E00 -> 0x9000:0xFFFF = Free Useable Memory!

0xA000:0x0000 -> 0xB000:0xFFFF = VGA Video RAM
0xC000:0x0000 -> 0xF000:0xFFFF = BIOS ROM Memory Area

0xFFFF:0x0010 -> 0xFFFF:0xFFFF = Free Useable Memory (If the A20 Gate is Enabled) - This
Memory is Above the 1mb Mark, 0xFFFF:0x0010 = 0x00100000(1mb)
0x0000:0x0500, is the first free memory location...

Re:problem getting into pmode

Posted: Thu Feb 12, 2004 1:49 pm
by Pype.Clicker
did you see your 'pmode' message displayed ? if so you *are* in pmode ... activate the trace-on if you want to be sure ... i wouldn't put too much confidence in the "panic power button pressed" if i were you...

Re:problem getting into pmode

Posted: Thu Feb 12, 2004 3:20 pm
by bubach
Hehe.. No, it?s not that power button message i was meaning... it was this part:

Code: Select all

00024771000i[CPU  ] real mode           <-bad...
00024771000i[CPU  ] CS.d_b = 16 bit   <- also bad
00024771000i[CPU  ] SS.d_b = 16 bit   <- really bad.. :-)
And no, i can?t see my Pmode message...
Why me!!!!!!???????

How come that the computer does not hang or enything, the code works just fine, except that it does not go into pmode..

Thank you very muck Clicker for taking the time to help me this far..

Re:problem getting into pmode

Posted: Fri Feb 13, 2004 2:51 am
by bubach
now i fixed half of the problem..
now bochs says this

Code: Select all

00260435000i[CPU  ] protected mode
00260435000i[CPU  ] CS.d_b = 32 bit
00260435000i[CPU  ] SS.d_b = 32 bit
becasue i fixed (i think) the ORG stuff...

but my pmode message still don?t show up.. and on a "real" computer it dosen?t print anything at all..

now it looks like this in loader.asm

Code: Select all

    [BITS 16]
          [ORG 0x0500]

          jmp     START

; some data and functions..........

     START:                                           ; Jump here.


     ; Code located at 0000:0500, adjust segment registers.
     ;------------------------------------------------------
          cli
          mov     ax, 0x0000
          mov     cs, ax
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax
and later...

Code: Select all

     ; Code to enter Protected Mode.
     ;-------------------------------
          mov     si, msgSetPmode                     ; Print
          mov     bl, 07h                             ; lightgrey
          call    DisplayMessage                      ; message.

          cli                                         ; Disable interrupts, we want to be alone

          lgdt    [gdtr]                              ; Load the GDT descriptor

          mov     eax, cr0                            ; Copy the contents of CR0 into EAX
          or      eax, 1                              ; Set bit 0
          mov     cr0, eax                            ; Copy the contents of EAX into CR0

          jmp     CODE_SEL:pmode_start                ; Jump to code segment, offset pmode_start

     ;*************************************************************************


     [BITS 32]
     pmode_start:

     ; Refresh all segment registers.
     ;--------------------------------
          mov     ax, DATA_SEL                        ; Save data segment identifyer
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax
          mov     ss, ax
          mov     esp, 0x9FFFF

     ; Turn off floppy motor.
     ;-----------------------
          mov     dx, 3F2h                            ; On my "real" testing PC
          mov     al, 0                               ; the floppy light just won?t
          out     dx, al                              ; go off, so.. (this didn?t work..)


     ; Load 'kernel.sys' from the FAT12 floppy and go to it.
     ; (Right now i will just print 'Pmode' and hang.)
     ;-------------------------------------------------------


     ; Write a 'Pmode' at upper left corner.
     ;---------------------------------------
          mov     byte [ds:0xB8000], 'P'
          mov     byte [ds:0xB8001], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8002], 'm'
          mov     byte [ds:0xB8003], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8004], 'o'
          mov     byte [ds:0xB8005], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8006], 'd'
          mov     byte [ds:0xB8007], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8008], 'e'
          mov     byte [ds:0xB8009], 1Bh              ; Assign a color code


     ; Hang.
     ;-------
          jmp $                                       ; Hang... :-)



     ;  Global Descriptor Table (GDT).
     ;---------------------------------

; same gdt as before.....
/ Christoffer

Re:problem getting into pmode

Posted: Fri Feb 13, 2004 3:44 am
by Pype.Clicker
1. "mov cs, ax" is not a valid instruction. I don't know how the assembler let you do that but it doesn't exist. the only way to reload the CS register is by doing a far jump.

Code: Select all

    jmp 0x0000:.here
.here:
2. your display code and your GDT seems just fine ... i don't really get what's wrong. I would say it might be a mis-loading problem (i.e. you loaded N sectors of loader.sys but accidently it grew up to N+1 and you're missing the end ...)

I really suggest you get a debug-enabled BOCHS and issue a 'trace-on' command or execute your code step by step from 0x500 to figure out ... instructions are available on bochs.sf.net and quick links to those instructions have been added recently on the Wiki FAQ

Re:problem getting into pmode

Posted: Fri Feb 13, 2004 3:52 am
by bubach
opps, that didn?t belong there.. ;-)
it seems that all my testing is making the code more and more ugly.. :-)
do you think that will fix it?

Many thanks for all your help!

/ Christoffer

Re:problem getting into pmode

Posted: Fri Feb 13, 2004 4:33 am
by bubach
removing the mov cs, ax fixed the first problem..
now it looks the same in both bochs and on a real computer, but the Pmode message still don?t shows up..

Hmm...