Page 1 of 1

Protected Mode

Posted: Wed Aug 21, 2002 5:05 pm
by Peter Liddle
hey Guys

I have written my own boot loader in nasm but it won't switch into protected mode properly. I am running a x86 emulator called bochs and it gives the following error

CS.d_b = 16 bit
SS.d_b = 16 bit

i think this is the key problem. I would post my code but it makes the message to long so if anyone would be willing to have a look for me let me know and ill send them the code

Re:Protected Mode

Posted: Thu Aug 22, 2002 1:07 am
by Pype.Clicker
just attach your code, then ...

Re:Protected Mode

Posted: Sat Aug 24, 2002 9:13 am
by Peter Liddle
Oh Okay how stupid do i feel

Code: Select all

; ------------------------------------------------------------------------
; Phoenix OS boot loader           (c)2002 Peter Liddle
; ------------------------------------------------------------------------
; This code is the boot loader for the Phoenix OS
; ------------------------------------------------------------------------
[BITS 16]      ;Set code generation to 16 bit mode
[ORG 0x0000]   ;Tell compiler this si offset 0, it isn;t but will be after jump

jmp BOOT


; -------------------------------------
; Data section
; ------------------------------------------------------------------------
DATA:   
   BootDrv      db   0x80

   BootMsg      db   'Booting Phoenix OS', 0x0D, 0x0A, 0   
   PModeMsg   db      'Jumping to Protected Mode', 0x0D, 0x0A, 0
   PModeEnabledMsg   db      'Where in Protected Mode at Last', 0x0D, 0x0A, 0

   EnablA20Msg   db   'Enabling A20 Line', 0x0D, 0x0A, 0
   A20EnabledMsg   db   'A20 Line is Now Turned On', 0x0D, 0x0A, 0

   IDTptr          DW 7FFh         ;LIMIT 256 IDT Slots
         DD 0000h      ;BASE (Linear)

   GDTptr          DW 17FFh      ;LIMIT 768 slots
         DD 0800h      ;BASE (Linear)

; ------------------------------------------
; Functions section
; ------------------------------------------------------------------------
.386
RESETDISK:                      ; Reset drive
   mov ax, 0              ;
        mov dl, [BootDrv]   ; Drive=BootDrv
        int 13h                ; Actually Reset
        jc RESETDISK              ; ERROR => reset again
   ret

READ:
   mov ax, 0x1000         ; ES:BX = 0x1000:0000
        mov es, ax             ;
        mov bx, 0              ;

   call RESETDISK      ; First Reset Disk
        mov ah, 0x2            ; Load disk data to ES:BX
        mov al, 0x1          ; Load 1 sectors
        mov ch, 0x0          ; Track=1
        mov cl, 0x2          ; Sector=2
        mov dh, 0x00           ; Head=0
        mov dl, [BootDrv]    ; Drive=BootDrv
        int 13h                ; Read!

        jc READ                ; ERROR => Try again
   ret

PRINTMSG:                       ; Dump ds:si to screen.
        lodsb                   ; load byte at ds:si into al
        or al,al                ; test if character is 0 (end)
        jz done
        mov ah,0eh              ; put character
        mov bx,0007             ; attribute
        int 0x10                ; call BIOS
        jmp PRINTMSG
   done:
        ret

CLEARBUF:
   XOR CX,CX
        in al, 64h              ; get input from keyboard status port
        test al, 02h            ; test the buffer full flag
        loopnz CLEARBUF           ; loop until buffer is empty
   ret
; ------------------------------------------------------------------------



; ------------------------------------------
; Boot Code
; ------------------------------------------------------------------------
BOOT:
   

   ;mov [BootDrv],dl   ; Save Boot Drive
   
   ;Set up Location of Data Segment
   mov ax,0x7C0
   mov ds,ax

   
   cli                ; Turn Off interrupts while we setup a stack and A20 and Get to P-Mode        
        
   ;Set Up Stack
   mov ax,0x9000      ; this seems to be the typical place for a stack
        mov ss,ax
        mov sp,0xFFFF      ; let's use the whole segment.  Why not?  We can :)
        

   mov si,BootMsg      ; display our startup message
   call PRINTMSG

   ;call READ      ; Load in a sector
   
   ;Enable A20 Address Line
   mov si,EnablA20Msg   ; display our startup message
   call PRINTMSG


   ;Turn on A20 Line
      
   call CLEARBUF      ; Wait till keyboard Buffer is empty
   
   mov al, 0D1h            ; keyboard: write to output port
   out 64h, al             ; output command to keyboard
   
   call CLEARBUF      ; Wait till keyboard Buffer is empty again

   mov al, 0x0DF           ; keyboard: set A20
   out 0x60, al            ; send it to the keyboard controller
   mov cx, 0x14

   call CLEARBUF      ; Wait 25 sec for A20 to be enabled
   
   nop
   nop

   mov si,A20EnabledMsg   ; display our startup message
   call PRINTMSG
   

   ;Lets Get Into P-Mode
   mov si, PModeMsg
   call PRINTMSG


   ; Set Global Descriptor Table here, this must be done PRIOR to Prot Mode
   LIDT [IDTptr]
   LGDT [GDTptr]
   
   mov eax, CR0      ; load the control register in
   or  eax, 1              ; set bit 1: pmode bit
   mov CR0, EAX            ; copy it back to the control register
   jmp $+2         ; and clear the prefetch queue
   nop
   nop

   db      066h, 0EAh
   dw      prot, 06h
   dw      08h


[BITS 32]
prot:   
   ; Set up segments
   mov ebx, 10h
   mov ds, bx
   mov es, bx
   mov fs, bx
   mov gs, bx

   mov si, PModeEnabledMsg
   call PRINTMSG


   MOV BX, 10h
   MOV DS,BX
   MOV ES,BX
   MOV FS,BX
   MOV GS,BX
   MOV SS,BX

   ;jmp 0x1000:0000


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



Re:Protected Mode

Posted: Sat Aug 24, 2002 12:53 pm
by frank
1. the is no gdt table
2. I suggest you do a far jump instead of jmp $+2,
jmp code:place (code is a segment specified in the gdt)
3. int 10h does not work in pmode, especially not if you don't do sti ;)
(and put it in the idtr)

Re:Protected Mode

Posted: Mon Aug 26, 2002 3:49 am
by Pype.Clicker
sti-ing will not enable int10h (neither in pmode nor in realmode !) cli/sti only affect IRQs receipt by the processor, but in no way does it have an effect on INT xx command...

And even if it did, the 16bits BIOS code is unlikely to work from pmode ;)

Re:Protected Mode

Posted: Tue Aug 27, 2002 9:00 am
by pskyboy
[attachment deleted by admin]

Re:Protected Mode

Posted: Tue Aug 27, 2002 10:41 am
by crazybuddha
jmp dword LINEAR_CODE_SEL:PMODECODE


A couple of notes though. This style of referencing the GDT is clever (tricky, whatever), but is not very informative for the beginner IMO. It is being copied over and over on this forum, but I suspect that it is rarely understood what the selector value means or why using the offset this way works. I hope I'm wrong.

You will need to actually put some code in the PMODECODE. But don't be shocked when you can't refer to any offsets. Since you opted for ORG 0x0, your offsets are relative to the value in DS (ie. 0x07c0). This will be meaningless once you make the switch to pmode.

You won't be able to see anything on the screen unless you write (or steal) some video code. So you probably won't know where it is working or not (except perhaps by not resetting the machine).