Where do i start??

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.
Berserk

Re:Where do i start??

Post by Berserk »

Thank you sooooo much, this has helped ALOT!! ;D
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Ok this is how far i have gotten, i have made a BootSector that loads a BootLoader, I got my kernel to load at 0x1000, Now i am having problems getting into Protected Mode ;D

Ok, So i need a GDT (Global Descriptor Table); What is in a GDT? I tried using somebody elses code but it just triple faulted the cpu :'( So, i will take it one step at a time ;D, First of all, what do i need to put in a GDT?

Cya.
jrfritz

Re:Where do i start??

Post by jrfritz »

Here:

Use this GDT...but it just before the "times" in your bootsector:

GDTR
dw GDTEnd-1
dd GDT
GDT
nullsel equ $-GDT
GDT0
dd 0
dd 0
CodeSel equ $-GDT
dw 0ffffh
dw 0
db 0
db 09ah
db 0cfh
db 0h
DataSel equ $-GDT
dw 0ffffh
dw 0h
db 0h
db 092h
db 0cfh
db 0
GDTEnd

and, just before the enter pmode with the cr0 stuff, put this code:

lgdt [ GDTR ]

your code should look like this:

   lgdt [ GDTR ]      ; Load the GDTR.

; Set Protected Mode ( PMode )
mov eax,   cr0
or eax,      1
mov cr0,   eax      ; PMode bit set.
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Well, i've spent a couple of hours trying to make this work. Then i tryed to use another GDT, but bochs keeps on Triple Faulting, so i am just going to post the code here, in hope that you'se will help ;D

This is my Second Stage Loader:

Code: Select all

[BITS 16]
[ORG 0x7E00]

;Jump over the Functions & Variables, and goto the BootCode
 jmp StartOf_Code

 BootDrive db 0

 StartOf_Code:
                 mov [BootDrive], dl

;Reset the FloppyDrive
 Reset_FloppyDrive:
                mov ax, 0x00               ;Select Reset Function
                mov dl, [BootDrive]        ;Select Drive to Reset
                int 0x13                   ;Call FloppyDrive Interrupt

                jc Reset_FloppyDrive       ;If there is an Error, Try Again!

;Read in Kernel
 ReadIn_Kernel:
                mov dl, [BootDrive]        ;Drive to Read From

                mov ax, 0x9000             ;Segment to load DiskData to
                mov es, ax

                mov bx, 0                  ;Offset

                mov ah, 0x02               ;Get the Segment:Offset from ES:BX

                mov ch, 0                  ;Cylinder
                mov dh, 0                  ;Head
                mov cl, 6                  ;Sector to Start Loading at
                mov al, 10                 ;Sectors to Load

                int 0x13                   ;Read!

                jc ReadIn_Kernel           ;If there is an Error, Try Again!

;Enter PM (Protected Mode)
 Enter_ProtectedMode:

 ;Disable Interrupts
                cli

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

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

   call   Empty_8042
   jmp      A20_GateDone

Empty_8042:

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

A20_GateDone:

; Move the GDTR_BASE_ENTRIES into place
   mov      ax, 0x1000
   mov      es, ax
   mov      si, GDTR_BASE_ENTRIES
   xor      di, di
   mov      cx, 6
   cld
   rep      movsd

;Load the GDT (Global Descriptor Table)
                lgdt [GDTR_PTR]

; Set PE (PMode) Bit
   mov      eax, cr0
   or      eax, 1
   mov      cr0, eax

; Jump into PMode Code
                jmp 0x08:In_ProtectedMode

[BITS 32]

;This is where Protected Mode is Entered!
 In_ProtectedMode:

        ; Put the Data Selector into eax for setting up other registers.
        mov eax,   0x10      ; Data Selector.

   ; Make SS, DS, ES, FS and GS = the Data Selector ( In the GDT )
        mov ss, eax
        mov ds, eax
        mov es, eax
        mov fs, eax
        mov gs, eax

   ; Set up the PMode stack:
        mov ax, 0x10
        mov ss, ax
        mov esp, 0xFFFF

                jmp 0x9000               ;Jump to the Kernel

GDTR_PTR
   dw 0xffff
   dd 0x00010000

GDTR_BASE_ENTRIES
   dd 0
   dd 0

   db 11111111b   ; 7:0 of Limit
   db 11111111b   ; 15:8 of Limit
   db 00000000b   ; 7:0 of Base
   db 00000000b   ; 15:8 of Base
   db 00000000b   ; 23:16 of Base
   db 10011010b   
   db 11001111b   
   db 00000000b   ; 32:24 of Base

   db 11111111b   ; 7:0 of Limit
   db 11111111b   ; 15:8 of Limit
   db 00000000b   ; 7:0 of Base
   db 00000000b   ; 15:8 of Base
   db 00000000b   ; 23:16 of Base
   db 10010010b   
   db 11001111b   
   db 00000000b   

GDTEnd

 CodePadding     times 2048-($-$$) db 0
Berserk

Re:Where do i start??

Post by Berserk »

Could Somebody Please help out if they can.....
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Ok, i think i have isolated the problem, the code seems to be triple faulting here:

Code: Select all

                jmp 0x8000               ;Jump to the Kernel
It seems to go into Protected Mode, How can i check if i am in Protected Mode? Then i will know where the problem is ;D

Thanks in Advance, Ciao ;)
beyondsociety

Re:Where do i start??

Post by beyondsociety »

Access the video memory directly.

Try this:

Code: Select all

mov byte [ds:0B8000h], 'P'      
mov byte [ds:0B8001h], 1Bh
If this works, then you are in protected mode. Another way to tell if your in pmode is if the floppy light stays on forever when you boot from a floppy drive.

Note: if your using bochs to test, you will see the letter P in pmode but not the floppy light staying on. You have to test it on a real machine.

Of course this is going to be your problem.

Code: Select all

jmp 0x8000              ;Jump to the Kernel
Put a

Code: Select all

jmp $

before this and comment out this line. In order to use the jmp to the kernel, you have to set it up like this:

Code: Select all

jmp 0x8:0x8000  ; jump to C/asm kernel
Hope this helps. Don't feel bad, I've had this problem before.
jrfritz

Re:Where do i start??

Post by jrfritz »

In FritzOS...the jump to the kernel depends on the GDT...like this:

jmp CodeSel:0x8000
Berserk

Re:Where do i start??

Post by Berserk »

Thanks,

It goes into Protected Mode, i found out by the floppy motor ;D

There's something wrong with me loading the Kernel or Jumping to It. I'll have a look at it when i have some time ;D

Ciao.
Berserk

Re:Where do i start??

Post by Berserk »

Hey Everybody,

I am ready to go back to OS Dev ;D Ok, here i have some newbie questions on assembler and OS Dev ;D So please bear with me :)

Ok:

In most BootSectors, BootLoaders and other assembler programs i see this:

Code: Select all

;Initialise the Segment Registers
                xor ax, ax
                mov ds, ax
                mov es, ax
                mov fs, ax
                mov gs, ax
This sets all the registers to 0 right? Then instead of puting "xor ax, ax" Would puting "mov ax, 0" Do the same thing? And why do the registers need to be set to 0?

And also, in my GDT (I am using PlayOS's GDT) There is this Code:

Code: Select all

                mov ax, 0x1000
                mov es, ax
                mov si, GDT
                xor di, di
                mov cx, 6

                cld

                rep movsd
What i figured is that this code loads the GDT into memory, then the GDT pointer points to it, Am i right? Is this what the code does? And also could somebody please explain to me what each function of the code does?

Here is my code to set up a Protected Mode Stack:

Code: Select all

;Put the Data Selector into eax for setting up other registers
                mov eax, 0x10

;Make SS, DS, ES, FS and GS = The Data Selector
                mov ss, eax
                mov ds, eax
                mov es, eax
                mov fs, eax
                mov gs, eax

;Set up a Protected Mode Stack
                mov eax, 0x10
                mov ss,  eax
                mov esp, 0xFFFF
Could Somebody please explain this code to me, and also, why are the registers loaded with 0x10?

Ok, i got one more question:

Which Selectors can i use using my GDT (The Code is in a Previous Post)? And i am having trouble loading my Kernel starting on sector 6 on my floppy, it is 9 sectors big ;D Could somebody please post some example code on how to load it and jump to it, i am having big problems trying to load it, my cpu keeps triple faulting :'(

Cya.
Curufir

Re:Where do i start??

Post by Curufir »

Berserk wrote:

Code: Select all

;Initialise the Segment Registers
                xor ax, ax
                mov ds, ax
                mov es, ax
                mov fs, ax
                mov gs, ax
"mov ax, 0" works fine, the "xor ax,ax" just saves a byte. This kind of thing gets used by people that set "org xxx" at the top of their code. The segment registers are set to zero because the assembler takes care of making sure jumps are offset correctly within the segment. Effectively they are making all memory addresses as 0:offset.

Code: Select all

                mov ax, 0x1000
                mov es, ax
                mov si, GDT
                xor di, di
                mov cx, 6

                cld

                rep movsd
He moves 6 doublewords from the addresses following the label GDT to addresses following 0x10000. This is just moving everything to the place he wants it. Presumably in his kernel scheme the GDT will live permanently in memory following 0x10000.

Code: Select all

;Put the Data Selector into eax for setting up other registers
                mov eax, 0x10

;Make SS, DS, ES, FS and GS = The Data Selector
                mov ss, eax
                mov ds, eax
                mov es, eax
                mov fs, eax
                mov gs, eax

;Set up a Protected Mode Stack
                mov eax, 0x10
                mov ss,  eax
                mov esp, 0xFFFF
This code sets up all segment registers to be loaded with the second selector in the GDT. It's reasonable to assume that this is a data selector, and extrapolating general posts on this board that it is a 4gb limit 0 base selector. Without a valid selector in PMode the processor will not function properly (This can be useful, research big real mode for details). In PMode addressing is done via selector:offset, so when you address a piece of memory, eg mov ax,[some label] then what actually happens is the processor uses the base of the selector in ds, adds offset to it, checks permissions and limits then retrieves the data.
beyondsociety

Re:Where do i start??

Post by beyondsociety »

Code: Select all

Which Selectors can i use using my GDT (The Code is in a Previous Post)?
0x00 = Null Segment Descriptor
0x08 = Code Segment Descriptor
0x10 = Data Segment Descriptor

There's two more but I don't know what they are. I suggest looking at the Intel manuals for reference.

Why do you want to load your kernel at sector 6 on the floppy drive? Normally it starts at Sector 2, Cylinder 0, Head 0

Heres an example

Code: Select all

mov ah,0x02            ; load disk data to ES:BX
mov al,5                   ; load 5 sectors
mov ch,0                  ; cylinder = 0
mov cl,3                   ; sector = 2 (starts at sector 1 not 0)
mov dh,0                 ; head = 0 = side one
mov dl,0                  ; Floppy drive A = 0

int 0x13                   ; read it
jc read_me              ; if there's an error then we'll 

Code: Select all

Could somebody please post some example code on how to load it and jump to it, i am having big problems trying to load it, my cpu keeps triple faulting  
Are you trying to jump to a second-stage loader or trying to get into pmode and then jump to your kernel?
Berserk

Re:Where do i start??

Post by Berserk »

Hey,

Thanks Curufir.

Now, My BootSector loads my BootLoader (Second Stage Loader) to 0x7E00, It works perfectly, My BootLoader takes up 5 Sectors on the Floppy (well, it doesn't but i've given it space to get bigger ;D) And my Kernel Starts at Sector 6. My Kernel is 9 Sectors. I am loading my Kernel in Real Mode, then i jump to it in Protected Mode (I got PM up and running, it works ;D)

I also have a PM stack setup ;D I just need some example code to load my Kernel, i know how to use int 0x13, But i don't know where to load the Kernel?

What i mean by this is: I know HOW to load the Kernel, but i don't know WHERE to load it, what should i put as the Segment:Offset? (When i load it ;D)

Thanks everybody for your help, i have come a long way in OS Dev Since when i started (a couple of months ago ;D)

Ciao.
beyondsociety

Re:Where do i start??

Post by beyondsociety »

Since your in protected mode, you cant use the normal real-mode segment-offset pair. Its selector:0ffset.

Here's some example code from my OS

Code: Select all

jmp 0x08:0x1000   ; Jump to ASM/C Kernel
0x08 = Code Segment Descriptor. I.E part of your GDT

0x1000 = The address you want to load your kernel to

Are you going to load a C file or an ASM file? Depending on what your going to load, will depend on how you go about loading your kernel.

Hope this helps. Always glad to help a newbie ;)
Berserk

Re:Where do i start??

Post by Berserk »

Thanks,

My Kernel is a 'C' Bianary File. I use gcc, and the ld linker ;D And i use ObjCopy to make it Binary Format!

So, Is this code correct for loading my Kernel?

Code: Select all

;Read in BootLoader
 ReadIn_Kernel:
                mov dl, [BootDrive]        ;Drive to Read From

                mov ax, 0x08             ;Segment to load DiskData to
                mov es, ax

                mov bx, 0x1000             ;Offset

                mov ah, 0x02               ;Get the Segment:Offset from ES:BX

                mov ch, 0                  ;Cylinder
                mov dh, 0                  ;Head
                mov al, 4                  ;Sectors to Load
                mov cl, 6                  ;Sector to Start Loading at

                int 0x13                   ;Read!

                jc ReadIn_Kernel       ;If there is an Error, Try Again!
Then i would do "jmp 0x08:1000" (After i am in PM) Right?

But i can't load my Kernel to 0x1000 since my GDT is there ;D I'll load it Somewhere else ;D

Actually, Could i load my GDT to 0x500? And then Load my Kernel to 0x1000?

Thanks for your help, i'm nearly there ;)
Ciao.
Post Reply