Where do i start??
Re:Where do i start??
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.
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.
Re:Where do i start??
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.
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.
Re:Where do i start??
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:
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
Re:Where do i start??
Hey,
Ok, i think i have isolated the problem, the code seems to be triple faulting here:
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
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
Thanks in Advance, Ciao
Re:Where do i start??
Access the video memory directly.
Try this:
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.
Put a
before this and comment out this line. In order to use the jmp to the kernel, you have to set it up like this:
Hope this helps. Don't feel bad, I've had this problem before.
Try this:
Code: Select all
mov byte [ds:0B8000h], 'P'
mov byte [ds:0B8001h], 1Bh
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
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
Re:Where do i start??
In FritzOS...the jump to the kernel depends on the GDT...like this:
jmp CodeSel:0x8000
jmp CodeSel:0x8000
Re:Where do i start??
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.
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.
Re:Where do i start??
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:
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:
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:
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.
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
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
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
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.
Re:Where do i start??
"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.Berserk wrote:Code: Select all
;Initialise the Segment Registers xor ax, ax mov ds, ax mov es, ax mov fs, ax mov gs, ax
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
mov ax, 0x1000 mov es, ax mov si, GDT xor di, di mov cx, 6 cld rep movsd
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.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
Re:Where do i start??
Code: Select all
Which Selectors can i use using my GDT (The Code is in a Previous Post)?
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
Code: Select all
Re:Where do i start??
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.
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.
Re:Where do i start??
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
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
Here's some example code from my OS
Code: Select all
jmp 0x08:0x1000 ; Jump to ASM/C Kernel
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
Re:Where do i start??
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?
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.
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!
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.