Page 1 of 1

Protected mode + error (general protection error?) nr 13

Posted: Sat Feb 07, 2004 12:00 am
by bubach
Hello!
I have tried to set Pmode in my kernel loader, 'loader.sys'.
Bochs says something about CPU panic nr 13 (general protection error?).

The code i based it on works just fine (but it´s from a bootsector), it looks like this:
-----------------------------------

[BITS 16]       ; We need 16-bit intructions for Real mode

[ORG 0x7C00]    ; The BIOS loads the boot sector into memory location 0x7C00

        cli                     ; Disable interrupts, we want to be alone

        xor ax, ax
        mov ds, ax              ; Set DS-register to 0 - used by lgdt

        lgdt [gdt_desc]         ; Load the GDT descriptor

        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0

        jmp 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions
clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov byte [ds:0B8000h], 'P'      ; Move the ASCII-code of 'P' into first video memory
        mov byte [ds:0B8001h], 1Bh      ; Assign a color code

hang:
        jmp hang                ; Loop, self-jump


gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT



gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT




times 510-($-$$) db 0           ; Fill up the file with zeros

        dw 0AA55h                ; Boot sector identifyer

-----------------------------------

I have almost the exact same code, but mine dosn´t work! My code looks like this:

-----------------------------------

;..........here i set the A20-gate and lots of other stuff....

     ; Code to enter Protected Mode.
     ;-------------------------------
          mov     si, msgSetPmode                     ; Print
          call    DisplayMessage                      ; message.

          cli                                         ; Disable interrupts, we want to be alone

          xor     ax, ax
          mov     ds, ax                              ; Set DS-register to 0 - used by lgdt

          lgdt    [gdt_desc]                          ; Load the GDT descriptor

          mov     eax, cr0                            ; Copy the contents of CR0 into EAX
          or      eax, 1                              ; Set bit 0
          mov     cr0, eax                            ; Copy the contents of EAX into CR0

          jmp     CODE_SEL:start32                    ; Jump to code segment, offset 32start

     ;*************************************************************************


     [BITS 32]
     start32:

     ; Fix segments.
     ;---------------

          mov     ax, DATA_SEL                        ; Save data segment identifyer
          mov     ds, ax                              ; Move a valid data segment into the data segment register
          mov     ss, ax                              ; Move a valid data segment into the stack segment register
          mov     esp, 090000h                        ; Move the stack pointer to 090000h



     ; Load 'kernel.sys' from the FAT12 floppy and go to it.
     ; (Right now i will just print 'Pmode' and hang.)
     ;-------------------------------------------------------


     ; Write a 'Pmode' at upper left corner.
     ;---------------------------------------
          mov     byte [gs:0xB8000], 'P'
          mov     byte [ds:0xB8001], 1Bh              ; Assign a color code
          mov     byte [gs:0xB8002], 'm'
          mov     byte [ds:0xB8003], 1Bh              ; Assign a color code
          mov     byte [gs:0xB8004], 'o'
          mov     byte [ds:0xB8005], 1Bh              ; Assign a color code
          mov     byte [gs:0xB8006], 'd'
          mov     byte [ds:0xB8007], 1Bh              ; Assign a color code
          mov     byte [gs:0xB8008], 'e'
          mov     byte [ds:0xB8009], 1Bh              ; Assign a color code

     ; Hang.
     ;-------
     hang:
          jmp hang                                    ; Loop, self-jump



     ;  Global Descriptor Table (GDT).
     ;---------------------------------
     gdt:                                             ; Address for the GDT

     gdt_null:                                        ; Null Segment
          dd     0
          dd     0

     CODE_SEL     equ $-gdt
     gdt_code:                                        ; Code segment, read/execute, nonconforming
          dw     0FFFFh
          dw     0
          db     0
          db     10011010b
          db     11001111b
          db     0

     DATA_SEL     equ $-gdt
     gdt_data:                                        ; Data segment, read/write, expand down
          dw     0FFFFh
          dw     0
          db     0
          db     10010010b
          db     11001111b
          db     0

     gdt_end:                                         ; Used to calculate the size of the GDT

     gdt_desc:                                        ; The GDT descriptor
          dw     gdt_end - gdt - 1                    ; Limit (size)
          dd     gdt                                  ; Address of the GDT

     ;*************************************************************************

-------------------------------

So as you can see, it is almost the same.. I have tested al sorts of things, but i just can´t get it to work.
Sorry for this big posting...

Thanks in advance

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Sat Feb 07, 2004 12:00 am
by beyondsociety
[code]mov     byte [gs:0xB8000], 'P'
      mov     byte [ds:0xB8001], 1Bh[/code]

This wont work because your loading the values into two seperate segment registers. Use one for both, ds or gs. If its gs, you need to add it to your setup of segment registers, like this:

[code]mov ax, DATA_SEL
      mov ds, ax
      mov gs, ax ; Added for print frunction
      mov ss, ax[/code]
    

RE:Protected mode + error (general protection error?) nr 13

Posted: Sat Feb 07, 2004 12:00 am
by bubach
ok, but that part is "commented away" with ;
so it don´t matter..

RE:Protected mode + error (general protection error?) nr 13

Posted: Sat Feb 07, 2004 12:00 am
by beyondsociety
Is it working yet? Have you tried running your code in bochs?

RE:Protected mode + error (general protection error?) nr 13

Posted: Sun Feb 08, 2004 12:00 am
by bubach
No it isn´t working.. :-(
I have rewritten some of the "set pmode" code (i changed some things that i can´t remember) but it still dosn´t work...
I get this new error:
========================================================================
Event type: PANIC
Device: [CPU  ]
Message: fetch_raw_descriptor: LDTR.valid=0

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]

Can someone help?

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Sun Feb 08, 2004 12:00 am
by beyondsociety
It means that there is something wrong with your gdt code addresses.

it seems to complain about LDTR not to be set up ... did you by any chance place a wrong bit in the gdt selectors that would accidentally ask for a LDT table?

RE:Protected mode + error (general protection error?) nr 13

Posted: Mon Feb 09, 2004 12:00 am
by bubach
I have fixed that now (the gdt was ****** **). :-)
But now i got back that nice "CPU panic nr 13" error instead..
So i am back where i began.
Can someone show me how they set pmode?

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Tue Feb 10, 2004 12:00 am
by BillFarber
Do you have the ORG line in your code?
=>
[ORG 0x7C00]    ; The BIOS loads the boot sector into memory location 0x7C00

If you don't, then the "jmp CODE_SEL:start32" sends the eip to the offset start32 rather than x7c00+start32, which is what you really want.

-Phil

RE:Protected mode + error (general protection error?) nr 13

Posted: Wed Feb 11, 2004 12:00 am
by bubach
No i don´t have this: [ORG x7C00], becasue it´s in my kernel that is loaded to
0x0500...
So i got [ORG 0] and then i set up my registers right to 0x0500...

Is this the problem?

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Wed Feb 11, 2004 12:00 am
by BillFarber
The bootsector loads the kernel someplace in memory. Wherever your kernel is loaded, ie 0x0500, you need to have that address in an ORG statement at the top of the asm code for the kernel. Otherwise far jmp commands will be wrong.

RE:Protected mode + error (general protection error?) nr 13

Posted: Thu Feb 12, 2004 12:00 am
by bubach
not if i set up my segments to 0x0500, right?
All other code works..

RE:Protected mode + error (general protection error?) nr 13

Posted: Fri Feb 13, 2004 12:00 am
by bubach
now i fixed half of the problem..
now bochs says this

[code]
00260435000i[CPU  ] protected mode
00260435000i[CPU  ] CS.d_b = 32 bit
00260435000i[CPU  ] SS.d_b = 32 bit
[/code]

becasue i fixed (i think) the ORG stuff...

but my pmode message still don´t show up.. and on a "real" computer it dosen´t print anything at all..

now it looks like this in loader.asm
[code]
    [BITS 16]
          [ORG 0x0500]

          jmp     START

; some data and functions..........

     START:                                           ; Jump here.


     ; Code located at 0000:0500, adjust segment registers.
     ;------------------------------------------------------
          cli
          mov     ax, 0x0000
          mov     cs, ax
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax
[/code]

and later...

[code]
     ; Code to enter Protected Mode.
     ;-------------------------------
          mov     si, msgSetPmode                     ; Print
          mov     bl, 07h                             ; lightgrey
          call    DisplayMessage                      ; message.

          cli                                         ; Disable interrupts, we want to be alone

          lgdt    [gdtr]                              ; Load the GDT descriptor

          mov     eax, cr0                            ; Copy the contents of CR0 into EAX
          or      eax, 1                              ; Set bit 0
          mov     cr0, eax                            ; Copy the contents of EAX into CR0

          jmp     CODE_SEL:pmode_start                ; Jump to code segment, offset pmode_start

     ;*************************************************************************


     [BITS 32]
     pmode_start:

     ; Refresh all segment registers.
     ;--------------------------------
          mov     ax, DATA_SEL                        ; Save data segment identifyer
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax
          mov     ss, ax
          mov     esp, 0x9FFFF

     ; Turn off floppy motor.
     ;-----------------------
          mov     dx, 3F2h                            ; On my "real" testing PC
          mov     al, 0                               ; the floppy light just won´t
          out     dx, al                              ; go off, so.. (this didn´t work..)


     ; Load 'kernel.sys' from the FAT12 floppy and go to it.
     ; (Right now i will just print 'Pmode' and hang.)
     ;-------------------------------------------------------


     ; Write a 'Pmode' at upper left corner.
     ;---------------------------------------
          mov     byte [ds:0xB8000], 'P'
          mov     byte [ds:0xB8001], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8002], 'm'
          mov     byte [ds:0xB8003], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8004], 'o'
          mov     byte [ds:0xB8005], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8006], 'd'
          mov     byte [ds:0xB8007], 1Bh              ; Assign a color code
          mov     byte [ds:0xB8008], 'e'
          mov     byte [ds:0xB8009], 1Bh              ; Assign a color code


     ; Hang.
     ;-------
          jmp $                                       ; Hang... :-)



     ;  Global Descriptor Table (GDT).
     ;---------------------------------
     gdtr:
      lim dw gdt_end - gdt - 1                        ; GDT limit
          dd gdt                                      ; (GDT base gets set above)

     gdt:

     NULL        equ $-gdt                            ; Null Segment
          dw 0                                        ; Limit 15:0
          dw 0                                        ; Base 15:0
          db 0                                        ; Base 23:16
          db 0                                        ; Type
          db 0                                        ; Limit 19:16, flags
          db 0                                        ; Base 31:24

     CODE_SEL    equ $-gdt                            ; Code segment, read/execute, nonconforming
     gdt1:
          dw 0xFFFF                                   ; Limit 0xFFFFF
          dw 0                                        ; (base gets set above)
          db 0
          db 0x9A                                     ; Present, ring 0, code, non-conforming, readable
          db 0xCF                                     ; Page-granular, 32-bit
          db 0

     DATA_SEL    equ $-gdt                            ; Data segment, read/write, expand down
     gdt2:
          dw 0xFFFF                                   ; Limit 0xFFFFF
          dw 0                                        ; (base gets set above)
          db 0
          db 0x92                                     ; Present, ring 0, data, expand-up, writable
          db 0xCF                                     ; Page-granular, 32-bit
          db 0

     gdt_end:

     ;*************************************************************************
[/code]

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Sat Feb 14, 2004 12:00 am
by beyondsociety
Is this loader.asm considered your bootsector or another file being loaded? If its a bootsector, the first part of your code must be a [ORG 0x7C00] and not [ORG 0x0500]. If its another file being loaded, then its fine.

Also try this piece of code in pmode. If it displays, then you are in protected mode.

mov byte [es:dword 0xB8000],'0'

For your pmode printing code, try one piece of it at a time. Also it wont work unless ds is initialized.

RE:Protected mode + error (general protection error?) nr 13

Posted: Wed Feb 18, 2004 12:00 am
by bubach
It´s not the bootsector.. (i am not _that_ stupid!)
I solved the problem a while ago, i was in the graphic mode 10h (that i used in my bootsector to get color, see stupid notes..), witch make it possible to send color attributes with the BIOS teletype INT call.
But i changed video mode to the classical 03h and made my own "teletype" function instead..
This kind of printing does _not_ work in mode 10h: mov byte [es:dword 0xB8000],'0' (don´t know witch address the mode 10h uses, but it´s not B8000..)

Some (stupid) notes:
The BIOS teletype int takes only the color attribute when we are in a graphic mode, thats why i used mode 10h, it´s both graphics (640x350) and normal text.
There are another BIOS INT to print a char at current cursor position (that takes the color attrb. in mode 03h aswell), but it does not change the cursor position or handle special chars like the CR/LF for a new line.
So i made a special function to read the cursor pos. print the color-char and add 1 to cursor char before changing the cursor (it can handle CR/LF).

/ Christoffer

RE:Protected mode + error (general protection error?) nr 13

Posted: Mon Mar 08, 2004 12:00 am
by ben
ok i'm also workin' on a os !

i did the pmode stuff in the boot sector :

[ORG 07C00h]

jmp start

;for strings : 0x01 (newline) , 0x02 (end of string) , 0x03 (right screen independ to the row)
;partition table
db 0x80  ; yes it is bootable
db 0x00
db 0x00
db 0x00
db 0xAF
db 0x01
db 17
db 79
dd 0
dd 2880
;partition table
bootdrv db 0
start:
        mov ax,cs
        mov ds,ax
        mov byte [bootdrv],dl  ;save the bootdrive



        cli
        mov ax,0x9000 ;set stack for know
        mov ss,ax
        mov sp,0xffff
sti
; load the kernel on his position in memory (0x1000)
load_disk:

    xor eax,eax
    mov es,eax
    mov bx,0x1000
    mov ah,2
    mov dl,0
    mov dh,0
    mov ch,0
    mov cl,2
    mov al,60


    int 13h
;before we set up anything we turn of the floppy motor
;mov dx,0x3F2
;mov al,0x0C
;out dx,al
; now set up the global descritor table
set_up_gdt:
cli
mov bx,cs
shl bx,4
mov eax,ebx
mov [kernel_code + 2], ax
mov [kernel_data + 2], ax
mov [kernel_stack + 2],ax
shr eax,16
mov [kernel_code + 4],al
mov [kernel_data + 4],al
mov [kernel_stack + 4],al
mov [kernel_code + 7],ah
mov [kernel_data + 7],ah
mov [kernel_stack + 7],ah
; disable the NMI interrupts
in al,70h
or al,80h
out 70h,al
; do the a20 line
call empty_a20
mov al,0x1D
out 0x64,al
call empty_a20
mov al,0xDF
out 0x60, al
call empty_a20

;init the pic controller for our irqs
mov al,00010001b
out PIC_MASTER_PORT0,al
out PIC_SLAVE_PORT0,al
mov al,20h                 ;base vector number of master PIC
out PIC_MASTER_PORT1,al
mov al,28h                 ;base vector number of slave PIC
out PIC_SLAVE_PORT1,al
mov al,00000100b           ;IR2 is connected to slave PIC
out PIC_MASTER_PORT1,al
mov al,2h                  ;IRQ2 of master PIC is used for the slave PIC
out PIC_SLAVE_PORT1,al
mov al,00000001b           ;Intel environment, manual EOI
out PIC_MASTER_PORT1,al
out PIC_SLAVE_PORT1,al

; disable all irqs ;-)
mov al,0xFF
out 0x21,al
; get the memory size
mov dword [conv_mem],640*1024

xor eax,eax
mov ah, 0x88
int 0x15
add eax,1024
mov [ext_mem],eax


;set up the gdtr
lea eax,[ebx + gdt]
mov [gdtr + 2],eax


;yeeha now comes our protected mode init
lgdt [gdtr]
xor edx,edx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
;intialize the first page table
mov bx,0x0FFF
mov dx, 0x9C00
mov es, dx
xor di, di
mov dh, 4096/256
.10: mov cx, 1024
mov al, 7
.20: stosd
add eax, edx

loop .20
shr eax, 2
neg bl
jns .10

cli

mov eax, 0x9C007
stosd
mov ax, (1024-3)*2
xchg ax, cx
rep stosw
mov ax, 0xD007
stosd
mov ah, 0xE0
stosd
mov al, 0
mov CR3, eax
mov ax,0x0001
xor ebx,ebx
mov ebx,[ext_mem]
lmsw ax
mov eax, CR0 ;Turn on paging and protected mode
or eax, 0x80000000
mov CR0, eax
xor eax,eax

;that was the hole thing, nice,not?

jmp codesel:pm ; so do the jump to our pm label do_pm

[BITS 32]
pm:

mov ax,datasel
mov ss,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov esp,stack
xor ax,ax
lldt ax
mov al,[bootdrv]
; here we jump to our kernel where the idt is set and the C code will start
jmp 0x1012   ;we jump over 12bytes this is the file information of my os
gdtr:
dw gdt_end - gdt - 1
dd gdt

gdt:
nullsel equ $-gdt
gdt0:
dd 0
dd 0
codesel equ $-gdt  ;0x8
kernel_code:
dw 0xFFFF
dw 0x0
db 0x0
db 0x9A
db 0xCF
db 0x0
datasel equ $-gdt ;0x10
kernel_data:
dw 0xFFFF
dw 0x0
db 0x0
db 0x92
db 0xCF
db 0x0
stack equ $-gdt ;0x18

kernel_stack:
dw 0xFFFF
dw 0x0
db 0x0
db 0x92
db 0xCF
db 0x0
gdt_end:

empty_a20:
in al,0x64
test al,2
jnz empty_a20
ret
ret
PIC_MASTER_PORT0 equ 20h

PIC_MASTER_PORT1 equ 21h

PIC_SLAVE_PORT0 equ 0A0h

PIC_SLAVE_PORT1 equ 0A1h
ext_mem dd 0
conv_mem dd 0
times 510-($-$$) db 0
dw 0xAA55



i hope this could help !!!
if there are any other questions please mail to [email protected] !!!