From earlier posts on the forum I was trying to test code between privilege levels so I had designed a small label for a gate in protected mode to try and reset the values by the GDT accordingly. Instead I made another segment for my code to go through the steps when I realized that my boot code couldn't make calls from the new real mode.Originally I was making a task state segment value and was happy that all the other functions worked in the section until I called from the IDT pipeline to truly verify the state between protected modes. Here is the source for this code.
%define BUILD_GDT_DESC(bounds,base,access,flags) \
((( base & 0x00FFFFFF) << 16) | \
(( base & 0xFF000000) << 32) | \
( bounds & 0x0000FFFF) | \
(( bounds & 0x000F0000) << 32) | \
(( access & 0xFF) << 40) | \
(( flags & 0x0F) << 52))
TSS_IO_MAP_SIZE EQU 0x400/8
[BITS 16]
section .data
ROWS EQU 25
COLS1 EQU 80
section .text
_prep_module2:
jmp _prep_module2_
Idtpipe32:
dw 0
dd 0
_prep_module2_:
cld
cli
in al,0x92
or al,2
out 0x92,al
; mov [saved_segment],ds
lgdt[gdt32Ptr]
lidt[Idtpipe32]
mov word [gate_voucher],GATE_VOUCHER
protectedGate:
mov eax,cr0
or eax,1
mov cr0,eax
jmp code32_post:protectedMode
;.pm_track:
; mov word [gate_voucher],GATE_CHECK
; jmp protectedGate
[bits 32]
trail:
jmp $
; mov sp,bp
; ret
protectedMode:
mov cx,word [gate_voucher]
cmp cx,0
jz trail
mov dword [saved_segment],data32_post
call task_prod
; mov ebp,tss32_post
; ltr bp
call task_poke
mov esp,edx
mov esp,PM_MODE_STACK
mov ah,COLOR_ATTR_PSC
mov al,ah
mov esi, pm_str
call printstr_pm
; jmp $
prep_stage:
mov ebp,tss
mov edx,0
mov ecx,0
; mov ebp,0
.prep_loop1:
mov es:bp,dx
add bp,1
cmp bp,0x8298
; cmp bp,0x8319
jnz .prep_loop1
; jmp prototype2
.prep_stage2:
mov word [tss.iomap_base],tss.iomap - tss
mov ebp,tss32_post
ltr bp
_prep_stage1:
; lgdt[gdt16Ptr]
jmp rm_poll_function
; jmp 0:rm_poll_function
;[bits 16]
;use16
;testing states
rm_poll_function:
;use16
cli
xor ecx,ecx
mov ebp,esp
;rmGate:
; jmp 0:rm_poll_state
; jmp cs:rm_poll_state
; use16
; jmp rmGate
; jmp 0:rmGate
jmp code16_post:rmGate
[bits 16]
rm_trail:
ret
rmGate:
mov ecx,data16_post
mov es,cx
; mov cs,cx
mov ds,cx
mov fs,cx
mov gs,cx
mov ss,cx
mov eax,cr0
mov [save_cr0],eax
and eax,07ffffffeh
mov cr0,eax
; lgdt[gdt32Ptr]
; lidt[Idtpipe]
; mov word [gate_voucher],GATE_VOUCHER
; push word [gate_voucher]
; pop cx
mov cx,1
cmp cx,0
jz rm_trail
; jmp code16_post:rm_poll_state
jmp 0:rm_poll_state
; push cs
; push rm_poll_state
; retf
Idtpipe:
dw 0x3ff
dd 0
Idtpipe2:
dw 0xffff
dd 0
rm_poll_state:
xor eax,eax
xor ecx,ecx
; mov sp,0x0000_9000
mov esp,0x00009000
; mov sp,0x9000
; mov cx,0
mov es,cx
; mov cs,cx
mov ss,cx
mov ds,cx
mov fs,cx
mov gs,cx
; mov sp,0x0000_9000
lidt[Idtpipe2]
sti
jmp retstack
; jmp prototype
mov dword [saved_segment],data16_post
mov word [gate_voucher],GATE_CHECK
call task_prod16
; call task_poke16
call poll_function1
call color_function
; jmp retstack
; jmp prototype
; jmp protectedGate2
; jmp protectedGate.pm_track
jmp _prep_module3
; jmp $
retstack:
; pushf
push 0x0000
; push byte data16_post
; push byte code16_post
; push byte Idtpipe
push word color_function
retf
; retfw
prototype:
xor ax,ax
mov ds,ax
mov ax,[0x40]
mov dx,[0x42]
mov [pre],ax
mov [pre+2],dx
mov word [0x40],handler
mov [0x42],cs
mov ah,0x0e
mov al,'h'
int 0x10
jmp $
handler:
inc ax
jmp far [pre]
pre: dd 0
poll_function1:
.prep:
xor ebx,ebx
xor edx,edx
; mov ax,0
mov cx,0
mov es,cx
mov ax,ROWS
mov bx,es:0x044A
mul bx
add ax,COLS1
shl ax,1
mov si,ax
; mov cx,0B000H
; test byte es:0x0410,2
; jnz .Address_OK
mov cx,0B800H
.Address_OK:
mov es,cx
mov al,'H'
mov es:[si],byte al
; mov es:0,byte al
mov es:si,byte al
mov ds:si,byte al
mov ds:[si],byte al
inc si
ret
; jmp $
loopcheck:
; hlt
jmp loopcheck
color_function:
; set base pointer to heap
; and stack pointer to stack for functions and variables
mov dx,sp
mov ax,0x13
int 0x10
mov cx,0xA000
mov es,cx
mov word[X],50
mov word[Y],60
call color_method
mov word[X],100
mov word[Y],60
call color_method
mov word[X],120
mov word[Y],120
call color_method
mov word[X],140
mov word[Y],30
call color_method
mov sp,dx
; hlt
ret
color_method :
mov ax, word[X]
mov bx, word[Y]
xor si, si
add si,word 320
imul si, bx
add si, ax
mov cx, word[color_pkg]
mov [es:si], cx
ret
task_poke16:
; mov word [gate_voucher],1
;check wizard stall
mov cx,word [gate_voucher]
cmp cx,0
jnz .prep
.prep:
mov eax,[tss.eax]
mov ecx,[tss.ecx]
mov edx,[tss.edx]
mov ebx,[tss.ebx]
mov esp,[tss.esp]
mov ebp,[tss.ebp]
mov esi,[tss.esi]
mov edi,[tss.type2]
mov cx,[tss.ds]
mov es,cx
; mov cs,cx
mov ss,cx
mov ds,cx
mov fs,cx
mov gs,cx
mov cx,word [gate_voucher]
cmp cx,0
jnz .post
; call rmGate
.post:
ret
;%endif
;[bits 32]
task_prod16:
mov cx,word [gate_voucher]
cmp cx,0
jnz .inst_placer
; call protectedGate
.reference:
mov word [tss.ecx],cx
mov word [tss.esp1],sp
mov cx,ss
mov word [tss.ss1],cx
.inst_placer:
pop cx
push cx
mov word [tss.eip],cx
.prep:
; pushd ecx
pushf
; popf dword [tss.eflags]
pop cx
mov word [tss.eflags],cx
mov word [tss.eax],ax
; mov dword [tss.ecx],ecx
mov word [tss.edx],dx
mov word [tss.ebx],bx
mov word [tss.esp],sp
mov word [tss.ebp],bp
mov word [tss.esi],si
mov word [tss.type2],di
push cx
mov cx,[saved_segment]
mov word [tss.es],cx
mov word [tss.cs],cx
mov word [tss.ss],cx
mov word [tss.ds],cx
mov word [tss.fs],cx
mov word [tss.gs],cx
pop cx
ret
;r2pm_backtrack:
_prep_module3:
cld
cli
in al,0x92
or al,2
out 0x92,al
; mov [saved_segment],ds
lgdt[gdt32Ptr]
lidt[Idtpipe32]
mov word [gate_voucher],GATE_VOUCHER
protectedGate2:
mov eax,cr0
or eax,1
mov cr0,eax
jmp code32_post:modeProtect2
;.pm_track:
; mov word [gate_voucher],GATE_CHECK
; jmp protectedGate
[bits 32]
trail2:
jmp $
; mov sp,bp
; ret
modeProtect2:
mov word [saved_segment],data32_post
; call task_poke
mov ecx,[saved_segment]
mov es,cx
; mov cs,cx
mov ss,cx
mov ds,cx
mov fs,cx
mov gs,cx
.loopcheck:
jmp $
printstr_pm:
push ds
; push esi
push eax
; push ebp
mov ebp,0
jmp .gettext
.output:
mov esi,[vidmem_ptr]
add esi,ebp
mov [es:esi],ax
add ebp,2
pop esi
.gettext:
mov al,[ds:si]
add si,1
push esi
test al,al
jnz .output
.stub1:
dec esi
shr ebp,1
add esi,ebp
mov [vidmem_ptr],esi
pop esi
pop eax
pop ds
ret
task_poke:
mov cx,word [gate_voucher]
cmp cx,0
jnz .prep
.prep:
mov eax,[tss.eax]
mov ecx,[tss.ecx]
mov edx,[tss.edx]
mov ebx,[tss.ebx]
mov esp,[tss.esp]
mov ebp,[tss.ebp]
mov esi,[tss.esi]
mov edi,[tss.type2]
mov cx,[tss.ds]
mov es,cx
; mov cs,cx
mov ss,cx
mov ds,cx
mov fs,cx
mov gs,cx
mov cx,word [gate_voucher]
cmp cx,0
jnz .post
; call rmGate
.post:
ret
;%endif
;[bits 32]
task_prod:
mov cx,word [gate_voucher]
cmp cx,0
jnz .inst_placer
mov dword [tss.ecx],ecx
.inst_placer:
pop ecx
push ecx
mov dword [tss.eip],ecx
.prep:
; pushd ecx
pushf
; popf dword [tss.eflags]
pop ecx
mov dword [tss.eflags],ecx
mov dword [tss.eax],eax
; mov dword [tss.ecx],ecx
mov dword [tss.edx],edx
mov dword [tss.ebx],ebx
mov dword [tss.esp],esp
mov dword [tss.ebp],ebp
mov dword [tss.esi],esi
mov dword [tss.type2],edi
push ecx
mov cx,[saved_segment]
mov word [tss.es],cx
mov word [tss.cs],cx
mov word [tss.ss],cx
mov word [tss.ds],cx
mov word [tss.fs],cx
mov word [tss.gs],cx
pop ecx
ret
section .rodata
__STACK__ dd 0x00FFFFFF
__HEAP__ dd 0x00008C24
VGA_MEM dw 0xA000
WIDTH dw 320
HEIGHT dw 219
VIDEO_TEXT_ADDR EQU 0XB8000
COLOR_ATTR_PSC EQU 0X6A
COLOR_ATTR_BSC EQU 0X5F
PM_MODE_STACK EQU 0X80000
VM_STACK_SEG EQU 0X0000
VM_STACK_OFS EQU 0X0000
VM_CS_SEG EQU 0X0000
FLAGS_VM_CMP EQU 17
FLAGS_CMP1 EQU 1
FLAGS_CMP_IF EQU 9
FLAGS_CMP_IOPL EQU 12
RING0_PROC_STACK_SIZE EQU 2048
;TSS_IO_MAP_SIZE EQU 0
TSS_IO_MAP_SIZE EQU 0x400/8
;VM_STACK_ADDRESS EQU vidmem_address
GATE_CHECK EQU 0
GATE_VOUCHER EQU 1
section .data
align 4
gdt32:
dq BUILD_GDT_DESC(0,0,0,0)
gdt32code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1100b)
gdt32data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1100b)
gdt16code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1000b)
gdt16data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1000b)
;gdt16tss:dq BUILD_GDT_DESC(0x8230,TSS_SIZE-1,10001001b,0000b) & 0 << 22
gdt32tss:
dq BUILD_GDT_DESC(TSS_SIZE-1,0x8470,10001001b,0000b)
; dq BUILD_GDT_DESC(TSS_SIZE-1,0x9260,10001001b,0000b)
.stub1:
code32_post: equ gdt32code -gdt32
data32_post: equ gdt32data -gdt32
;.stub:
code16_post: equ gdt16code -gdt32
data16_post: equ gdt16data -gdt32
tss32_post: equ gdt32tss -gdt32
gdt32Len: equ $-gdt32
gdt32Ptr: dw gdt32Len-1
dd gdt32
;align 4
vidmem_ptr: dd VIDEO_TEXT_ADDR
pm_str: db 'protected mode string ',0
pm_str_length: equ $-pm_str
vm_str: db 'virtual',0
;vidmem_address: dw 0
;resb 512
times 512 db 0
align 16
tss:
.back_link: dd 0
.esp0: dd 0
.ss0: dd 0
.esp1: dd 0
.ss1: dd 0
.esp2: dd 0
.ss2: dd 0
.cr3: dd 0
.eip: dd 0
.eflags: dd 0
.eax: dd 0
.ecx: dd 0
.edx: dd 0
.ebx: dd 0
.esp: dd 0
.ebp: dd 0
.esi: dd 0
.type2: dd 0
.es: dd 0
.cs: dd 0
.ss: dd 0
.ds: dd 0
.fs: dd 0
.gs: dd 0
.ldt: dd 0
.trap: dw 0
.iomap_base: dw 0
.iomap: TIMES TSS_IO_MAP_SIZE db 0x00
%if TSS_IO_MAP_SIZE > 0
.iomap_pad:db 0xff
%endif
.end:
TSS_SIZE: EQU tss.end -tss
save_cr0 dd 0
saved_segment resd 0
gate_voucher dw 1
X dd 0
Y dd 0
color_pkg dw 5
What I essentially was doing was combining all the steps that I could use to walkthrough the 16 <-->32 gates.Right now what I understand is
0) Makefile settings for debugging elf i386 objects
1) GDT references for size 16&32
2) Code settings for cr0 between 16&32
3) Long jumps to reset state values (like from the sources online)
4) Distinct models for 16&32 size tasks
5) Returns values from most other mode functions
6) New protected mode gate restate
Testing code.
7) IDT reference calls
retf stack method resets
9) other sources
So hopefully one of the good chat users could show us how to go about this because the answer would check out a good amount of methods.
Cheers!