However I implemented the additional code to save SS:SP in data segment before entering the protected mode and restore it into SS:SP after exiting the protected mode. In that case, the system resets, not sure why. Using jmp$ instruction, I found that reset happens right after enabling the interrupt back after exiting the protected mode.
I checked the stack values before and after by printing it out to screen to see any stack imbalance and no it was just fine. Both before and after values are same. I am wondering what else could be causing it?
Here is snippet of code, the entire code is quite big, so I pasted here the only ones that matter:
THere are two software switches I use to turn on and off the stack preparation and stack loading:
CONFIG_PMODE_SETUP_SS - code that prepares anything related to stack segment so SS:SP can be loaded with valid segments
CONFIG_PMODE_LOAD_SS - actual code that does the loading of SS:SP.
Add'l two switches en/dis-s the IDT preparation and loading of IDT into desc. cache however this is currently both turned off so code inside this switch can be ignored.
CONFIG_PMODE_SETUP_IDT
CONFIG_PMODE_LOAD_IDT
Sorry if it is a lot of code, but that is how i made it to be very configurable code.
Code: Select all
M_ENTER_PMODE macro
local mEnterPmodeExit, mEnterPmodeLab1, mEnterPmodeLab2
; Check if already in protected mode
IF OPTION_DEBUG_PMODE
M_PRINTF "\nM_ENTER_PMODE: Testing to see system is in protected mode."
ENDIF ; OPTION_DEBUG_PMODE
mov eax, cr0
test eax, 01b
jz mEnterPmodeLab2
IF OPTION_DEBUG_PMODE
M_PRINTF "\nSystem is in protected-mode. Exit with CX=1."
ENDIF ; OPTION_DEBUG_PMODE
mov cx, 1
jmp mEnterPmodeExit
mEnterPmodeLab2:
IF OPTION_DEBUG_PMODE
M_PRINTF "\nSystem is not in pmode. Checking A20."
ENDIF ; OPTION_DEBUG_PMODE
; A20 gate turned on
IF CONFIG_SUPPORT_A20
jmp $+2
in al, 92h
or al, 2h
out 92h, al
jmp $+2
ENDIF ; CONFIG_SUPPORT_A20
IF OPTION_DEBUG_PMODE
M_PRINTF "\nChecking pmode initialization flag."
ENDIF ; OPTION_DEBUG_PMODE
cmp word ptr pModeInitDone, 1
je mEnterPmodeLab1
IF OPTION_DEBUG_PMODE
M_PRINTF "\nError. pMode is not initialized."
ENDIF ; OPTION_DEBUG_PMODE
jmp mEnterPmodeExit
mEnterPmodeLab1:
IF OPTION_DEBUG_PMODE
M_PRINTF "\nSetting gdt ptr."
ENDIF ; OPTION_DEBUG_PMODE
mov ebx, DATA:offset gdtPtr
lgdt fword ptr ds:[ebx] ; issue LGDT/LIDT instruction.
IF CONFIG_PMODE_LOAD_IDT
mov ebx, DATA:offset idtPtr
lidt fword ptr ds:[ebx] ; issue LIDT instruction.
ENDIF ; CONFIG_PMODE_LOAD_IDT
; save SS:SP, do not change stack after this!!!
; while until SS:SP is loaded in p-mode values.
IF CONFIG_PMODE_SETUP_SS
IF OPTION_DEBUG_PMODE
M_PRINTF "\nSaving SS SP."
ENDIF ; OPTION_DEBUG_PMODE
mov si, DATA
mov ds, si
lea si, DATA:rModeSsSp
mov ds:[si], sp
mov ds:[si+2], ss
ENDIF ; CONFIG_PMODE_SETUP_SS
push es
push di
lea si, DATA:rModeSsSp
mov es, ds:[si]
mov di, ds:[si+2]
M_PRINTF "\nSS:SP before exiting pMode: "
M_PRINT_1616 es, di
pop di
pop es
; disable interrupts
cli
; Set control register bit.
mov eax, cr0
or al, 01h
mov cr0, eax
jmp $+2
jmp cs:farJump
farJump:
; DS = set segment descriptor entry FLAT DATA in GDT
mov ax, (flatdata-gdt)
mov ds, ax
jmp $+2
; setup protected mode stack segment.
IF CONFIG_PMODE_SETUP_SS
IF CONFIG_PMODE_LOAD_SS
mov ax, (sstack-gdt)
mov ss, ax
mov sp, 1024
; mov 0b800h,
; jmp $+2
ENDIF ; CONFIG_PMODE_LOAD_SS
ENDIF ; CONFIG_PMODE_SETUP_SS
; stack can be changed now.
IF CONFIG_PMODE_SETUP_IDT
IF CONFIG_PMODE_LOAD_IDT
sti
ENDIF ; CONFIG_PMODE_LOAD_IDT
ENDIF ; CONFIG_PMODE_SETUP_IDT
sub cx, cx ; (CX) = indicate successfull entry to pmode.
mEnterPmodeExit:
ENDM
; M_EXIT_PMODE macro is used for exiting protected mode.
; M_ENTER_PMODE is usually followed by M_EXIT_PMODE macro and it is
; extremely important that if CX=1, then M_EXIT_PMODE macro not be called
; for obvious reason. Otherwise M_EXIT_PMODE can inadvertently clear
; CR0[0] which was set and initialized by external O/S not this framework.
; output: CX=0 - if successfully exited from pmode to real mode.
; CX=1 - if system was already in real mode or any other failure.
M_EXIT_PMODE macro
local mExitPmodeExit, mExitPmodeLab2
mov eax, cr0
test eax, 01b
jnz mExitPmodeLab2
mov cx, 1
jmp mExitPmodeExit
mExitPmodeLab2:
IF CONFIG_PMODE_SETUP_IDT
IF CONFIG_PMODE_LOAD_IDT
cli ; do not change stack until SS:SP is restored!!!
ENDIF ; CONFIG_PMODE_LOAD_IDT
ENDIF ; CONFIG_PMODE_SETUP_IDT
; exit protected mode
mov eax, cr0
and eax, 0fffffffeh
mov cr0, eax
mov ax, DATA
mov ds, ax
; save SS:SP, do not change stack after this!!!
; while until SS:SP is loaded in p-mode values.
IF CONFIG_PMODE_SETUP_SS
mov si, DATA
mov ds, si
lea si, DATA:rModeSsSp
mov sp, ds:[si]
mov ss, ds:[si+2]
ENDIF ; CONFIG_PMODE_SETUP_SS
; turn off A20 gate
IF CONFIG_SUPPORT_A20
jmp $+2
in al, 92h
and al, 0feh
out 92h, al
jmp $+2
ENDIF ; CONFIG_SUPPORT_A20
; enable back interrupts
sti
push es
push di
lea si, DATA:rModeSsSp
mov es, ds:[si]
mov di, ds:[si+2]
M_PRINTF "\nSS:SP after exiting pMode: "
M_PRINT_1616 es, di
pop di
pop es
IF OPTION_DEBUG_PMODE
M_PRINTF "\nSuccessfully exited from pmode."
ENDIF ; OPTION_DEBUG_PMODE
sub cx, cx ; (CX) = indicate success.
mExitPmodeExit:
ENDM
Code: Select all
Installing gdt to descriptor cache.
Setting up &dt& PTR address:
gdt address: 00007080
gdt ptr Limit | Base:0048:00007080
Installing idt to descriptor cache.
Setting up idt ptr address:
idt address: 000070D0
idt ptr Limit | Base:0800:000070D0
input flat address: 000F56F0
M_ENTER_PMODE: Testing to see system is in protected mode.
System is not in pmode. Checking A20.
Checking pmode initialization flag.
Setting gdt ptr.
Saving SS SP.
SS:SP before exiting pMode: 00E8:06F3
SS:SP after exiting pMode: 00E8:06F3
Successfully exited from pmode.
output: 00010302
1. EBX from getDwordExtMem:00010302
Saving input addr:000F56F4
input flat address: 000F56F4
M_ENTER_PMODE: Testing to see system is in protected mode.
System is not in pmode. Checking A20.
Checking pmode initialization flag.
Setting gdt ptr.
Saving SS SP.
SS:SP before exiting pMode: 00E8:06F3
SS:SP after exiting pMode: 00E8:06F3
Successfully exited from pmode.
output: 00010302
2. EBX from getDwordExtMem:00010302
SS:SP 1a: 06F3:00FE
SS:SP 1b: 06F3:00FE
However i put the all defined descriptor table information below and entry #4 is the stack segment called sstack:
Code: Select all
==============
Descriptor No 00
BX, DS, DI: 0920 0703:08C0
Descriptor. name: null descriptor
===============:
GDT/LDT Descriptor Info:
---------------:
00000000:00000000
Segment base: 00000000
Segment size(lim): 00000000
Rx06[7]: 00 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 00 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 00 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 00 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 00 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 00 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 01
BX, DS, DI: 0922 0703:08D0
Descriptor. name: Flat-32 code
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:00CF9A00
Segment base: 00000000
Segment size(lim): 000FFFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 0A - segment descriptor type:
Rx05[3]: 01 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
code: 0=code can only be exec-d from priv.lvl set in ring
1=code can be exec-d from same or lower priv.level
Rx05[1]: 01 - W(data)/R(code)
code: 0=read access not allowed
1=read access allowed (write access never allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 02
BX, DS, DI: 0924 0703:08DD
Descriptor. name: Flat-32 data
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:00CF9200
Segment base: 00000000
Segment size(lim): 000FFFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 02 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 03
BX, DS, DI: 0926 0703:08EA
Descriptor. name: IDT
===============:
GDT/LDT Descriptor Info:
---------------:
70D007FF:00009200
Segment base: 000070D0
Segment size(lim): 000007FF
Rx06[7]: 00 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 00 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 02 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 04
BX, DS, DI: 0928 0703:08EE
Descriptor. name: Sstack
===============:
GDT/LDT Descriptor Info:
---------------:
000007FF:00409610
Segment base: 00100000
Segment size(lim): 000007FF
Rx06[7]: 00 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 06 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 01 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 05
BX, DS, DI: 092A 0703:08F5
Descriptor. name: User code
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:40C39200
Segment base: 40000000
Segment size(lim): 0003FFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 02 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 06
BX, DS, DI: 092C 0703:08FF
Descriptor. name: User data
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:80C39200
Segment base: 80000000
Segment size(lim): 0003FFFF
Rx06[7]: 01 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 02 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 00 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 07
BX, DS, DI: 092E 0703:0909
Descriptor. name: Kstack
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:C04F9610
Segment base: C0100000
Segment size(lim): 000FFFFF
Rx06[7]: 00 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 06 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 01 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)
==============
Descriptor No 08
BX, DS, DI: 0930 0703:08C0
Descriptor. name: null descriptor
===============:
GDT/LDT Descriptor Info:
---------------:
0000FFFF:C04F9620
Segment base: C0200000
Segment size(lim): 000FFFFF
Rx06[7]: 00 - Granularity (0: multiplier 1, 1: multiplier 4K):
Rx06[6]: 01 - Default Rx size: (0: 16-bit, 1: 32-bit):
Rx06[5:4]: 00 - AVL (for O/S use any way):
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4]: 01 - descriptor type (0: system segment, 1: data/code segment):
Rx05[4:1]: 06 - segment descriptor type:
Rx05[3]: 00 - code/data bit (0: data/stack/non-exec, 1: code segment):
Rx05[2]: 01 - expansion direction(data)/conform(code) bit:
data: 0=segment grows up
1=segment growns down(SS)
Rx05[1]: 01 - W(data)/R(code)
data: 0=write access not allowed
1=write access allowed (read always allowed)
Rx05[0]: 00 - A bit(accessed, each time CPU accesses it)