Ok, I write because Im stuck, have passed much time from this subject attract me, but in fact havent done nothing about practice.

By the way, the "enviroment" is still in real mode, I have "copied" some code for load sectors in the floppy. and jump where is it loaded...

Im now "traslating" the tutorial 2 of this guy, the problem come when is called the function update_cs, tought I cant see where the problem reside...

I will paste my code and break where I think is the problem... (scroll down to the second "code" section)

This first lines are the output of the loops taht check the descriptors...

; (1:2)  (3:4)  (5) (6)  (7)  (8)  | NAME_OF_SELECTOR
; 0000 | 0000 | 00  | 00  | 00  | 00  |  (zero)
; ffff | 0000 | 01  | 9a  | 00  | 00  |  (code)
; ffff | 0000 | 01  | 92  | 00  | 00  |  (data)
; ffff | 0000 | 01  | 92  | 00  | 00  |  (stack)
; ffff | 8000 | 0b  | 92  | 00  | 00  |  (video)
jmp start2

; %define REGPRINT
%include "basic.inc"
%include "pmdefs.inc"
Print_DL
Print_Hex16:
push bx
mov cx, 2

PrintDigit:
rol  dl, 4      ; rotate so that lowest 4 bits are used
mov  ax, 0E0Fh ; ah = request, al = mask for nybble
and  al, dl

add  al, 90h ; convert al to ascii hex (four instructions)
daa
adc  al, 40h
daa

int  10h ; call BIOS to print char
loop  PrintDigit
pop bx
ret

Print_CRLF:
mov ax,0E0Dh ; al=CR=0x0D, ah=0x0E=print char fn
int 10h
mov ax,0E0Ah ; al=LF=0x0A
int 10h
ret
; ##########################################
; pm.h
; ##########################################

; unsigned int read_msw();
read_msw:
smsw ax
ret

; unsigned long read_cr0();
read_cr0:
mov eax, cr0
;mov edx, eax
;shr edx, 16 ; return dx:ax
ret

; void write_cr0 (unsigned long value);
write_cr0:
push bp
mov bp, sp
mov eax, ; 2 ret addr + 2 of old bp and read from here 32-bit argument
mov cr0, eax
pop bp
ret 4

; void            lgdt (GDTR *gdtr);
; is load_gdt because lgdt is the asm instruction...
load_gdt:
push bp
mov bp, sp
push bx
mov bx, ; ds:bx = pointer to the GDTR
lgdt   ; load GDTR
pop bx
pop bp
ret 2

; void            update_cs (unsigned int bew_cs);
update_cs:
push bp
mov bp, sp
mov ax, ; ax = new CS
push ax        ; push segment
push word .1  ; push offset
retf          ; we have a new CS now
.1:
pop bp
ret 2



; ##########################################



; ####################################################################
; source of tutorial
; ####################################################################


gdt_label: times (5*DESCR_SEG_size) db 0
gdtr_label: times DESCR_GDTR_size db 0

old_CS dw 0
old_DS dw 0
old_SS dw 0

msg db "H e l l o  f r o m  P M o d e  w i t h  G D T ! ", 0xa, 0xd, 0x0

;void setup_GDT_entry (DESCR_SEG *item,
;                  dword base, dword limit, byte access, byte attribs)
setup_GDT_entry:
%define item ebp+4    ; word
%define base ebp+6    ; dword
%define limit ebp+10  ; dword
%define access ebp+14 ; byte
%define attribs ebp+16; byte
push bp
mov bp, sp
mov bx,
; /* Setup the descriptor base address */
; item->base_l = base & 0xFFFF;
mov ax,
mov , ax
; item->base_m = (base >> 16) & 0xFF;
mov al,
mov , al
; item->base_h = base >> 24;
mov al,
mov , al

;/* Setup the descriptor limits */
; item->limit = limit & 0xFFFF;
mov ax,
mov , ax

; item->attribs = attribs | ((limit >> 16) & 0x0F);
mov al,
and al, 0x0f
and byte, 0xf0
or al,
mov , al
; Finally setup access
; item->access = access;
mov al,
mov , al
pop bp
ret 14



; void my_exit();
msg_exit: db 13, 10, "We are back...", 13, 10
db "PMode Tutorial by Alexei A. Frounze (c) 2000", 13, 10

my_exit:
mov ah,0x19
mov si, msg_exit
call PrintStr2CharVideo
BEEP
WAITKEY
jmp $ ; don't halt the system.

; ####################################################################
msg1 db "Welcome to the 2nd PMode tutorial!", 13, 10, 0
msg2 db "The CPU is already in PMode.", 13, 10, "Aborting...", 13, 10, 0
msg3 db "We're going to PMode using CR0 for 5 seconds...",13, 10, 0
start2:
; #################################################################
; ############# SOLAR OS startup #################################
cli ; please no interupts
mov ax,cs
mov ds,ax
; mov es,ax ; es same as ds

; mov ,dl ; save drive #
;------------------------------------------------------
; here we make our own stack
; just under the A000h video memory
;------------------------------------------------------
mov ax,09000h ; segment for stack
mov ss,ax
mov sp,0F800h ; offset for stack

sti ; enable ints again
; #################################################################
; #################################################################
push bp
mov bp, sp
%define p bp-2
%define c bp-4 ; the align instead of take like byte...
%define scr bp-12
sub esp, 12

call InitCharVideo
mov ah, 0x07
call ClrScr
mov si, msg1
call PrintStr2CharVideo
mov word, my_exit ; atexit (my_exit);
push ax
call read_msw
and ax, 1
pop ax
jz .noPMode
mov si, msg2
call PrintStr2CharVideo
mov sp, bp
pop bp
ret
.noPMode:

jmp .n2
.m2 db "0x0:NULL DESC", 13, 10, 0
.m3 db "0x8:CODE DESC", 13, 10, 0
.m4 db "0x10:DATA DESC", 13, 10, 0
.m5 db "0x18:STACK DESC", 13, 10, 0
.m6 db "0x20:Video DESC", 13, 10, 0
.m7 db "Entering PM", 13, 10, 0
.m8 db "Out of PM", 13, 10, 0
.n2

; /* 0x00 -- null descriptor */
; setup_GDT_entry (&gdt[0], 0, 0, 0, 0);
mov si, .m2
call PrintStr2CharVideo
push ax
push byte 0
push byte 0
push word 0 ; high word of the doble word
push word 0 ; low word of the doble word
push word 0 ; high word of doble word
push word 0 ; low word of doble word
push word gdt_label + 0* DESCR_SEG_size
call setup_GDT_entry
pop ax
xor bx, bx
.descriptor1
mov dl,
call Print_Hex16
inc bx
cmp bx, 8
jne .descriptor1
call Print_CRLF
; /* 0x08 -- code segment descriptor */
; setup_GDT_entry (&gdt[1], ((dword)_CS)<<4, 0xFFFF, ACS_CODE, 0);
mov si, .m3
call PrintStr2CharVideo
push ax
push byte 0
push 0x9a ; ACS_CODE
push word 0
push word 0xffff
mov ax, cs
mov cx, cs
shl ax, 4  ; low
shr cx, 12 ; high
push cx
push ax
push word gdt_label + 1*DESCR_SEG_size
call setup_GDT_entry
pop ax
xor bx, bx
.descriptor2
mov dl,
call Print_Hex16
inc bx
cmp bx, 8
jne .descriptor2
call Print_CRLF
; /* 0x10 -- data segment descriptor */
; setup_GDT_entry (&gdt[2], ((dword)_DS)<<4, 0xFFFF, ACS_DATA, 0);
mov si, .m4
call PrintStr2CharVideo
push ax
push byte 0
push 0x92 ; ACS_DATA
push word 0      ; high word of double word
push word 0xffff ; low word of double word
mov ax, cs
mov cx, cs
shl ax, 4
shr cx, 12
push cx
push ax
push word gdt_label + 2*DESCR_SEG_size
call setup_GDT_entry
pop ax
xor bx, bx
.descriptor3
mov dl,
call Print_Hex16
inc bx
cmp bx, 8
jne .descriptor3
call Print_CRLF
; /* 0x18 -- stack segment descriptor */
; setup_GDT_entry (&gdt[3], ((dword)_SS)<<4, 0xFFFF, ACS_STACK, 0);
mov si, .m5
call PrintStr2CharVideo
push ax
push byte 0
push 0x92 ; ACS_STACK
push word 0
push word 0xffff
mov ax, cs
mov cx, cs
shl ax, 4
shr cx, 12
push cx
push ax
push word gdt_label + 3*DESCR_SEG_size
call setup_GDT_entry
pop ax
xor bx, bx
.descriptor4
mov dl,
call Print_Hex16
inc bx
cmp bx, 8
jne .descriptor4
call Print_CRLF
; /* 0x20 -- text video mode segment descriptor */
; setup_GDT_entry (&gdt[4], 0xB8000L, 0xFFFF, ACS_DATA, 0);
mov si, .m6
call PrintStr2CharVideo
push ax
push byte 0
push 0x92 ; ACS_DATA
push word 0
push word 0xffff
push word 0xb
push word 0x8000
push word gdt_label + 4*DESCR_SEG_size
call setup_GDT_entry
pop ax
xor bx, bx
.descriptor5
mov dl,
call Print_Hex16
inc bx
cmp bx, 8
jne .descriptor5
call Print_CRLF


; /* disable interrupts so that IRQs don't cause exceptions */
cli
; /* disable NMIs as well */
in al, 0x70
or al, 0x80
out 0x70, al


Here is where the problem reside...

; ########~~~~~~~~~~~~~~$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%///////////////
;  /* setting up the GDTR register */
; gdtr.base = ((dword)_DS)<<4;
; gdtr.base += (word)&gdt;
; gdtr.limit = sizeof(gdt)-1;
; lgdt (&gdtr);
mov ax, ds
mov cx, ds
shl ax, 4 ;low
shr cx, 12 ; high
; cs is now in cx + ax
add ax, gdtr_label
adc cx, 0
mov , ax
mov , cx
mov ax, 5*DESCR_SEG_size-1
mov , ax

push word gdtr_label
call load_gdt

; /* saving real mode segment addresses */

mov ax, cx
mov , ax
mov ax, ds
mov , ax
mov ax, ss
mov , ax

mov si, .m7
call PrintStr2CharVideo
WAITKEY
; /* WOW!!! This switches us to PMode just setting up CR0.PM bit to 1 */
call read_cr0 ; ; return dx:ax
or ax, 1
push eax
call write_cr0
; BEEP ; this beep sound OK !!!!

; /* loading segment registers with PMode selectors */
mov ax, 0x8
push ax
call update_cs
BEEP ; this BEEP never sound!!!
; ########~~~~~~~~~~~~~~$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%///////////////


when I call update_cs the comptuer restart... tought I think the selectors are ok... like I see my routines are ok.. load_gdt and update_cs. I supose Im blocked for see the problem...


mov ax, 0x8
add ax, ax
mov ds, ax
mov es, ax
add ax, ax
mov ss, ax
; /* writing a message to the screen */

; this will not be done until I correct the thing :D

; /* get out of PMode clearing CR0.PM bit to 0 */
call read_cr0
and eax, 0xFFFFFFFE
push eax
call write_cr0

; /* restoring real mode segment values */
push word
call update_cs
mov ax,
mov es, ax
mov ds, ax
mov ax,
mov ss, ax


mov ah, 0x57
mov si, .m8
call PrintStr2CharVideo

; /* enable NMIs */
in al, 0x70
and al, 0x7f
out 0x70, al

; /* enabling interrupts */
sti

xor ax, ax
mov sp, bp
pop bp
ret


Sorry for all the "extra" stuff that come there...


By the way, hope when I terminate with them, put all here ;).
Posted on 2005-05-19 19:52:28 by rea
I was thinking that will be more easy if I give the other two modules and the output...

You can assemble them with
1) nasmw t1.asm
2) nasmw disk.asm or nasmw disk.asm -D emu, if you whant to pad the extra bytes have the size of a floppy disk.
Attachments:
Posted on 2005-05-20 09:13:02 by rea
You can start by simple isolation. Put jmp $ after certain parts to determine what "exactly" is causing the triple-fault. Keep moving the jmp $ until you've reached a point where it doesn't triple-fault anymore. Look at the code between the 2 points, then you can work your way back to the source of the problem
Posted on 2005-05-20 16:37:55 by SpooK
The code that cause the fault is the update of the CS, in any way like the following


push 0x8
push .cont
retf
.cont

or

call update_cs


also I have tested with

jmp 0x8:.continueHere
.continueHere


And also cause the same error.




grrrrrr.... lol :lol: :shock: :mad: :D wait a moment, I have watched something that I have missed....


add ax, gdtr_label

isntead of

add ax, gdt_label



Lol, I must think in a good way of name my variables...


I will see what things are changed....
Posted on 2005-05-20 17:35:07 by rea
What a mess I do for detect my change of names... isnt it?

:).

I only have one thing left in this tut...

; (1:2)  (3:4)  (5) (6)  (7)  (8)  | NAME_OF_SELECTOR
; 0000 | 0000 | 00  | 00  | 00  | 00  |  (zero)
; ffff | 0000 | 01  | 9a  | 00  | 00  |  (code)
; ffff | 0000 | 01  | 92  | 00  | 00  |  (data)
; ffff | 0000 | 01  | 92  | 00  | 00  |  (stack)
; ffff | 8000 | 0b  | 92  | 00  | 00  |  (video)
jmp start2

; %define REGPRINT
%include "basic.inc"
%include "pmdefs.inc"

; ##########################################
; pm.h
; ##########################################

; unsigned int read_msw();
read_msw:
smsw ax
ret

; unsigned long read_cr0();
read_cr0:
mov eax, cr0
;mov edx, eax
;shr edx, 16 ; return dx:ax
ret

; void write_cr0 (unsigned long value);
write_cr0:
push bp
mov bp, sp
mov eax, ; 2 ret addr + 2 of old bp and read from here 32-bit argument
mov cr0, eax
pop bp
ret 4

; void            lgdt (GDTR *gdtr);
; is load_gdt because lgdt is the asm instruction...
load_gdt:
push bp
mov bp, sp
push bx
mov bx, ; ds:bx = pointer to the GDTR
lgdt   ; load GDTR
pop bx
pop bp
ret 2

; void            update_cs (unsigned int bew_cs);
update_cs:
push bp
mov bp, sp
mov ax, ; ax = new CS
push ax        ; push segment
push word .1  ; push offset
retf          ; we have a new CS now
.1:
pop bp
ret 2



; ##########################################



; ####################################################################
; source of tutorial
; ####################################################################


gdt_label: times (5*DESCR_SEG_size) db 0
gdtr_label: times DESCR_GDTR_size db 0

old_CS dw 0
old_DS dw 0
old_SS dw 0
old_SP dw 0

msg db "H e l l o  f r o m  P M o d e  w i t h  G D T ! ", 0x0

;void setup_GDT_entry (DESCR_SEG *item,
;                  dword base, dword limit, byte access, byte attribs)
setup_GDT_entry:
%define item ebp+4    ; word
%define base ebp+6    ; dword
%define limit ebp+10  ; dword
%define access ebp+14 ; byte
%define attribs ebp+16; byte
push bp
mov bp, sp
mov bx,
; /* Setup the descriptor base address */
; item->base_l = base & 0xFFFF;
mov ax,
mov , ax
; item->base_m = (base >> 16) & 0xFF;
mov al,
mov , al
; item->base_h = base >> 24;
mov al,
mov , al

;/* Setup the descriptor limits */
; item->limit = limit & 0xFFFF;
mov ax,
mov , ax

; item->attribs = attribs | ((limit >> 16) & 0x0F);
mov al,
and al, 0x0f
and byte, 0xf0
or al,
mov , al
; Finally setup access
; item->access = access;
mov al,
mov , al
pop bp
ret 14



; void my_exit();
msg_exit: db 13, 10, "We are back...", 13, 10
db "PMode Tutorial by Alexei A. Frounze (c) 2000", 13, 10, 0

my_exit:
WAITKEY
BEEP
mov ah,0x19
mov si, msg_exit
call PrintStr2CharVideo
jmp $ ; don't halt the system.

; ####################################################################
msg1 db "Hi. Welcome to the 2nd PMode tutorial!", 13, 10, 0
msg2 db "The CPU is already in PMode.", 13, 10, "Aborting...", 13, 10, 0
msg3 db "We're going to PMode using CR0 for 5 seconds...",13, 10, 0
start2:
; #################################################################
; ############# SOLAR OS startup #################################
cli ; please no interupts
mov ax,cs
mov ds,ax
mov es,ax ; es same as ds

; mov ,dl ; save drive #
;------------------------------------------------------
; here we make our own stack
; just under the A000h video memory
;------------------------------------------------------
mov ax,09000h ; segment for stack
mov ss,ax
mov sp,0F800h ; offset for stack

sti ; enable ints again
; #################################################################
; #################################################################
push bp
mov bp, sp
%define p bp-2
%define c bp-4 ; the align instead of take like byte...
%define scr bp-12
sub esp, 12

call InitCharVideo
mov ah, 0x07
call ClrScr
mov si, msg1
call PrintStr2CharVideo
mov word, my_exit ; atexit (my_exit);
push ax
call read_msw
and ax, 1
pop ax
jz .noPMode
mov si, msg2
call PrintStr2CharVideo
mov sp, bp
pop bp
ret
.noPMode:

; /* 0x00 -- null descriptor */
; setup_GDT_entry (&gdt[0], 0, 0, 0, 0);
push byte 0
push byte 0
push word 0 ; high word of the doble word
push word 0 ; low word of the doble word
push word 0 ; high word of doble word
push word 0 ; low word of doble word
push word gdt_label + 0* DESCR_SEG_size
call setup_GDT_entry
; /* 0x08 -- code segment descriptor */
; setup_GDT_entry (&gdt[1], ((dword)_CS)<<4, 0xFFFF, ACS_CODE, 0);
push byte 0
push 0x9a ; ACS_CODE
push word 0
push word 0xffff
mov ax, cs
mov cx, cs
shl ax, 4  ; low
shr cx, 12 ; high
push cx
push ax
push word gdt_label + 1*DESCR_SEG_size
call setup_GDT_entry
; /* 0x10 -- data segment descriptor */
; setup_GDT_entry (&gdt[2], ((dword)_DS)<<4, 0xFFFF, ACS_DATA, 0);
push byte 0
push 0x92 ; ACS_DATA
push word 0      ; high word of double word
push word 0xffff ; low word of double word
mov ax, cs
mov cx, cs
shl ax, 4
shr cx, 12
push cx
push ax
push word gdt_label + 2*DESCR_SEG_size
call setup_GDT_entry
; /* 0x18 -- stack segment descriptor */
; setup_GDT_entry (&gdt[3], ((dword)_SS)<<4, 0xFFFF, ACS_STACK, 0);
push byte 0
push 0x92 ; ACS_STACK
push word 0
push word 0xffff
mov ax, cs
mov cx, cs
shl ax, 4
shr cx, 12
push cx
push ax
push word gdt_label + 3*DESCR_SEG_size
call setup_GDT_entry
; /* 0x20 -- text video mode segment descriptor */
; setup_GDT_entry (&gdt[4], 0xB8000L, 0xFFFF, ACS_DATA, 0);
push byte 0
push 0x92 ; ACS_DATA
push word 0
push word 0xffff
push word 0xb
push word 0x8000
push word gdt_label + 4*DESCR_SEG_size
call setup_GDT_entry
; /* disable interrupts so that IRQs don't cause exceptions */
cli
; /* disable NMIs as well */
in al, 0x70
or al, 0x80
out 0x70, al

;  /* setting up the GDTR register */
mov ax, ds
mov cx, ds
shl ax, 4 ;low
shr cx, 12 ; high
; cs is now in cx + ax
add ax, gdt_label
adc cx, 0
mov , ax
mov , cx
mov ax, 5*DESCR_SEG_size-1
mov , ax

push word gdtr_label
call load_gdt

; /* saving real mode segment addresses */

mov ax, cx
mov , ax
mov ax, ds
mov , ax
mov ax, ss
mov , ax
mov ax, sp
mov , ax

; Here this work OK...
; mov sp, bp
; pop bp
; ret
; /* WOW!!! This switches us to PMode just setting up CR0.PM bit to 1 */
call read_cr0 ; ; return dx:ax
or ax, 1
push eax
call write_cr0

; /* loading segment registers with PMode selectors */
push 0x8
call update_cs
mov ax, 0x10
mov ds, ax
mov es, ax
mov ax, 0x18
mov ss, ax

; /* writing a message to the screen */
mov ax, 0x20
mov gs, ax
mov si, msg
mov di, 40*40
.aga
lodsb
or al, al
jz .fin
mov , al
inc di
jmp .aga
.fin

; /* get out of PMode clearing CR0.PM bit to 0 */
call read_cr0
and eax, 0xFFFFFFFE
push eax
call write_cr0


Code continue after this.

From the Intel manual I read

9.9.2. Switching Back to Real-Address Mode
...
7. Execute a far JMP instruction to jump to a real-address mode program. This operation
flushes the instruction queue and loads the appropriate base and access rights values in the
CS register.
...


Aparently is only valid to return with a jump, but in the source code of the tutorial, is used the same function "update_cs" pushing the value of old_CS, in the precompiled exe under DosBox it work ok..., then why aparently call update_cs for return to real mode work in the exe and not in my code?.. but in the intel manual say with a "jump" instead of a "retf" it explicetely state a "jump", not like to enter to PM

9.9.1. Switching to Protected Mode
....
4. Immediately following the MOV CR0 instruction, execute a far JMP or far CALL
instruction. (This operation is typically a far jump or call to the next instruction in the
instruction stream.)
....


That you can select a far jump or call...


A posible way to calculate at runtime (without hardcode that 0x1000:.continueHere) can be with a far jump with a memory operand????


; /* restoring real mode segment values */
;push word   ; This two lines dosent work
;call update_cs

;push 0x1000          ; This three lines also dont work
;push .continueHe
;retf

jmp 0x1000:.continueHe ; This is OK.
.continueHe
mov ax,
mov es, ax
mov ds, ax
mov ax,
mov ss, ax
mov ax,
mov sp, ax
; /* enable NMIs */
in al, 0x70
and al, 0x7f
out 0x70, al

; /* enabling interrupts */
sti

call InitCharVideo
mov sp, bp
pop bp
ret
Posted on 2005-05-20 21:29:12 by rea