Page 1 of 2

Pmode + Kernel

Posted: Sun Jun 06, 2004 4:35 pm
by Pulser
Is it wrong to enter Pmode in the kernel rather than the bootsector? As my bootsector is getting rather full. Thanks.

Re:Pmode + Kernel

Posted: Sun Jun 06, 2004 6:09 pm
by Curufir
There is no right or wrong. There is only code that works and code that doesn't. If you want to set up PMode outside the bootsector then go ahead and do it...I'll allow it this one time ;D.

Re:Pmode + Kernel

Posted: Sun Jun 06, 2004 6:17 pm
by Pulser
Ok, I think I can *barely* fit the PMode code into the bootloader. But, Im having a problem with:

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

While trying to move eax back into the control register, it seems to hang, and Ctrl+C doesn't seem to work in the Bochs Debugger.. Any hints? I am new to the bochs debugger :) Thanks.

Re:Pmode + Kernel

Posted: Sun Jun 06, 2004 6:25 pm
by Curufir
Did you turn off interrupts?

Re:Pmode + Kernel

Posted: Sun Jun 06, 2004 6:29 pm
by Pulser
Yep :)
Can interrupts be turned off anywhere tho? Because I have turned them off after all my FAT/disk reading code using int 0x13, so maybe that is the problem?

Re:Pmode + Kernel

Posted: Sun Jun 06, 2004 10:05 pm
by stonedzealot
Yeah, interrupts can be turned off or on anywhere, so that shouldn't be a problem.

Re:Pmode + Kernel

Posted: Mon Jun 07, 2004 1:36 am
by Pype.Clicker
- i don't recommend to switch to pmode within your kernel as it's incredibly difficult to write (and compile) a large program that share 32 and 16 bits parts.
- if your bootsector becomes full, you can alternatively use a second-stage boot loader or have the first 512 bytes of your bootsector loading more bytes of a too large bootloader.

Get a look at the "Guru Meditation in a Nutshell" page on http://www.osdev.org/osfaq2/ to see if you can find some tracing techniques that might help you. Showing any panic message reported by BOCHS may help us aswell ...

btw, make sure you have a debugger-enabled bochs. this doesn't come by default!

Re:Pmode + Kernel

Posted: Mon Jun 07, 2004 3:02 am
by Pulser
I have the bochs debugger enabled :) But I am kinda new to it. But anyway, just before the:

mov cr0, eax

I dumped the cpu, and this is what I get:

Code: Select all

eax:0x60000011
ebx:0x2
ecx:0x90010
edx:0x0
ebp:0x0
esi:0x7e03
edi:0x7e00
esp:0xfffe
eflags:0x2
eip:0x7d3c
cs:s=0x0, dl=0xffff, dh=0x9b00, valid=1
ss:s=0x0, dl=0xffff, dh=0x9300, valid=7
ds:s=0x0, dl=0xffff, dh=0x9300, valid=7
es:s=0x1000, dl=0xffff, dh=0x9301, valid=1
fs:s=0x0, dl=0xffff, dh=0x9300, valid=1
gs:s=0x0, dl=0xffff, dh=0x9300, valid=1
ldtr:s=0x0, dl=0x0, dh=0x0, valid=0
tr:s=0x0, dl=0x0, dh=0x0, valid=0
gdtr:base=0x7d, limit=0x9118
idtr:base=0x0, limit=0x3ff
dr0:0x0
dr1:0x0
dr2:0x0
dr3:0x0
dr6:0xffff0ff0
dr7:0x400
tr3:0x0
tr4:0x0
tr5:0x0
tr6:0x0
tr7:0x0
cr0:0x60000010
cr1:0x0
cr2:0x0
cr3:0x0
cr4:0x0
inhibit_mask:0
Can anyone see anything particulary wrong with the state of the CPU?! I am kinda stumped.

This is my GDT (over commented as you can see :P):

Code: Select all

gdt:                            ; Very start of our GDT
gdt_null:                       ; Null Segment -> 4 Null Words
        dw 0                    ; Null Word
        dw 0                    ; Null Word
        dw 0                    ; Null Word
        dw 0                    ; Null Word
gdtCode:                        ; Code Segment
        dw 0xFFFF               ; Limit -> 4GB
        dw 0x0000               ; Base Address -> 0 (Start of memory)
        db 0x00                 ; Continue base address
        ; Access flag -> 0, Readable Segment -> 1, Conforming -> 0
        ; Code Segment -> 1, Code/Data Segment -> 1, Privelage level -> 00
        ; Present -> 1
        db 10011010b            ; Above flags
        ; Last bits of segment limit -> 1111, Ignored -> 0, Reserved -> 0,
        ; 32-bit code -> 1, Granularity -> 1,
        db 11001111b            ; Above flags
        db 0x00                 ; Remaining base address
gdtData:                        ; Our data segment
        dw 0xFFFF               ; Limit -> 4GB
        dw 0x0000               ; Base Address -> 0 (Start of memory)
        db 0x00                 ; Continue base address
        ; Accessed -> 0,  Writeable Segment -> 1, Expand -> 0 (down),
        ; Code Segment -> 0 (data), Code/Data Segment -> 1, Privelage -> 00
        ; Present -> 1
        db 10010010b            ; Above flags
        ; Last bits of segment limit -> 1111, Ignored -> 0, Reserved -> 0,
        ; 32-bit code -> 1, Granularity -> 1
        db 11001111b            ; Above Flags
        db 0x00                 ; Remaining base address
gdtEnd                          ; End of our GDT
                                                                                     
gdtDesc:                        ; GDT Descriptor
        db gdtEnd - gdt         ; Size of GDT in bytes
        dw gdt                  ; GDT's memory address
And this is the code after all my FAT reading:

Code: Select all

        cli
        lgdt [gdtDesc]
        mov eax, cr0
        or eax, 1
        mov cr0, eax ; hangs here
Would the whole source be of more help? I'm totally stumped... Thanks.

EDIT:

Bochs Log messages:
00000711220e[CPU0 ] jump_protected: gate type 0 unsupported
00000711220e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting

Re:Pmode + Kernel

Posted: Mon Jun 07, 2004 3:47 am
by Candy
Pulser wrote:

Code: Select all

gdtr:base=0x7d, limit=0x9118
This is my GDT (over commented as you can see :P):

Code: Select all

gdt:                            ; Very start of our GDT
<snip>
gdtDesc:                        ; GDT Descriptor
        db gdtEnd - gdt         ; Size of GDT in bytes
        dw gdt                  ; GDT's memory address
Do you see a mismatch? The limit is 16-bit, the base 32-bit, base must be 8-byte aligned, and the dump shows it didn't load correctly. What's the offset of the GDT itself in your memory image?

Re:Pmode + Kernel

Posted: Mon Jun 07, 2004 4:01 pm
by Pulser
How do I find the offset of the GDT in my "memory image"? Thanks.

Re:Pmode + Kernel

Posted: Tue Jun 08, 2004 3:16 am
by Pype.Clicker
just add the offset of your GDT to the value of the datasegment * 16 ... if you chose the "0x07C0:0000" approach, it means GDTR.base should be gdt+7C00. If you chose the "0x0000:7C00" approach, GDTR.base is simply gdt :)

Re:Pmode + Kernel

Posted: Tue Jun 08, 2004 4:04 am
by Pulser
I went for the 0x0000:7c00 approach, and my GDTR.base is set to gdt... any other ideas? Thanks :)

Re:Pmode + Kernel

Posted: Tue Jun 08, 2004 4:08 am
by Candy
Pulser wrote: I went for the 0x0000:7c00 approach, and my GDTR.base is set to gdt... any other ideas? Thanks :)
Your ORG is good I suppose (ORG 0x7C00 would work). Make the base a dd, and the limit a dw, then it should work.

Re:Pmode + Kernel

Posted: Tue Jun 08, 2004 4:16 am
by Pulser
Crap. Still doesn't work candy :( Though the base and limit are different when I dump the cpu...

Re:Pmode + Kernel

Posted: Tue Jun 08, 2004 9:48 am
by Pype.Clicker
the 'type gate 0' would worth deeper investigation. What instructions do you have right after 'mov cr0,eax' ? you know it should be a far jump with segment being your code selector ...