I am trying to implement protected - real mode switching. The code below is supposed to run on a protected mode os and is eventually supposed to enable vesa activation through 10h interrupt and then switch back to beloved protected mode . The routine _exit_pmode is integrated into the c++ project files of my os-code through a c++-header file with the corresponding inline code. I have most of the code off this forum. Thanks so far!
I am working with linux and nasm 0.98.38. So the errors I am getting are 1st:
' relocation truncated to fit: R_386_16 against ' when trying to compile. It must have something to do with me not being in 16 bit code when I should be, I also read about that here and on the net. (Ah, and the org directive doesn't work)
2: I can compile with no errors when I add the option '-Ttext 0xEFFF' to ld in the Makefile which I understand is supposed to tell the linker that the code should be put to that adress. Well if I do this and run the system in bochs the bochs-cpu triple-faults. Could this have something to do with the code messing with my startup code?
I have been looking around in the web for quite a while now. I would really appreciate some specific response to my problem! Thanks so much!
Best,
joegy
Code: Select all
_exit_pmode: ; method exported to c++ to exit protected mode
[BITS 32]
jmp REAL_CODE_SEL:do_16
[BITS 16]
do_16:
; disable interrupts
cli
; let's create a new stack / load SS with real mode values
mov ax, REAL_DATA_SEL
mov ds, ax
mov ss, ax
nop
; push real-mode CS:IP
mov bx,[RealModeCS]
push bx
lea bx,[RealMode]
push bx
;lea bx,[RealMode]
;push bp
;push bx
; Exit Protected Mode
mov eax, cr0
and al,0xFE
mov cr0, eax
sti
ret
;jmp REAL_CODE_SEL:RealMode
RealMode:
; Stack-Stuff / Load all data segment registers with real mode values
mov ax, cs
mov ds, ax
mov ss, ax
nop
mov es, ax
mov fs, ax
mov gs, ax
; restore the Real-Mode IDT
lidt [ridtr]
;mov dx, 0x70
;in al, dx
;and al, 0x7F
;out dx, al
;enable interrupts
sti
ret
[SECTION .data]
gdt0 equ $ ; null entry
GDT:
.Entry0: 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
REAL_CODE_SEL equ $-gdt0 ; code segment descriptor for 16 bit mode
.Entry1: dw 0xFFFF
dw 0x0 ; base
db 0x0 ; base
db 0x9A ; present, ring 0, code, non-conforming, readable
db 0x00 ; 16 bit
db 0
REAL_DATA_SEL equ $-gdt0 ; data segment descriptor for 16 bit mode
.Entry2: dw 0xFFFF
dw 0x0 ; base
db 0x0 ; base
db 0x92 ; present, ring 0, data, expand-up, writable
db 0x00 ; 16 bit
db 0
RealModeCS equ $-gdt0
.Entry3:
dw 0
ridtr equ $-gdt0
.Entry4:
dw 0xFFFF ; limit=0xFFFF
dd 0 ; base=0