C call makes exception #13 wake...

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

C call makes exception #13 wake...

Post by Googles »

I'm trying to call "BYTE ReadSector(ULONG LBA, BYTE NumberOfSectors, ULONG off)" with this C code:

Code: Select all

                         if(ReadSector((ULONG)FAT_Root_Dir_Start,(BYTE)FAT_Root_Dir_Size,0x50000))
                            for(;;);
                   PrintString("done",2);
                   for(;;);
But for some reason bochs alarms exception #13 (GP):
00068791839e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
I havn't enabled paging yet so it can't be any memory problem (hopefully)... ReadSector is located in the same file as the function (main) where the call i made from.

Does anyone see a problem?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

Is that address 0x50000 what so ever accessible for your kernel (look at your segment descriptors)?

What happens inside readsector? (not as If I couldna imagine but it's better to see the crucial place where the error shows up.)

Can you track down the error a bit narrower? Maybe the gpf is triggered inside readsector, hm?

stay safe :-)
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Googles

Re:C call makes exception #13 wake...

Post by Googles »

0x50000 is a temp storage place for my SecondBootLoader, InitDrive(BYTE drive) used it to download the IDENTIFY_DEVICE packet without problem also all segment (except CS) is loaded with a flat datasegment (base=0x0,limit=0xfffff,G=1).

The problem is readsector is nevere called! the problem seems to arise before the call but when I put an for(;;); before the readsector call everything works fine...

Also, changing:

Code: Select all

if(ReadSector((ULONG)FAT_Root_Dir_Start,(BYTE)FAT_Root_Dir_Size,0x50000))
into (I have now declared FAT_Root_Dir_Start as unsigned long int insted of unsigned short int):

Code: Select all

if(ReadSector(0,1,0x50000))
or

Code: Select all

if(ReadSector(FAT_Root_Dir_Start,0,0x50000))
works!

So I suspect that something is wrong with FAT_Root_Dir_Size... any suggestions?
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:C call makes exception #13 wake...

Post by Pype.Clicker »

usually, if a GPF is raised due to some segment receiving some weird value. I'd then suspect that some IRQ handler is doing something wrong when popping back segment registers ... The crash status and the dump_cpu output of Bochs may help you tracing back the why of the thing.
Googles

Re:C call makes exception #13 wake...

Post by Googles »

DS,ES,FS,GS = flat datasel, in the whole secondbootloader.

The kernel configures the interrupts, the secondbootloader has no interupts: they are disabled...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

Hmmm ... and what if the code isn't loaded into memory because your bootloade fetches not enough sectors?

Check the size of your images and the amount of sectors you are fetching from disk. That's a culprit to find. Has happened to me too.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Googles

Re:C call makes exception #13 wake...

Post by Googles »

InitDrive() is located under ReadSector() and it can be called without problems...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

and some function calls readsector() needs may be located beneath initdrive()?

I suppose you center your bug hunting *inside* readsector(). Place printf's and for-loops and track it.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
googles

Re:C call makes exception #13 wake...

Post by googles »

I think I have found it:
Just before readsector is called I calculate the FAT details and it seems the "root directory size" (in sectors) results in a divide by zero because "SectorsPerCluster" and "MaxRootEntries" isn't loaded correctly from the memory.

Wouldn't:

Code: Select all

typedef unsigned short int USHORT;
typedef unsigned long int ULONG;
typedef char BYTE;

      typedef struct FAT_Header
      {
         BYTE BOOTSECTOR_JUMP_INSTRUCTION[3];
        BYTE OEM_ID[8];
         USHORT BytesPerSector;
         BYTE SectorsPerCluster;
        USHORT ReservedSectors;
        BYTE TotalFATs;
        USHORT MaxRootEntries;
        USHORT TotalSectorsSmall;
        BYTE MediaDescriptor;
        USHORT SectorsPerFAT;
        USHORT SectorsPerTrack;
        USHORT NumHeads;
        ULONG HiddenSectors;
        ULONG TotalSectorsLarge;
        BYTE DriveNumber;
        BYTE Flags;
        BYTE Signature;
        ULONG VolumeID;
        BYTE VolumeLabel;
        BYTE SystemID;
      }FAT_Header __attribute__((__packed__));

FAT_Header *FATHeader = (FAT_Header *) 0x7c00;
FAT_Root_Dir_Size=FATHeader->MaxRootEntries;
make sure that FAT_Root_Dir_Size is equal to the word a 0x7c11?!!!

What am I missing!!
Googles

Re:C call makes exception #13 wake...

Post by Googles »

according the the assembly output nothing is located under Initdrive()
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

Now, easy: if you tell, the cpu traps into a divide by zero exception - it looks into the idt: if it can't find something valid there, it triggers a gpf, and at this pont, bochs decides to stop. Real cpu would triple fault.

Do you have a valid interrupt descriptor table and valid interrupt descriptors set up? When in Pmode, you need at least 32 descriptors pointing to a dummy handler - for the exceptions, because those fire off even with interrupts locked away.

I know nothing about FAT implementation. There's some text on our osfaq WIKI aboput fat12.

*wink* I ask those questions because these are things one oversees with ease.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Googles

Re:C call makes exception #13 wake...

Post by Googles »

No I don't have a IDT setup. Interrupts and Exception and enabled (and an IDT) is initialized in the kernel INIT process. In the secondbootloader I'm not using anything like that. All it does is load the kernel into memory...

Could you please try to help me with the other problem (it's a general C problem).

Wouldn't:

Code: Select all

typedef unsigned short int USHORT;
typedef unsigned long int ULONG;
typedef char BYTE;

      typedef struct FAT_Header
      {
         BYTE BOOTSECTOR_JUMP_INSTRUCTION[3];
        BYTE OEM_ID[8];
         USHORT BytesPerSector;
         BYTE SectorsPerCluster;
        USHORT ReservedSectors;
        BYTE TotalFATs;
        USHORT MaxRootEntries;
        USHORT TotalSectorsSmall;
        BYTE MediaDescriptor;
        USHORT SectorsPerFAT;
        USHORT SectorsPerTrack;
        USHORT NumHeads;
        ULONG HiddenSectors;
        ULONG TotalSectorsLarge;
        BYTE DriveNumber;
        BYTE Flags;
        BYTE Signature;
        ULONG VolumeID;
        BYTE VolumeLabel;
        BYTE SystemID;
      }FAT_Header __attribute__((__packed__));

FAT_Header *FATHeader = (FAT_Header *) 0x7c00;
FAT_Root_Dir_Size=FATHeader->MaxRootEntries; 


make sure that FAT_Root_Dir_Size is equal to the word a 0x7c11?!!!

How can I make GCC stop adding padding to it's structures? __attribute__((__packed__)) doesn't work at all I think?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

It *is* an idt problem. Because if it weren't, bochs would gladly carry lout your gpf exception handler. It would gladly carry out your divide_by_zero-exception handler. Hm?

The __attribute__((PACKED)) ... I think there has been a discussion about this on this board. Vaguely I remember that they have added __attribute__((PACKED)) to each member of the structure.

try this out, then output sizeof(oldstruct) and sizeof(newstruct) and compare the sizes, where oldstruct==the fat_header structure presented here and newstruct==fat_header struct with __attribute__((PACKED)) after each member.

Please please set up at least a preliminary IDT as soon as possible, especially if operating in protected mode.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Googles

Re:C call makes exception #13 wake...

Post by Googles »

hehe, I promise to set up a IDT as soon as my kernel loads.
When I was building my OS in asm (I'm planning to skip C and move back to asm since C seems so "weird") my kernel used to loadup the IDT the first thing it did.

I know it's a interrupt problem, but adding a IDT won't solve the problem. The Secondbootloader should load the kernel without a exception occuring. What would the divide by zero exception do even I enabled/initialized interrupts? kill the task and move to the next one? that's gonna be problem since multitasking isn't enabled...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:C call makes exception #13 wake...

Post by distantvoices »

It doesn't necessarily kill any task. It can also notify you, if something fishy happens - like div/0 exceptions. easier to debug than bochs error code.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Post Reply