Page 1 of 1

Running PM again.. ;/

Posted: Thu Dec 28, 2006 1:43 pm
by mrkaktus
Hi everyone, I have great bootloader that has PM initiation and rest of needed stuff, but now after I write a kernel I am writing bigger bootL to put there more stuff like loading necessary aps (I am working on microkernel). So I writed secon stage of that bootL but there code doing PM initialisation isn't working ;/.

It is very similiar to :
http://www.osdev.org/phpBB2/viewtopic.p ... +gdt+index
(I was trying thing mentioned there but nothing helps ;/ )

So This is how code looks:

BITS 16
ORG 0

CS = 0x1B00 (physical adress is 0x1B000).

GDT is loaded at physical adress: 0x10800.
KERNEL is loaded at physical adress: 0x1000.

Code in second stage:

Code: Select all

     cli                                        ; Wylaczamy przerwania

     in  al, 0x70                               
     or  al, 0x80                               
     out 0x70, al                              

     xor ax, ax                                 
     mov ds, ax                                

     o32 lgdt [0x1B000 + GDT_Reg]

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

     jmp 0x8:0x1000                            


.
.
.

GDT_Reg: 

dw 512                                 
dd 0x10800                           
  
And after running this code bochs resets PC with result:

fetch_raw_descriptor: GDT: index (f)1 > limit (0)
interrupt(): gate descriptor is not valid sys seg
interrupt(): gate descriptor is not valid sys seg

And my GDT looks like this:

Code: Select all

; 0
         dw 0          ; NULL Deskryptor
         dw 0     
         db 0     
         db 0     
         db 0     
         db 0
; 8
         dw 0xFFFF     ; Deskryptor DPL-0 dla 4GB kodu
         dw 0    
         db 0    
         db 10011010b    
         db 11001111b   
         db 0  
; 16
         dw 0xFFFF     ; Deskryptor DPL-0 dla 4GB danych
         dw 0    
         db 0    
         db 10010010b    
         db 11001111b   
         db 0
; 24
         dw 0x0002     ; Deskryptor DPL-0 dla 8KB stosu (od 76 do 84KB)
         dw 0x3000     ; Limit: 8KB   ;2FFF
         db 0x01       ; Adres: 76KB
         db 10010010b  ; Expand up 
         db 11000000b   
         db 0
; 32
         dw 0xFFFF     ; Deskryptor DPL-3 dla 4GB kodu
         dw 0   
         db 0    
         db 11111010b    
         db 11001111b   
         db 0   
; 40
         dw 0xFFFF     ; Deskryptor DPL-3 dla 4GB danych
         dw 0   
         db 0   
         db 11110010b    
         db 11001111b   
         db 0
; 48
         dw 0x2600     ; System TSS Deskryptor (9728bajtow-0x2600)
         dw 0x0A00     ;\Adres poczatkowy - 0x10A00
         db 0x1        ;/
         db 11101001b  ; DPL-3, NOT-BUSY
         db 0          ; 1B gran, AVL-0
         db 0


; TEMPORARY
; 56
         dw 0x0001     ; Deskryptor DPL-3 dla 4KB stosu (od 76 do 80KB)
         dw 0x2FFF     ; Limit: 4KB
         db 0x01       ; Adres: 76KB
         db 11110010b  ; Expand up 
         db 11000000b   
         db 0
Please help ;(.

Posted: Thu Dec 28, 2006 2:49 pm
by earlz
Did you create a gdt pointer?
what did you use to load your gdt(what's the exact line)

edit:
oops didn't read all of your post, ignore above..

Posted: Thu Dec 28, 2006 4:27 pm
by Combuster
First:

Code: Select all

o32 lgdt [0x1B000 + GDT_Reg]
You need to be in Unreal Mode to do this. I dont see that, nor can i see wether it assembles to the correct opcode. Bochs comes up with a GDT limit of 0 which cant really be correct...

Also, the size portion of your GDTR seems to be incorrect - it should be descriptors * 8 - 1. In your case that is 63 (or 511 if you want to reserve area for expansion), but at least not 512

Re: Running PM again.. ;/

Posted: Thu Dec 28, 2006 5:03 pm
by INF1n1t
I know what I'm saying is stupid, but try the GDT without the null segment...I think you will get more mistakes..but try it, it may work!

Posted: Fri Dec 29, 2006 2:31 am
by mrkaktus
Ok firts thing, GDT is loaded from file, that is filled with zerous up to 512 bytes, so size of 512 is correct and is fixed for ever so when I am doing changes in GDT I don't need to change this parameter every time. And this GDT is correct because when I was starting PM from first stage bootloader it works fine.

So the problem is that this code in first stage is working:

BITS 16
ORG 7c00
(CS = 0000)

Code: Select all

     cli                                        
     in  al, 0x70                               
     or  al, 0x80                               
     out 0x70, al                              

     xor ax, ax                                
     mov ds, ax                                

     lgdt [GDT_Reg]                             
     mov eax,cr0                                
     or  eax,1                                  
     mov cr0,eax                               

     jmp  8h:IN_PM                             

.
.
.

[BITS 32]
IN_PM:
jmp 0x1000                                     

GDT_Reg: 

dw 512                                
dd 0x10800   
                          
times 510-($-$$) db 0                           
        dw 0xAA55       
And thesame code remaked for second stage that I mentioned in first post isn't working.

I think that this absolute adress could have something wrong to do, like you say Unreal Mode. But in this case how it is possible to have GDT_Reg in higher location that 64KB ?

Posted: Fri Dec 29, 2006 2:43 am
by mrkaktus
Yeaaahh !!!

It works :). I move GDT_Reg under 64KB boundary to my fixed data area (first 4KB of ram) and it works!!

This is a code:

BITS 16
ORG 0

CS = 0x1B00 (physical adress is 0x1B000).

GDT is loaded at physical adress: 0x10800.
KERNEL is loaded at physical adress: 0x1000.

Code: Select all


cli                                        ; Wylaczamy przerwania 

     in  al, 0x70                                
     or  al, 0x80                                
     out 0x70, al                              

     xor ax, ax                                  
     mov ds, ax                                

     mov word [DS:0x6F6], 512
     mov dword [DS:0x6F8], 0x10800

     o32 lgdt [0x6F6] 

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

     jmp 0x8:0x1000                           

Thanks for sugestions :).

Posted: Fri Dec 29, 2006 4:14 am
by Combuster
mrkaktus wrote:Ok firts thing, GDT is loaded from file, that is filled with zerous up to 512 bytes, so size of 512 is correct
No its not. The limit is given as the last accessible byte from the start of the GDT. in your case, the GDT is 512 bytes in size, starting at 0x10800 to 0x109ff (0x10A00 does no longer belong to the GDT). The limit = 0x109ff-0x10800=0x1ff=511.
I think that this absolute adress could have something wrong to do, like you say Unreal Mode. But in this case how it is possible to have GDT_Reg in higher location that 64KB ?
Use Unreal Mode as said, or use the real mode segment selectors to your advantage (which work up to the 1MB).