Pmode + Kernel

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

Pmode + Kernel

Post by Pulser »

Is it wrong to enter Pmode in the kernel rather than the bootsector? As my bootsector is getting rather full. Thanks.
Curufir

Re:Pmode + Kernel

Post 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.
Pulser

Re:Pmode + Kernel

Post 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.
Curufir

Re:Pmode + Kernel

Post by Curufir »

Did you turn off interrupts?
Pulser

Re:Pmode + Kernel

Post 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?
stonedzealot

Re:Pmode + Kernel

Post by stonedzealot »

Yeah, interrupts can be turned off or on anywhere, so that shouldn't be a problem.
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:Pmode + Kernel

Post 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!
Pulser

Re:Pmode + Kernel

Post 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
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Pmode + Kernel

Post 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?
Pulser

Re:Pmode + Kernel

Post by Pulser »

How do I find the offset of the GDT in my "memory image"? Thanks.
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:Pmode + Kernel

Post 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 :)
Pulser

Re:Pmode + Kernel

Post by Pulser »

I went for the 0x0000:7c00 approach, and my GDTR.base is set to gdt... any other ideas? Thanks :)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Pmode + Kernel

Post 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.
Pulser

Re:Pmode + Kernel

Post by Pulser »

Crap. Still doesn't work candy :( Though the base and limit are different when I dump the cpu...
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:Pmode + Kernel

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