Use BIOS funcions from long mode ---

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
supernicky
Posts: 1
Joined: Sun Apr 03, 2016 5:59 am

Use BIOS funcions from long mode ---

Post by supernicky »

Hello,

in my OS (64bit) I would change the Displayresolution with the bios int 10h.

To switch I use the following code: http://forum.osdev.org/viewtopic.php?f=1&t=23125

Code: Select all

use64						;
bios_call:	
	cli	                                                        ;Interrupts off
		;save all GPR's
      push rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		push r9
		push r10
		push r11
		push r12
		push r13
		push r14
		push r15
		
		mov rbx, _old_esp                             ;save Stackpointer
		mov [rbx], rsp
		
		mov rsp, 6800h                                 ;new Stackpointer
		
		sidt [System.oldidt]		;save IDT
		
		push 40h				;Realmode Desc 64k laden
		push @f
		retfq
			
use16						;16 Bit P-Mode
@@:		
		
		;PE und PM off
		mov eax, cr0
		and eax, 7FFFFFFEh
		mov cr0, eax
		                                                      ;ESP to RM Addr
		mov esp, 6700h
		
		                                                      ;ds, es, ss = NULL
		xor eax, eax
		mov ds, ax
		mov es, ax
		mov fs, ax
		mov gs, ax
		mov ss, ax
		
		;Far Jump 
		jmp 0x0:@f
		
@@:		

		;Realmode IDT
		lidt [System.nullidt]
;---------------------------------------------------------------------------------------------------------------------
                           ;BIOS Calls here
;---------------------------------------------------------------------------------------------------------------------
		;PE und PM on
		mov eax, cr0
		or eax, 80000001h
		mov cr0, eax		
		
		jmp @f
@@:
		
		; Enable long mode by setting the EFER.LME flag in MSR 0xC0000080 
		mov ecx, 0C0000080h
		rdmsr
		or eax, 100h
		wrmsr
		
		

		db 66h, 0eah
		dd _p64_mode3
		dw 28h

use64		
_p64_mode3:
		jmp @f
@@:
		
		lidt [System.oldidt]		
		
		;restore Stackpointer		
		mov rbx, _old_esp
		mov rsp, [rbx]
                            ;restore all GPR's		
		pop r15
		pop r14
		pop r13
		pop r12
		pop r11
		pop r10
		pop r9
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		pop rax
	sti                                       ;Interrupt on
ret                                                     ;Exit
align 16
_old_esp dq 0
align 4
_modus_old dw 0
_oldtr dw 0
The Code works fine without Bios Calls, but when i am insert a Bios Call (e.g.

Code: Select all

mov ax, 12h
int 10h
), the processor shutdown.

what could be the Problem?

Another Question about the GDT:

Code: Select all

System:
.GDT:
		dd 0,0
._CODE32:					;0x8
		dw 0xFFFF
		dw 0                 		
		db 0                 			
		db 10011010b
		db 11001111b			;DB und G Bit gesetzt
		db 0
._DATA32:					;0x10
		dw 0xFFFF
		dw 0					
		db 0		                 	
		db 10010010b
		db 11001111b			;DB und G Bit gesetzt
		db 0	
._CODE64:				;0x28
		dw 0xFFFF
		dw 0                 		
		db 0                 			
		db 10011010b
		db 10101111b			;DB und G Bit gesetzt
		db 0		
		
._TSS64:	dw 104d			;0x30
		dw 0000h
		db 1h
		db 10001001b
		dw 00000000b
._CODE16:				;0x40
		dw 0FFFFh  		; compatibility mode code descriptor
		dw 0
		db 0
		db 10011010b
		db 0h
		db 0
._DATA16:					;0x30
		dw 0FFFFh		  ; compatibility mode data descriptor
		dw 0
		db 0
		db 10010010b
		db 0h
		db 0
;		dd 0, 0
In P-Mode VBox reads as follows:
0008 CodeER Bas=00000000 Lim=fffff000 DPL=0 P A G BIG AVL=0 L=0
0010 DataRW Bas=00000000 Lim=fffff000 DPL=0 P A G BIG AVL=0 L=0
0018 CodeER Bas=00000000 Lim=fffff000 DPL=3 P NA G BIG AVL=0 L=0
0020 DataRW Bas=00000000 Lim=fffff000 DPL=3 P NA G BIG AVL=0 L=0
0028 CodeER Bas=00000000 Lim=fffff000 DPL=0 P NA G AVL=0 L=1
0030 Tss32A Bas=00010000 Lim=00000068 DPL=0 P NB AVL=0 R=0
0040 CodeER Bas=00000000 Lim=0000ffff DPL=0 P NA AVL=0 L=0
0048 VERR_INVALID_SELECTOR
In L-Mode VBox reads as follows:
0008 CodeER Bas=00000000 Lim=ffffffff DPL=0 P A G BIG AVL=0 L=0
0010 DataRW Bas=00000000 Lim=ffffffff DPL=0 P A G BIG AVL=0 L=0
0018 CodeER Bas=00000000 Lim=ffffffff DPL=3 P NA G BIG AVL=0 L=0
0020 DataRW Bas=00000000 Lim=ffffffff DPL=3 P NA G BIG AVL=0 L=0
0028 CodeER Bas=00000000 Lim=ffffffff DPL=0 P A G AVL=0 L=1
0030 Tss64B Bas=0000000000010000 Lim=00000068 DPL=0 P B AVL=0 R=0
003c ConfER Bas=f053f000 Lim=0000ef57 DPL=3 P A AVL=0 L=0
0044 CodeEO Bas=f04dc000 Lim=00000022 DPL=3 P NA AVL=0 L=0
004c Ill-3 41 f8 00 f0 fe e3 00 f0 DPL=3 P
0054 CodeEO Bas=f059f000 Lim=0000e739 DPL=3 P NA AVL=0 L=0
005c Trap64 Sel:Off=f000:f000f0a4f000e82e DPL=3 P
0068 VERR_INVALID_SELECTOR
Why has ._Code64 Index 0x28 and not 0x18?

I am grateful for every advice,
Nicky

If you need more Code let me know.
User avatar
iansjack
Member
Member
Posts: 4689
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Use BIOS funcions from long mode ---

Post by iansjack »

You can't use BIOS calls from Long Mode.
Octocontrabass
Member
Member
Posts: 5521
Joined: Mon Mar 25, 2013 7:01 pm

Re: Use BIOS funcions from long mode ---

Post by Octocontrabass »

supernicky wrote:what could be the Problem?
Have you tried running this in Bochs yet? The Bochs log will provide tons of useful information about the CPU state when it crashes; that will be very helpful for figuring out what's going wrong.

If all you want to do is set the video mode, there are other methods:
  • Write a native driver for the video card
  • Set the video mode in the bootloader
  • Run the video card's (legacy or UEFI) PCI option ROM in an emulator
iansjack wrote:You can't use BIOS calls from Long Mode.
Of course you can't. This is switching to real mode first, and then using BIOS calls from real mode.
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: Use BIOS funcions from long mode ---

Post by SpyderTL »

I think you may be missing a few steps. Check out the Real Mode wiki page for a full list.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
rdos
Member
Member
Posts: 3286
Joined: Wed Oct 01, 2008 1:55 pm

Re: Use BIOS funcions from long mode ---

Post by rdos »

It's perfectly possible to call the BIOS (in V86 mode, not real mode) from long mode provided your OS also sets up "shadow" 32-bit protected-mode interrupt handlers. When calling BIOS, you switch the IDT and processor to 32-bit handlers, and then switch to V86 mode. When you return, you switch back the IDT and processor to long mode. I have this feature in my OS, and it works just fine. Microsoft and the Linux community couldn't solve it, but that doesn't mean it can't be done.
Octocontrabass
Member
Member
Posts: 5521
Joined: Mon Mar 25, 2013 7:01 pm

Re: Use BIOS funcions from long mode ---

Post by Octocontrabass »

rdos wrote:Microsoft and the Linux community couldn't solve it, but that doesn't mean it can't be done.
They did solve it. They use an interpreter, instead of switching the CPU mode.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Use BIOS funcions from long mode ---

Post by alexfru »

rdos wrote:It's perfectly possible to call the BIOS (in V86 mode, not real mode) from long mode provided your OS also sets up "shadow" 32-bit protected-mode interrupt handlers. When calling BIOS, you switch the IDT and processor to 32-bit handlers, and then switch to V86 mode. When you return, you switch back the IDT and processor to long mode. I have this feature in my OS, and it works just fine. Microsoft and the Linux community couldn't solve it, but that doesn't mean it can't be done.
Windows gets the necessary drivers, no need for BIOS in most cases. For those odd cases where falling back to BIOS is better than nothing there's an emulator (I'd guess, it was there in one shape or another from the days of Windows NT).

What happens in your system when you go all the way from long mode to v86, do smth in there and then come back? Do you reprogram interrupt handlers? Disable some or all interrupts for many CPU cycles? Change page tables? Invalidate caches (TLB and what not)? Acquire and hold global locks for a long time? IOW, you can do it, but at what cost?
rdos
Member
Member
Posts: 3286
Joined: Wed Oct 01, 2008 1:55 pm

Re: Use BIOS funcions from long mode ---

Post by rdos »

Octocontrabass wrote:
rdos wrote:Microsoft and the Linux community couldn't solve it, but that doesn't mean it can't be done.
They did solve it. They use an interpreter, instead of switching the CPU mode.
That's not a solution.
Octocontrabass
Member
Member
Posts: 5521
Joined: Mon Mar 25, 2013 7:01 pm

Re: Use BIOS funcions from long mode ---

Post by Octocontrabass »

rdos wrote:That's not a solution.
Why not?
rdos
Member
Member
Posts: 3286
Joined: Wed Oct 01, 2008 1:55 pm

Re: Use BIOS funcions from long mode ---

Post by rdos »

alexfru wrote: What happens in your system when you go all the way from long mode to v86, do smth in there and then come back? Do you reprogram interrupt handlers?
No. You only need to switch the IDT register. The only limitation is that all the IRQ-handlers must exist in both 32-bit protected mode form and long mode form. When a new IRQ-handler is added, it must be added to both IDT-tables.
alexfru wrote: Disable some or all interrupts for many CPU cycles? Change page tables? Invalidate caches (TLB and what not)? Acquire and hold global locks for a long time? IOW, you can do it, but at what cost?
No, the only costly operation is to switch mode, which do invalidate the TLB as you need to turn off paging and turn it on again in 32-bit mode (or long mode when you go the other way). There is also a need for a code-stub that is located at a physical address that is mapped to the same linear address where the mode-switching code needs to reside. There is no need for global locks. The switch code itself is linked to the scheduler, and the scheduler knows if a thread is for 64-bit or 32-bit, and would automatically switch between modes when needed. In the current design, 32-bit processes will run in protected mode and 64-bit processes will run in long mode, which is more efficient since 32-bit processes can still use callgates to transfer from usermode to kernel, something that is not supported in compatibility mode within long mode.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Use BIOS funcions from long mode ---

Post by gerryg400 »

rdos originally wrote:It's perfectly possible to call the BIOS (in V86 mode, not real mode) from long mode ....
rdos later wrote:No, the only costly operation is to switch mode, which do invalidate the TLB as you need to turn off paging and turn it on again in 32-bit mode (or long mode when you go the other way). There is also a need for a code-stub that is located at a physical address that is mapped to the same linear address where the mode-switching code needs to reside. There is no need for global locks. The switch code itself is linked to the scheduler, and the scheduler knows if a thread is for 64-bit or 32-bit, and would automatically switch between modes when needed. In the current design, 32-bit processes will run in protected mode and 64-bit processes will run in long mode, which is more efficient since 32-bit processes can still use callgates to transfer from usermode to kernel, something that is not supported in compatibility mode within long mode.
Rdos, it sounds like you are not actually calling the BIOS from long mode at all. Am I missing something?
If a trainstation is where trains stop, what is a workstation ?
rdos
Member
Member
Posts: 3286
Joined: Wed Oct 01, 2008 1:55 pm

Re: Use BIOS funcions from long mode ---

Post by rdos »

gerryg400 wrote:
rdos originally wrote:It's perfectly possible to call the BIOS (in V86 mode, not real mode) from long mode ....
rdos later wrote:No, the only costly operation is to switch mode, which do invalidate the TLB as you need to turn off paging and turn it on again in 32-bit mode (or long mode when you go the other way). There is also a need for a code-stub that is located at a physical address that is mapped to the same linear address where the mode-switching code needs to reside. There is no need for global locks. The switch code itself is linked to the scheduler, and the scheduler knows if a thread is for 64-bit or 32-bit, and would automatically switch between modes when needed. In the current design, 32-bit processes will run in protected mode and 64-bit processes will run in long mode, which is more efficient since 32-bit processes can still use callgates to transfer from usermode to kernel, something that is not supported in compatibility mode within long mode.
Rdos, it sounds like you are not actually calling the BIOS from long mode at all. Am I missing something?
The task that calls the BIOS is 32-bit, so you are partly right. However, the feature to be able to run both long mode applications and call the BIOS without any emulation is present. I think that is the main issue, and the switch takes place even if it is the scheduler that does it.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Use BIOS funcions from long mode ---

Post by gerryg400 »

Rdos, I get it now. Actually I think I recall reading a thread as you were developing this some time ago.
If a trainstation is where trains stop, what is a workstation ?
Post Reply