Reset in protected mode

Programming, for all ages and all languages.
Post Reply
phoenix07p
Posts: 11
Joined: Tue Sep 15, 2009 1:11 am

Reset in protected mode

Post by phoenix07p »

I enter the protected mode successfully and make a jmp but at an instruction occurs pop es after which triple fault occurs the errors are

Code: Select all

00015087615e[CPU0 ] fetch_raw_descriptor: GDT: index (5ef)bd > limit (17)
00015087615e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
0d)
00015087615e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
08)
00015087615i[CPU0 ] CPU is in protected mode (active)
00015087615i[CPU0 ] CS.d_b = 32 bit
00015087615i[CPU0 ] SS.d_b = 32 bit
00015087615i[CPU0 ] EFER   = 0x00000000
00015087615i[CPU0 ] | RAX=0000000060000008  RBX=0000000000007e00
00015087615i[CPU0 ] | RCX=0000000000000002  RDX=0000000000000000
00015087615i[CPU0 ] | RSP=0000000000007c00  RBP=0000000000000000
00015087615i[CPU0 ] | RSI=00000000000e7e00  RDI=000000000000ffac
00015087615i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00015087615i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00015087615i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00015087615i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00015087615i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf AF pf CF
00015087615i[CPU0 ] | SEG selector     base    limit G D
00015087615i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00015087615i[CPU0 ] |  CS:0010( 0002| 0|  0) 00000000 f0000fff 1 1
00015087615i[CPU0 ] |  DS:0008( 0001| 0|  0) 00000000 f0000fff 1 1
00015087615i[CPU0 ] |  SS:0008( 0001| 0|  0) 00000000 f0000fff 1 1
00015087615i[CPU0 ] |  ES:0008( 0001| 0|  0) 00000000 f0000fff 1 1
00015087615i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00015087615i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00015087615i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00015087615i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00015087615i[CPU0 ] | RIP=0000000000007e4c (0000000000007e4c)
00015087615i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00015087615i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[15087615] [0x00007e4c] 0010:0000000000007e4c (unk. ctxt): pop es
         ; 07
00015087615e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
 status is 00h, resetting
The code I use is

Code: Select all

cli 
lgdt  [gdtr]

mov   eax, cr0
or    al,0x1 
mov   cr0,eax
jmp   0x10: protected

[BITS 32]

protected:

mov   ax,0x08 
mov   ds,ax
mov   es,ax
mov   ss,ax
mov   esp,0x7C00
jmp   buffer

[BITS 16]
gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF
gdt_end:

gdtr:       dw gdt_end - gdt - 1   
            dd gdt 

TIMES 510 - ($ - $$) db 0
DW 0xAA55

buffer:

buffer is where i have read sector from disk. After the jump to buffer it resets at instruction pop es. What should I do?
User avatar
Creature
Member
Member
Posts: 548
Joined: Sat Dec 27, 2008 2:34 pm
Location: Belgium

Re: Reset in protected mode

Post by Creature »

My assembly skills aren't too great but it might be a problem that you're not setting up all registers here:

Code: Select all

mov   ax,0x08 
mov   ds,ax
mov   es,ax
mov   ss,ax
Your GDT offset seems to be correct but I think you're supposed to set up all 5 registers: DS, ES, FS, GS and SS, so that would make:

Code: Select all

mov ax, 0x08
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
Not sure if this is the problem, though.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Reset in protected mode

Post by neon »

If I was to guess, buffer probably contains invalid code. Single step it with bochs after the jmp instruction to verify it.

Also, assuming buffer is an offset in a code or data segment and used in real mode, be sure it is also the correct linear address. i.e., in real mode segment:offset addressing, the offset is not necessarily a protected mode linear address thus a jmp buffer might not actually jump to the address that you expect.

*edit: Woops, I messed that buffer is a label on the 513th byte. Thatll cause issues if you dont load the second sector right after the boot sector into memory.
Last edited by neon on Fri Sep 25, 2009 7:14 pm, edited 2 times in total.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Reset in protected mode

Post by AJ »

Hi,

Is the code you posted just a snippet, or is there more code? For example, what is beyond buffer? Have you loaded the second sector in to memory correctly, or are you just jmp'ing to uninitialised RAM? If this is currently just a test boot sector, place the "buffer:" label before your zero padding and add a hlt / jmp $ instruction after the label.

Cheers,
Adam
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Reset in protected mode

Post by gravaera »

Hi: AJ has already touched on what I was about to say, but:

Since this bit of code is exactly 512 bytes, I assume it's bootsector code. The 'times' directive to the assembler fills all the rest of the bytes beyond the end of your code up to 510 bytes with 0s. The BIOS only loads the bootsector.

In other words, even though you assembled and linked the 513th bytes into the bootsector code, (the 'buffer' symbol, if my ASM serves me right, is at byte 513) IN MEMORY, only the first 512 bytes of your code are loaded. Since we can assume that either NULL or garbage is located in an uninitialized memory location, jumping to an address with no code inside of it will produce undefined results.

I don't think that's your problem, since bochs complains about a GDT index error, I'd like to suggest you remove the '[BITS 16]' above your GDT. There's no reason for it.

Not only that, but just below that, in your GDt Pointer, you go ahead and do a 'dd'. IIRC, LGDT is assumed to be a 32 bit instruction, so it's okay to use it without specifying [BITS 16] over the data it's going to take.

The instruction set provides an opcode modifier that allows 32 bits instructions to be intermixed with 16 bit ones.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
phoenix07p
Posts: 11
Joined: Tue Sep 15, 2009 1:11 am

Re: Reset in protected mode

Post by phoenix07p »

I think the code is getting loaded properly because I tried by loading the first sector of the disk itself beyond buffer and it was looping correctly. so i don't think a prob there. this is not the entire code only the one i thought relevant. i will post the entire code here. I would really appreciate it if some one could help me debug it. I am sorry but i am just going really crazy over this code so i am posting the entire thing.

I am able to call kernel_start.asm and kernel.c directly from grub by chain loading. I am just trying to invoke them from my bootloader. Without protected mode it just ends up at hlt but doesn't print anything. Then I read that GRUB by default enters protected mode while passing control to kernel so i thought that might be missing and also registers eax and ebx were used in begining of kernel_start.asm.

This is the linker file

Code: Select all

ENTRY (loader)

SECTIONS{
    . = 0x00100000;

    .text :{
        *(.text)
    }

    .rodata ALIGN (0x1000) : {
        *(.rodata)
    }

    .data ALIGN (0x1000) : {
        *(.data)
    }

    .bss : {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    }
}
Attachments
kernel.c
(1.24 KiB) Downloaded 144 times
bootl.asm
(1.35 KiB) Downloaded 114 times
kernel_start.asm
(1.19 KiB) Downloaded 98 times
geppyfx
Member
Member
Posts: 87
Joined: Tue Apr 28, 2009 4:58 pm

Re: Reset in protected mode

Post by geppyfx »

I'm not an expert in gcc, scripts or grub but have you compiled your kernel that you load with respect to 0x7e00 ( [ORG 0x7e00] ).

Actually its perfectly fine to start executing code at 0x7e00 while the code at 0x7e00 location was compiled for 0x100000. Until you hit a jump or memory reference instruction that uses some label. You will put in a register unknown value or jump to different location then.
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: Reset in protected mode

Post by Masterkiller »

Inproper:
phoenix07p wrote:

Code: Select all

jmp   0x10: protected
Proper:
phoenix07p wrote:

Code: Select all

jmp   0x10: dword protected
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
phoenix07p
Posts: 11
Joined: Tue Sep 15, 2009 1:11 am

Re: Reset in protected mode

Post by phoenix07p »

After tinkering around a bit I got a new error.. :lol: What does this mean???

Code: Select all

00015087609e[CPU0 ] jump_protected: gate type 0 unsupported
00015087609e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
0d)
00015087609e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
08)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Reset in protected mode

Post by Combuster »

It means your GDT is borked, and that you have no IDT
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
phoenix07p
Posts: 11
Joined: Tue Sep 15, 2009 1:11 am

Re: Reset in protected mode

Post by phoenix07p »

OK I got rid of the errors but now the message that it is supposed to display like when booted from grub is not getting displayed on screen. I entered the protected mode and I inserted a magic breakpoint just before hlt and where it does reach so i think it is executing the code but it is not displaying the message. And i wouldn't IDT right now if I temporarily disabled the interrupts would I? Also when I print on the screen from C(basically outputting characters check kernel.c file here it hasn't changed) will it require me to again turn on the interrupts?? If so, is setting up IDT necessary even for interrupts like 10h??I can post the new code again if some one can help me.

My deadline is fast approaching I really need help.

Thanks
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Reset in protected mode

Post by Combuster »

My deadline is fast approaching I really need help.
Beginner mistakes galore!

Seriously, your comments show that you understood about nothing about how the processor really works, and I wouldn't know where to start correcting.
Hence, read the intel manual volume 3 cover-to-cover and then again in reverse, and once you did that, explain what questions could not be answered.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Reset in protected mode

Post by neon »

Hello,
My deadline is fast approaching I really need help.
Extend the deadline then. I personally do use deadlines myself - just not on software projects I work on alone.
And i wouldn't IDT right now if I temporarily disabled the interrupts would I?
"Disabling interrupts" only applies to hardware generated IRQs. Other interrupts - software generated and processor generated - still require an IDT.
Also when I print on the screen from C(basically outputting characters check kernel.c file here it hasn't changed) will it require me to again turn on the interrupts??
Of course not. Why would it? Besides, doing that will triple fault the system again do to the PIT not being reprogrammed and not having an IDT. Hm, also you cannot use bios int 10h in protected mode.
...so i think it is executing the code
Dont "think" it is doing something, "know it". Single step the code and check it with a disassembly of your software - this is a great way to know it is executing as expected.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply