Page 1 of 1

Protected Mode.

Posted: Sat Jan 29, 2005 3:57 pm
by Seph
Ok.
I give up.

I was really hoping that I wouldn't need to ask for help until at least I started the kernel... but apperarantly, I would...
So...

Code: Select all

;.
[BITS 16]
[ORG 0x100]
start:
jmp   go

display_text:
   mov   bl,0x07
   mov   ah,0x0E
   mov   bh,0x00
   .ch_loop:
      lodsb
      or   al,al
      jz   .ch_done
      int   0x10
      jmp   .ch_loop
   .ch_done
      ret

BootMsg:   db   "Second stage loaded",10,0
PModeMsg:   db   "Starting Protected Mode",13,0
   align   8
gdt:   dw   0x0017
   dd   0x7C00+gdt
   dw   0x0000
   dw   0xFFFF,0x0000,0x9A00,0x00CF
   dw   0xFFFF,0x0000,0x9200,0x00CF
go:
;Set variables and the stack
   cli
      mov   bl,0x07

   mov   ds,ax
   mov   es,ax
   mov   ss,ax
   mov   sp,0x500
   sti

   mov   si,BootMsg
   call   display_text

   mov   si,PModeMsg
   call   display_text

cli 
cld

in   al,0x92
or   al,2
out   0x80,al
out   0x92,al

lgdt   [gdt]
mov   eax,cr0
or   al,1
mov   cr0,eax

jmp   start:contin

contin:
[BITS 32]
   mov   eax,10h
   mov   es,eax
   mov   ds,eax
   mov   ss,eax         
   mov   esp,0x7C00

jmp $
This is my second stage loader. Loaded by the loader in the bootsector to 0x100.

It all works great. Until I try to set Pmode.
That's when it all breaks down.

I've been looking through tons of examples and tutorials, but since I could never find any that explained the theory behind it. I have no idea if for example 0x10 is right to load into the variables and stuff...

Any suggestions are appreciated. (to what I should do with this code that is) (to make it work the way I want it that is)

Re:Protected Mode.

Posted: Sat Jan 29, 2005 8:28 pm
by Brendan
Hi,

Code: Select all

[ORG 0x100]
gdt:   dw   0x0017
   dd   0x7C00+gdt
   dw   0x0000
   dw   0xFFFF,0x0000,0x9A00,0x00CF
   dw   0xFFFF,0x0000,0x9200,0x00CF
Seph wrote: This is my second stage loader. Loaded by the loader in the bootsector to 0x100.

It all works great. Until I try to set Pmode.
First you're telling the CPU that the GDT is at "0x7c00+gdt". As you're using [org 0x100] this would be (roughly) "0x7c00+0x100+some" while the GDT is probably nowhere near this. Try something like:

Code: Select all

gdt:   dw   0x0017
   dd   gdt
   dw   0x0000
   dw   0xFFFF,0x0000,0x9A00,0x00CF
   dw   0xFFFF,0x0000,0x9200,0x00CF
Seph wrote: I have no idea if for example 0x10 is right to load into the variables and stuff...
That's the other problem - loading this code to 0x100 overwrites the CPU's IVT and some BIOS data. Any interrupt above 64 (depending on how big your code becomes) will cause the computer to crash. By looking through Ralph Brown's Interrupt list you'll see that these interrupts are used by some BIOS's in some situations, so even if it works on one computer it might not work on another. Generally 0x0600 is the lowest unused/safe address that can be used while the BIOS being used (e.g. for printing characters to video and handling IRQs).


Cheers,

Brendan

Re:Protected Mode.

Posted: Sat Jan 29, 2005 10:34 pm
by ASHLEY4
There is a number of thing wrong with your code, i have no time to go through them now, here is some simple code, for getting in to pmode, see were the differences are.

Code: Select all

;************************************
; \\|//
; (@ @)
; ASHLEY4.
; Put test.bin on boot sector
; with rawrite.
; Assemble with fasm
; c:\fasm test.asm test.bin
;************************************
org 0x7C00
use16
;****************************
; Realmode startup code.
;****************************

start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00

;*****************************
; Setting up, to enter pmode.
;*****************************
        cli 
        lgdt  [gdtr]
        
        mov   eax, cr0
        or    al,0x1 
        mov   cr0,eax
 
        jmp   0x10: protected

;*****************************
; Pmode. ;-)
;*****************************

use32
protected:
        mov   ax,0x8
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   esp,0x7C00
;*****************************
; Turn floppy off .
;*****************************

        mov   dx,3F2h
        mov   al,0
        out   dx,al

        lea   esi,[msg0]                 
        mov   edi,0xB8000 + (80 * 3 + 4) * 2     
        mov   ecx,28
        cld
        rep   movsb

        jmp   $
;*************************************
; GDT. 
;*************************************

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF
gdt_end:

gdtr:       dw gdt_end - gdt - 1                                     
       dd gdt

;*************************************
; Data. 
;*************************************

msg0        db "  H E L L O   W O R L D !   " 

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
            
times 510- ($-start)  db 0
dw 0xaa55 

It's coded for fasm, but should easy convert, to nasm.

ps: you must have the same spacers in the string, for the code to print the string.

\\\\||////
(@@)
ASHLEY4.

Batteries not included, Some assembly required.

Re:Protected Mode.

Posted: Sun Jan 30, 2005 8:42 am
by bubach
I often had problems when the GDT is in the 16-bit area.. Put it at the end of your file.

Re:Protected Mode.

Posted: Sun Jan 30, 2005 9:48 am
by seph
Thanks.
I'll try what you said.

I have tried it with the gdt on other places too.
This is just one way I tried...

[LATER THAT DAY]

W00tage!
It works!
Some combination of ashleys code and playing around with the numbers made it work.

I was wrong btw. The second stage is loaded into 0x10000, not 0x1000

Now to figure out why my kernel won't load...