flat assembler
Message board for the users of flat assembler.

Index > OS Construction > OS triple faults

Author
Thread Post new topic Reply to topic
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 06 Aug 2006, 21:35
Hey, I've written my own bootloader & OS Code, and basically what happens is the bootloader boots up, and then loads the OS code which starts off with the GDT. What happens though is that it triple faults and resets my computer. If someone could help I'd be very appreciative.

Here's the loader code:
Code:
;BOOTSTART
org 7C00h

jmp start

message db 'Loading RhynOS...',13,10,0

start:
        xor ax, ax
        mov ds, ax

        mov si, message
        call bios_print

load_os:
        mov ax, 0060h
        mov es, ax
        mov bx, 0000h
        mov ah, 02h
        mov al, 1
        mov ch, 0
        mov cl, 2
        mov dh, 0
        ;mov dl, 0  ; Not sure if needed, been told that dl already contains the drive that was booted on
        int 13h
        jmp 0060h:0000h

bios_print:
        lodsb
        or al, al
        jz done
        mov ah, 0x0E
        int 0x10
        jmp bios_print

done:
        call load_os

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


And here's the OS code:

Code:
org 0000h
use16
cli

mov ax, 0
mov ds, ax

lgdt [gdt_descriptor]

mov eax, cr0
or eax, 1
mov cr0, eax

jmp 08h:clear_pipe

use32
clear_pipe:
mov ax, 10h
mov ds, ax
mov ss, ax

mov esp, 090000h

mov byte [ds:0B8000h], 'P'
mov byte [ds:0B8001h], 1Bh

infinite_loop:
        jmp infinite_loop
;start:
;mov ax, 0013h
;int 10h

;mov bx, 0A000h
;mov es, bx

;mov bx, 0
;mov ah, 0

;mov cx, 64000

;startloop:
;mov [es:bx], ah
;inc bx
;inc ah
;loop startloop

gdt:
dd 0, 0
gdt_code:
db 0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0
gdt_data:
db 0FFh, 0FFh, 0, 0, 0, 10010010b, 11001111b, 0
gdt_end:

gdt_descriptor:
    dw gdt_end - gdt - 1
    dd gdt

times 512-($-$$) db 0    
    


BTW - Please ignore the commented drawing routines in there, those were from a prior 16-bit mode test.
Post 06 Aug 2006, 21:35
View user's profile Send private message Reply with quote
Artlav



Joined: 23 Dec 2004
Posts: 188
Location: Moscow, Russia
Artlav 07 Aug 2006, 05:28
OK, run it through a debugger.

Fifth line:
mov ax, 0
mov ds, ax

You load your OS at segment 60h offset 0h.

By putting 0 in the ds you make it load GDT not from the 60h:gdt_descriptor but from 0:gdt_descriptor.
(lgdt [gdt_descriptor] = lgdt ds:[gdt_descriptor])

That's first one.

Second, lgdt must use linear address of gdt, not segment-relative, so add sixth line
add dword [gdt_descriptor+2],600h

That's the second one.

Third one is in the idea - in GDT segment base is 0.
Code is compiled to be at base 0.
But when you switch to PM, your code appears at base 600h, since it loaded at 60h:0h
So, add org 600h+$ before use32.

And you don't want GDT to be after second org, so put it between jmp to pm and org #2.


Code:
org 0000h 
use16 
cli 

mov ax, 0060h
mov ds, ax
add dword [gdt_descriptor+2],600h 

lgdt [gdt_descriptor] 

mov eax, cr0 
or eax, 1 
mov cr0, eax 

jmp 08h:clear_pipe 




gdt: 
dd 0, 0 
gdt_code: 
db 0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0 
gdt_data: 
db 0FFh, 0FFh, 0, 0, 0, 10010010b, 11001111b, 0 
gdt_end: 

gdt_descriptor: 
    dw gdt_end - gdt - 1 
    dd gdt 





org 0600h+$
use32 
clear_pipe: 
mov ax, 10h 
mov ds, ax 
mov ss, ax 

mov esp, 090000h 

mov byte [ds:0B8000h], 'P' 
mov byte [ds:0B8001h], 1Bh 

infinite_loop: 
        jmp infinite_loop 

times 512-($-$$) db 0     
    
Post 07 Aug 2006, 05:28
View user's profile Send private message Visit poster's website Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 08 Aug 2006, 07:40
Thanks Artlav! I'll work with it tomorrow... It's 3:39 AM now, so it's kinda late for me.

- I actually just tried it, and it works, so thank you! Only thing is I didn't fully understand the second and third points you made, and as far as the last thing you said, about where the GDT would lie, I'm wondering why does that matter? If you could explain that to me, I'd be very grateful. Thanks!
Post 08 Aug 2006, 07:40
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 08 Aug 2006, 18:22
Also, since I've got that working (thanks again, Artlav!) I tried adding VGA coding to my os, and I'm wondering why it's not working? Could someone please explain drawing graphics in P-mode to me?

Also, if you wish to take a look at this, here's the OS code:

Code:
org 0000h
use16
mov ax, 0013h
int 10h
cli

mov ax, 0060h
mov ds, ax
add dword [gdt_descriptor+2], 600h

lgdt [gdt_descriptor]

mov eax, cr0
or eax, 1
mov cr0, eax

jmp 08h:clear_pipe

gdt:
dd 0, 0
gdt_code:
db 0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0
gdt_data:
db 0FFh, 0FFh, 0, 0, 0, 10010010b, 11001111b, 0
gdt_end:

gdt_descriptor:
    dw gdt_end - gdt - 1
    dd gdt

org 0600h+$
use32
clear_pipe:
mov ax, 10h
mov ds, ax
mov ss, ax

mov esp, 090000h

;mov byte [ds:0B8000h], 'P'
;mov byte [ds:0B8001h], 1Bh
mov bx, 0A000h
mov es, bx

mov ebx, 0
mov ah, 0

mov cx, 64000

startloop:
mov [es:ebx], ah
inc ebx
inc ah
loop startloop

infinite_loop:
        jmp infinite_loop

times 442-($-$$) db 0    
    


I thought that I was doing this correctly because it works when I'm in 16-bit real mode. So I'm pretty much confused. Confused
Post 08 Aug 2006, 18:22
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 09 Aug 2006, 06:52
you cannot just use

mov bx, 0A000h
mov es, bx

in protected mode. This won't work.
I suggest you to try reading IA-32 manuals...
Post 09 Aug 2006, 06:52
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Aug 2006, 19:06
Well, I have read the IA32 manuals, but I don't recall them talking about accessing video modes.
Post 09 Aug 2006, 19:06
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 09 Aug 2006, 20:41
it's a question of segmentation, but not video memory addressing.
when you're in protected mode, you cannot just load segment selector via

mov gp_reg, addr
mov segment_reg, gp_reg

remember? you did

lgdt [gdt_descriptor]

to load GDTR. So, if you defined GDTR Base = 0 then you can access video memory with its linear address. for example

mov byte [es:0A0000h], 'A'
Post 09 Aug 2006, 20:41
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 10 Aug 2006, 23:56
Of course! I think I see what you're saying now! I'm loading it from segment 0, in which instead I should be loading it from segment 10h (I think that's a segment number, at least)!!! LOL, and it even showed that in the freakin' code! Embarassed Man... Sorry for the nuisance, I guess I've just been a bit off lately with things. But I think I'm starting to understand more what you're saying. Y'see, I'm still kinda new to how the descriptor tables work.

Thank you though for your patience and kindness in these matters. Smile
Post 10 Aug 2006, 23:56
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 11 Aug 2006, 00:20
Well, I guess I still must have it wrong, because it still doesn't work. I tried what was commented out as far as the textual video memory, the:

;mov byte [ds:0B8000h], 'P'
;mov byte [ds:0B8001h], 1Bh

And instead did this:

Code:
mov ah, 0
mov ebx, 0A000h

mov cx, 64000 ;Loop counter

startloop:
    mov byte [ds:ebx], ah ;ds is still set to what it's set to above,  10h
    inc ebx
    inc ah
    loop startloop
    


And basically nothing shows up on the screen.
Post 11 Aug 2006, 00:20
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 11 Aug 2006, 00:56
oh, my! didn't you find your mistake, yet?

mov ebx, 0A000h

you write 0A000h to ebx, which is the real-mode segment address.
you should write 0A0000h, because linear_address = segment*10h+offset
Post 11 Aug 2006, 00:56
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 11 Aug 2006, 02:41
Sorry I didn't reply sooner! I found it out earlier, yes. Nevertheless, thank you. Smile

The reason that I was using 0A000 was because of the segment:offset, and 0A000 was the segment, but this time the video memory is the offset with the segment being memory segment 10h. Thank you for your time and help. Also, does it matter whether or not I use ecx as opposed to cx since I'm in 32-bit mode now?

Still I'm curious why Artlav told me to do this:
Code:
add dword [gdt_descriptor+2],600h 
    


Again, I am sorry if I am being a nuisance here, but as I have said previously I'm still new to how the GDT deals with memory.
Post 11 Aug 2006, 02:41
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 11 Aug 2006, 06:53
Quote:
Again, I am sorry if I am being a nuisance here

Hey, stop your excuses. We're here to ask questions and learn new things.

you have to add 600h to gdt_descriptor, because you load linear address with LGDT command, not segment:offset.

one more thing, never use loop instruction. it's toooo slooooow

label:
. . .
dec ecx
jnz label

is much faster.

you may use any GP registers you like both in protected and real modes.

Yea, I forgot to write about Gate-A20 last time... Where's your Gate-A20 enable routine? find and read some articles about A20 if you're not familiar with it.
Post 11 Aug 2006, 06:53
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 11 Aug 2006, 08:28
Okay, I've heard of it, but still don't know what it is used for (most things I've looked at that have mentioned it just beat around the bush and never exactly explained what it does). Thanks for all the help!
Post 11 Aug 2006, 08:28
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 11 Aug 2006, 08:43
A20 is an address line which allows you to access 64kbytes of memory above 1MB (100000h) in real mode (from 0FFFFh:0010h to 0FFFFh:0FFFFh). Also, if this line is disabled, then 1MB addresses will be wrapped. In example, if you try to write a byte at address 0FFFFh:0610h (100600h linear), then this byte will be actually written at address 0:0600h (000600h) because 20th bit cannot be set (it's not allowed that this bit is equal to 1). It concerns all address ranges that have 20th bit set: from 100000h to 1FFFFFh; from 300000h to 3FFFFFh, etc.
Post 11 Aug 2006, 08:43
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 11 Aug 2006, 21:40
Cool... Wait, you mean the 4GB of memory altogether? I thought I already set that up in my code. If you look closely I have both a data and code segment set up, which I thought the two together worked together to allow me to have 4GB of memory?

But then again, could you give me some links on it, just in case I'm wrong on that?
Post 11 Aug 2006, 21:40
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 11 Aug 2006, 22:16
I don't have any links on this topic. try google, wikipedia, osdever.net and other OSDev related sites. The whole Internet is for you...
Yes, you've enabled protected mode with 4GB segments... but try to write smth. at address 100000h and read the same value. I'm sure, you'll get wrong result if A20 isn't enabled.
Post 11 Aug 2006, 22:16
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.