org vs manual segments

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
mr. xsism

org vs manual segments

Post by mr. xsism »

i have recoded my bootloader for FAT12 and i am adding my pmode code back into a working version that prints off the # sectors read and the 1st sector in the memory buffer to help confirm that everything was read properly. But there is a problem. i can't get the GDT to be addressed properly without a org 0x7c00 but if i use org then my BIOS print function that uses DS doesn't work.

I set the segs except CS manually to 0x7c0 without an org statement and it works fine. Then i add the org statement for the GDT and it doesn't do anything. I have been figetting with it all day but now it is 1AM and i need sleep. Anyone have some information that could help solve my problem?

Maybe there is a special method to use both org and manual at the same time??? ??? :'(

Thanks,
mr. xsism :o
richie

Re:org vs manual segments

Post by richie »

I set the segs except CS manually to 0x7c0 without an org statement and it works fine. Then i add the org statement for the GDT and it doesn't do anything.
This might be your fault. The org-Statement tells the Assembler how far the code/data is placed beyond the segment-start. Since your code is placed at 0x7c00 and ds=0x7c0 you need no org (same as org 0x0).
But there's a problem:
When your Bootloader gets control you don't know if the BIOS jumped there with jmp 0x07c0:0x0000 or jmp 0x0000:0x7c00. You might say that this is the same but it isn't. In the first case cs=0x07c0, in the later cs=0x0000. If you do a (near) jmp in your bootloader you have to specify where to jmp. Let's assume that you want to jump to the 0x100th byte in your bootloader. Normally you would code jmp 0x100. If cs=0x07c0 this would execute the command at 0x07c0:0x0100. But if cs=0x0000 the next command would be at 0x0000:0x0100. BUT: 0x07c0:0x0100 != 0x0000:0x0100. The org-Statement cannot overcome this problem.
My suggestion is to do a far jump right at the beginning of your code:

Code: Select all

org 0x0000 ; not neccessary

Bootloader_Start:
  jmp 0x0000:Start

Start:
  cli ; disable interrupts

  mov ax, 0x0000
  mov ds, ax
  mov es, ax
  mov es, ax
  mov gs, ax
  mov ss, ax

;Don't forget to init sp
  mov sp, 0x7000 ; stack grwos downwards

  sti ; enable interrupts

  ...

mr. xsism

Re:org vs manual segments

Post by mr. xsism »

ok i set all segs to 0 and org 0x7C00 and it seemed to help. But now bochs tells me about some STR_Ew.
=======================================================================
Event type: PANIC
Device: [CPU ]
Message: STR_Ew: encountered in real mode.

A PANIC has occurred. Do you want to:
cont - continue execution
alwayscont - continue execution, and don't ask again.
This affects only PANIC events from device [CPU ]
die - stop execution now
abort - dump core
Choose one of the actions above: [die]
00000824568i[CPU ] BxError: instruction with op1=0xff
00000824568i[CPU ] nnn was 7
00000824568i[CPU ] WARNING: Encountered an unknown instruction (signalling illegal instruction):
00000836952p[CPU ] >>PANIC<< STR_Ew: encountered in real mode.
00000836952i[SYS ] Last time is 1071159891
00000836952i[CPU ] real mode
00000836952i[CPU ] CS.d_b = 16 bit
00000836952i[CPU ] SS.d_b = 16 bit
00000836952i[CPU ] | EAX=0009007b EBX=00000004 ECX=00090200 EDX=00007b00
00000836952i[CPU ] | ESP=00007bae EBP=00007bda ESI=00007c50 EDI=00007e00
00000836952i[CPU ] | IOPL=0 NV UP DI PL NZ NA PE NC
00000836952i[CPU ] | SEG selector base limit G D
00000836952i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00000836952i[CPU ] | DS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000836952i[CPU ] | ES:0007( 0000| 0| 0) 00000070 0000ffff 0 0
00000836952i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000836952i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000836952i[CPU ] | SS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000836952i[CPU ] | CS:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
Ever encountered that? It changes CS and ES? When i don't cal my putstr function it works fine.

Code: Select all

putstr:     ; SI = address of string to display
            lodsb
            or al,al
            jz putstrd
            mov ah,0x0E
            mov bx,0x0007
            int 0x10
            jmp putstr
putstrd:    retn            ; return to caller 
Look there, 0x0e and 0x07, same as ES and CS. What in the world is causing that?? :-X

Thanks,
mr. xsism
Slasher

Re:org vs manual segments

Post by Slasher »

Use
push cs
pop ds
or
push cs
pop ax
mov ds,ax
mov es,ax
.....
mr. xsism

Re:org vs manual segments

Post by mr. xsism »

i already do. I set the regs to 0 since i alredy use an org statement. Perhaps the source will come in handilly. It's attached, btw.


[edit]BAAA osrry, it must have been removed after i previewed it. Dang. Here it is, i hope.[/edit]

[attachment deleted by admin]
Slasher

Re:org vs manual segments

Post by Slasher »

There is no code there!
Curufir

Re:org vs manual segments

Post by Curufir »

Code: Select all

[org 0x7c00]
...
mov ax,cs                  ; setup ds segment
mov ds,ax
There is no standard. CS can be either 0x07c0 or 0x0 and still have the CS:EIP pair represent address 0x7c00. However the [org 0x7c00] sets up your labels on the premise that DS is only ever 0x0, so if CS is 0x07c0 then at some point your code is going to fall over due to a bad assumption.

This was all done to death about 3 weeks ago.
mr. xsism

Re:org vs manual segments

Post by mr. xsism »

ok this is really making me mad. It is definately the putstr function. I changed it:

Code: Select all

putstr:     ; SI = address of string to display
            lodsb
            or al,al
            jz putstrd
            mov ah,0x0E
            mov bx,0x07
            int 0x10
            jmp putstr
putstrd:
clit
hlt
ret            ; return to caller 

and i get:
00000000000i[ ] using log file bochsout.txt
========================================================================
Event type: PANIC
Device: [CPU ]
Message: prefetch: RIP > CS.limit

A PANIC has occurred. Do you want to:
cont - continue execution
alwayscont - continue execution, and don't ask again.
This affects only PANIC events from device [CPU ]
die - stop execution now
abort - dump core
Choose one of the actions above: [die]
from bochs and then it dumps:
00000886465i[CPU ] BxError: instruction with op1=0xff
00000886465i[CPU ] nnn was 7
00000886465i[CPU ] WARNING: Encountered an unknown instruction (signalling illegal instruction):
00001106525p[CPU ] >>PANIC<< prefetch: RIP > CS.limit
00001106525i[SYS ] Last time is 1071297679
00001106525i[CPU ] real mode
00001106525i[CPU ] CS.d_b = 16 bit
00001106525i[CPU ] SS.d_b = 16 bit
00001106525i[CPU ] | EAX=00170000 EBX=00000004 ECX=00170020 EDX=00007d00
00001106525i[CPU ] | ESP=00007bfa EBP=00007bda ESI=00007c51 EDI=00000001
00001106525i[CPU ] | IOPL=0 NV UP DI PL ZR NA PE NC
00001106525i[CPU ] | SEG selector base limit G D
00001106525i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00001106525i[CPU ] | DS:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
00001106525i[CPU ] | ES:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
00001106525i[CPU ] | FS:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
00001106525i[CPU ] | GS:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
00001106525i[CPU ] | SS:00e0( 0000| 0| 0) 00000e00 0000ffff 0 0
00001106525i[CPU ] | CS:4013( 0000| 0| 0) 00040130 0000ffff 0 0
00001106525i[CPU ] | EIP=00010ed0 (00010ed0)
00001106525i[CPU ] | CR0=0x60000010 CR1=0x00000000 CR2=0x00000000
00001106525i[CPU ] | CR3=0x00000000 CR4=0x00000000
00001106525i[ ] restoring default signal behavior
00001106525i[CTRL ] quit_sim called with exit code 1

looks at the segment registers, what sets those?? BTW, i ripped the putstr function for testing. I'm going mad. I guess i'll just remove it all together :( :( :'(



for the love of goodness someone help me!! :o :( :'(
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:org vs manual segments

Post by Candy »

Since you're using bochs, you might want to recompile bochs with debugging enabled, put a debug breakpoint at the start of the code (b 0x7c00) and then continue to that point (c). Then, put trace mode on (trace-on) and continue some more. After a while it'll crash, but at least you have a full dump of all the instructions and branches taken, so you can see how it runs through your code.

If you want, place more breakpoints and use the cpu status (dump_cpu) and memory dumps (xp /nxb addr, n = count of bytes, addr = address) for more info.
Slasher

Re:org vs manual segments

Post by Slasher »

Hi,
First you are not supposed to have Interrupts enabled so turn them off. Remove that sti.
You are supposed to change the GDT BEFORE you enable protected mode. Thats why you are getting that error. Change those lines around to
cli
;load gdt
lgdt[GDTR]


;enter pmode
mov eax,cr0
or al,1
mov cr0,eax
ps don't enable ot change the IDT until you have setup your interrupt routines
mr. xsism

Re:org vs manual segments

Post by mr. xsism »

no, GDT and pmode get setup just fine. I also don't have a sti, i have a cli. You can set GDT after you enable pmode bit but before you set segments. Also, i'm not an idiot...

ok, i know for fact that it has something to dowith that putstr as i can load my kernel now. BUT i get this error that i didn't get vefore when i used a NONFAT12 bootloader:
00000000000i[ ] using log file bochsout.txt
========================================================================
Event type: PANIC
Device: [FDD ]
Message: read/write command with DMA and int disabled

A PANIC has occurred. Do you want to:
cont - continue execution
alwayscont - continue execution, and don't ask again.
This affects only PANIC events from device [FDD ]
die - stop execution now
abort - dump core
Choose one of the actions above: [die]
That statement is incorrect because i definately choose DMA mode, but anyway. I'm almost bald; pulling out my hair over this crap. I think osdev increases the aging process :s :o :| :( :) :D

Thanks guys. I might try tracing but that also traces the BIOS interrupts which is crazy. Alwell, wouldn't hurt. Bye....
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:org vs manual segments

Post by Candy »

if you don't have a lot of code (boot sectors tend to be small) you can single-step (stepi) through the code, putting breakpoints after all the int calls and continuing (without trace) through them. You can also make an object dump from your code files to set all those breakpoints in advance.

Good luck bug hunting :)
mr. xsism

Re:org vs manual segments

Post by mr. xsism »

how exactly would i add breakpoints ahead of time? I currently just watch for a write to 0x5000 which i do at certain points but it only spots it the first time :( Thx Candy
mr. xsism

Re:org vs manual segments

Post by mr. xsism »

i pretty much fixed this problem. Thanks fo all your input peeps :D Now i am having problems with the actual kernel. But at least it loads properly. Question is how would FAT12 Bootloader make certain bugs level??
Post Reply