Still Having PMode Trouble

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
PlayOS

Still Having PMode Trouble

Post by PlayOS »

Hi again,

Nobody seems to want to touch my last post so I will just include the code here
and hopefully someone can help, I am new to OS programming and I have
been reading the theory and trying for days to get this boot code to work, I dont
understand why it doesn't work however it never triple faults my cpu so I dont know that it is not working, it just wont print the char to video memory so I can see that it has worked, anyway here is the code
can someone please have a look and help me out.

This code is written for NASM.

Thanks.


Here is the code:

[BITS 16]
[ORG 0x07C0]

jmp short PlayOSBoot

; ===========================================================
; The GDTR Limit and Base
gdtr
   dw 0xFFFF
   dd 0

; ===========================================================
; The GDT Setup Entries
gdt_start
   ; Null Segment Descriptor, 0x00
   dd 0         
   dd 0

   ; Code Segment Descriptor, 0x08
   db 11111111b   ; 4GB Limit
   db 11111111b   ; 4GB limit
   db 00000000b   ; Base 0
   db 00000000b   ; Base 0
   db 00000000b   ; Base 0
   db 10011010b   ; Present : Ring 0 : Code\Exec : Non-Conforming : Readable
   db 11001111b   ; 4KB Granularity : 32Bit : 4GB Limit
   db 00000000b   ; Base 0

   ; Data Segment Descriptor, 0x10
   db 11111111b   ; 4GB Limit
   db 11111111b   ; 4GB limit
   db 00000000b   ; Base 0
   db 00000000b   ; Base 0
   db 00000000b   ; Base 0
   db 10010010b   ; Present : Ring 0 : Data : Expand Up : Writable
   db 11001111b   ; 4KB Granularity : 32Bit : 4GB Limit
   db 00000000b   ; Base 0
gdt_end


; ===========================================================
; BootLoader Starting Position
PlayOSBoot:

   ; ====================================
   ; Move this code out of the way
   cld
   mov      ax, 0x4000
   mov      es, ax
   xor      di, di
   xor      si, si
   mov      cx, 0x0100
   rep      movsw

   ; ====================================
   ; Jump to the New Location
   jmp      0x4000:NewLocation
   
NewLocation:

   ; ====================================
   ; Move the GDT entries into position
   cld
   xor      ax, ax
   mov      es, ax
   mov      ax, 0x4000
   mov      ds, ax
   xor      di, di
   mov      si, gdt_start
   mov      cx, gdt_end - gdt_start - 1
   rep      movsb

   ; ====================================
   ; Enable the A20 Gate
   call   Empty_8042
   mov      al, 0xD1
   out      0x64, al

   call   Empty_8042
   mov      al, 0xDF
   out      0x60, al

   call   Empty_8042
   jmp      A20_GateDone

Empty_8042:

   mov      al, 0xD0
   in      al, 0x64
   test   al, 2
   jnz      Empty_8042
   ret

A20_GateDone:

   ; ====================================
   ; Disable Interrupts
   cli

   ; ====================================
   ; Load the GDTR
   lgdt   [gdtr]

   ; ====================================
   ; Set PM Bit
   mov      eax, cr0
   or      eax, 1
   mov      cr0, eax

   ; ====================================
   ; Jump into PMode Code
   jmp      dword 0x08:0x40000 + EnterPMode

EnterPMode:

   ; ====================================
   ; Set Data and Stack Segments
   mov      ax, 0x10
   mov      ds, ax
   mov      es, ax
   mov      fs, ax
   mov      gs, ax
   mov      ss, ax

   ; ====================================
   ; Is this actually going to put something into video memory
   mov      ecx, 0xB8000
   mov      word [ecx], 0x1E41

; Loop forever
HaltPlayOS:
   jmp    short HaltPlayOS

times 510-($-$$) db 0
PlayOS_Signature dw 0xAA55
Krom

Re:Still Having PMode Trouble

Post by Krom »

I have seen lot of things bad.

1- the ORG 0x07c0, you can use that org, but it will be more dificult for other things. i recomend you use ORG 0X7C00 or if you prefer ORG 0.

2- you use DS and still didnt initialize it. You doesnt know where is it pointing to when your code starts. in diferent computers may have diferent values, so best thing you should do is initialize it, if you use ORG 0X7C00 initialize it with 0(ds=0) if you use ORG 0; initialize it with 0x07C0. You must know that the offsets change if you change the ORG.

3-
; ====================================
; Move this code out of the way
cld
mov ax, 0x4000
mov es, ax
xor di, di
xor si, si
mov cx, 0x0100
rep movsw

; ====================================
; Jump to the New Location

in this jump you go to 0x4000:NewLocation, but NewLocation is with base 0x07c0 (what you put)
so It will jump to another diferent place that you doesnt know

jmp 0x4000:NewLocation

NewLocation:

; ====================================
; Move the GDT entries into position
Now you copy the GDT into the real mode IDT (at 0:0)
You may think that you will not need the realmode IDT but, that may change.
cld
xor ax, ax
mov es, ax
mov ax, 0x4000
mov ds, ax
xor di, di


at this point SI=OFFSET GDT_START, and because of the ORG 0x07C0 it will be 0x07C0 bytes more that what you wants.

mov si, gdt_start
mov cx, gdt_end - gdt_start - 1
rep movsb

4-
; ====================================
; Load the GDTR
again, the pointer to gdtr is wrong is 0x07c0 bytes more of what you wants.
lgdt [gdtr]

5-
; ====================================
; Jump into PMode Code
You cannot do this kind of jump, because the offset is more than 16 bits. You already have set the PE bit, but the CS segment isnt loaded to use 32 bit instructions, so you are limited to 16 bits offsets.

jmp dword 0x08:0x40000 + EnterPMode


You can read my boot sector, it is in one thread called something like "first i cant link, now i cant enter pmode", it is not very well comented, and i use lot of things to make code smaller, but it may help you.
PlayOS

Re:Still Having PMode Trouble

Post by PlayOS »

Thanks to Krom, I now have a working boot sector.
Post Reply