:( Mysterious Error

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.
Post Reply
Kyretzn

:( Mysterious Error

Post by Kyretzn »

Hey people, its me again.
Ive loaded some data from a disk into RAM...
Position 0x2000:0000
I want to jump to it from once im in Protected Mode.
... the result is Bochs looping over and over and over and over, floppy continuously spinning... then eventually it crashes and bochs yells at me about System timers.

Ive located the error, the point at which it tries to jump to the code loaded. A friend who does comp sci converted Real mode address 0x2000 to 0x8:2C000 or something...

Ill list both code for the Bootstrap ive written and code for the program im trying to load.
Both are .bin

Sorry, I havent commented it.
Ive just kinda hacked it together.


:: THE BOOTSTRAP ::

[BITS 16]
[ORG 0x7C00]

bStart:

mov bx, 0x2000 ;segment
mov es, bx ;make es point to segment
mov bx, 0 ;offset
mov ah, 02
mov al, 01
mov ch, 00
mov cl, 01
mov dh, 01
mov dl, 00
int 0x13

cli

xor ax, ax
mov ds, ax

lgdt [gdt_desc]

mov eax, cr0
or eax, 1
mov cr0, eax
jmp 08h:clear_pipe

[BITS 32]
clear_pipe:
mov ax, 10h
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 090000h

mov byte [ds:0B8000h], 'P'
mov byte [ds:0B8001h], 07h
mov byte [ds:0B8002h], 'M'
mov byte [ds:0B8003h], 07h
mov byte [ds:0B8004h], '!'
mov byte [ds:0B8005h], 07h

jmp 0x8:0x2C000 ;<-- problem I know of. It jumps
;where I suppose the code isnt located, just ends up
;looping over and over, giving me an eventual System Timer
;issue

hang:
jmp hang

gdt:

gdt_null:
dd 0
dd 0

gdt_code:
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0

gdt_data:
dw 0FFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:

gdt_desc:
dw gdt_end - gdt - 1
dd gdt

times 510-($-$$) db 0


:: THE PROGRAM I WANT TO RUN ::

[BITS 32]
[ORG 0x00]

mov byte [ds:0B8000h], 'O'
mov byte [ds:0B8001h], 07h
mov byte [ds:0B8002h], 'K'
mov byte [ds:0B8003h], 07h
mov byte [ds:0B8004h], '!'
mov byte [ds:0B8005h], 07h

hang2:
jmp hang2

times 512-($-$$) db 0


Thank you for any help.
Please explain what the error is, if you can find it.
Time for bed, its 4am!

~Kyretzn
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re::( Mysterious Error

Post by Pype.Clicker »

Kyretzn wrote:
Ive located the error, the point at which it tries to jump to the code loaded. A friend who does comp sci converted Real mode address 0x2000 to 0x8:2C000 or something...
i'd say you shouldn't blindly trust that friend ... i hardly see how "0x2000 * 16 + 0" will result in 0x2c000 ... that'd rather be 0x20000 (unless he also gave you a very weird GDT).
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

We tried jumping to your address, but it didnt work either.
Its very frusterating having errors like these.
But Ill tell you, Ive spent so much time checking through stuff in Hex and stuff. that it kept me up... VERY late... super late.
Atleast im learning :)
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

I found a bug in the gdt_data segment.

gdt_data:
dw 0FFFh ;<-- here it is., it should be 0FFFFh!
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:

APparently though, same friend says it shouldnt matter at this point because we havent called any data... I beg to differ, I think it needs to be set.

Please guys, I dont understand why my code for PM jumping isnt working.

:(

~Kyretzn
0Scoder
Member
Member
Posts: 53
Joined: Sat Nov 11, 2006 8:02 am

Re::( Mysterious Error

Post by 0Scoder »

lol dude I think you also need to set cs (code segment):
put in a

Code: Select all

mov ax, 08h
mov cs, ax
so it will look like this:

Code: Select all

[BITS 32]
clear_pipe:
mov ax, 08h
mov cs, ax
mov ax, 10h
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 090000h
Also, have you left out the code to load your program into memory? Or have I missed something...
johandj

Re::( Mysterious Error

Post by johandj »

As far as I know the code should now be correct (after correcting the GDT).
OScoder: It is not possible to set cs using a move instruction, cs will be set by the far jump instruction. If you would change the value of cs while you're executing code, the code will suddenly be fetched from a different segment and thus a different memory address. In that case the move-to-cs instruction would act like a jump. Usually you want to set both cs and (e)ip at the same time, for that purpose the far jump instruction exists.
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

Could you please give me an example of how I would say, far jump to Protected Mode value of 0x2000:0000?

(Im not at all sure how to do this, Im leaving for Class now, Ill check NASM doc when I get back).

also, in my source :

jmp 0x8:0x2C000

a) the address is 16dec * 0x2000h + 0 = 20000
(thanks Pype!)

b) but im not sure what the 0x8 is for.
I dont see why its needed.

Would you mind explaining that to me?
Sorry about these newbie questions, just ive been reading
through the FAQ, and ive almost read everything there.
And I still cant think of the reason.

Thanks!
~Kyretzn
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

Also, just so you know (maybe itll help)
(I just opened the disk of mine in a HEx Editor, and the second sector.. seems amazingly bare, yet the first 2 bytes of the 3rd sector have a Z ... and numbers.)

Im compiling the bootloader and program like so :

nasmw -f bin gbootl.asm -o gbootl.bin
nasmw -f bin gprog.asm -o gprog.bin

then copying it to disk like so :
partcopy gbootl.bin 0 200 -f0
partcopy gprog.bin 0 200 -f0 400

~Kyretzn
Kemp

Re::( Mysterious Error

Post by Kemp »

Offset 400 is the third sector on the disk
NotTheCHEAT

Re::( Mysterious Error

Post by NotTheCHEAT »

Some of this information you might find in the OS dev FAQ... ::)

btw, when posting code (in any language) you should enclose it in "[ code ]" and "[ / code ]" BBCode tags (except delete the spaces, of course). This (naive example which you don't have to understand in order to get the point):

Code: Select all

mov ax, 0
int 33h
looks so much better than this:

mov ax, 0
int 33h

Just a bit of friendly advice ;)
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

:/ Ive fixed my code... and ive loaded data into memory (as far as I know)... IVe fixed the Selector...

yet, the same thing happens in bochs. It looks like it keeps restarting over and over and over and then it gives me :

Also, what I dont understand (this is happening from a real floppy).

The disk drive light is on constantly. But then, I Guess if its causing bochs to reboot, that makes sense. However, it happens on my laptop aswell.

It doenst reboot the machine, but the FDD light is on like its being used hardcore...
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

Latest code:

Code: Select all

[BITS 16]
[ORG 0x7C00] 

bStart:
reset_drive:
  mov ah, 0
  int 13h
  or ah, ah
  jnz reset_drive

  mov bx, 0x1000 ;segment
  mov es, bx ;make es point to segment
  mov bx, 0 ;offset
  mov ah, 02h
  mov al, 02h
  mov ch, 00h
  mov cl, 02h
  mov dh, 00
  mov dl, 00
    int 0x13

  cli
  
  xor ax, ax
  mov ds, ax

  lgdt [gdt_desc]

  mov eax, cr0
  or eax, 1
  mov cr0, eax
  jmp 08h:clear_pipe

[BITS 32]
clear_pipe:
 mov ax, 10h
 mov ds, ax
 mov ss, ax
 mov esp, 090000h

 mov byte [0B8000h], 'P'
 mov byte [0B8001h], 07h
 mov byte [0B8002h], 'M'
 mov byte [0B8003h], 07h
 mov byte [0B8004h], '!'
 mov byte [0B8005h], 07h

 jmp 08h:01000h

hang:
 jmp hang

gdt:

gdt_null:
  dd 0
  dd 0

gdt_code:
  dw 0FFFFh
  dw 0
  db 0
  db 10011010b
  db 11001111b
  db 0

gdt_data:
  dw 0FFFFh
  dw 0
  db 0
  db 10010010b
  db 11001111b
  db 0
gdt_end:

gdt_desc:
  dw gdt_end - gdt - 1
  dd gdt

times 510-($-$$) db 0
dw 0AA55h
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

And the program im trying to load is:

Code: Select all

[BITS 32]
[ORG 0x00]

 mov byte [0B8000h], 'O'
 mov byte [0B8001h], 07h
 mov byte [0B8002h], 'K'
 mov byte [0B8003h], 07h
 mov byte [0B8004h], '!'
 mov byte [0B8005h], 07h

hang2:
jmp hang2

times 512-($-$$) db 0

User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re::( Mysterious Error

Post by Brendan »

Hi,

The BIOS turns the floppy drive motor (and the floppy drive light) off after a delay. To do this delay the BIOS needs a timer (usually RTC/CMOS, IRQ8) and interrupts must be enabled. Because you disable interrupts (and switch to protected mode) the BIOS never gets a chance to turn the motor off, which is why your floppy light is on.

To turn the floppy motor/light off yourself, you'd need to add the following code:

Code: Select all

   mov dx,0x03F2
   clr al
   out dx,al
At the very start of your boot sector, resetting the drive should be unnecessary as you know that the BIOS just loaded the boot sector sucessfully.

For the code that loads the second and third sectors into memory, you aren't checking for errors from the BIOS. It'd be a good idea to check - real floppies tend to be unreliable (read errors). This won't cause your code to crash on BOCHS though (where the floppy isn't actually a floppy and doesn't have read errors).

In the code just after setting up protected mode, it'd be a good idea to set all of the data segment registers instead of just DS and SS. For example:

Code: Select all

clear_pipe:
   mov ax, 10h
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax
   mov esp, 090000h
This isn't causing problems yet, because you don't use the other segment registers. If you tried "rep movsd" or something (and you will, sooner or later) it will cause problems...

For your 32 bit (kernel?) code you're using "[ORG 0x00]" but it's running at 0x00010000 with CS base set to 0. In this case you should use "[ORG 0x00010000]". This won't cause your code to crash at the moment either, because the "JMP HANG2" should be a relative jump, but it will cause problems later.

After all of this, I guess you're wondering what the problem with it actually is!

In real mode, address are calculated as "segment * 16 + offset", so 1000h:0000h in real mode (which is where your kernel is loaded) becomes actual address 010000h.

In protected mode the actual address is calculated as "segment_descriptor_base + offset". Your segment descriptor base is 00000000h, so you need 010000h for the offset...

The reason why it's triple faulting is because you're doing " jmp 08h:01000h" when you need "jmp 08h:010000h". :)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Kyretzn

Re::( Mysterious Error

Post by Kyretzn »

Thanks Brendon! That fixed it! :)
Post Reply