using vesa mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

using vesa mode

Post by ParaDarkness »

I'm trying to access video memory in a vesa mode...

I switch to graphic mode in real mode (before switch to protected mode) with this code :

Code: Select all

[BITS 16]

VesaInfo db 'VBE2'
times 252 db 0
ModeInfo times 256 db 0
FrameBuffer dd 0

;VesaInfo
VesaInfos : 
SinV  db "VESA"
VE1  db 0
VE2  db 0
PtrFARAscii  dd 0
Perf  dd 0
PtrFARLst  dd 0
NbrChunks  dw 0
Buffer  times 236 db 0

Mode_Info:      
ModeInfo_ModeAttributes      dw   1
ModeInfo_WinAAttributes      db   1
ModeInfo_WinBAttributes      db   1
ModeInfo_WinGranularity      dw   1
ModeInfo_WinSize      dw   1
ModeInfo_WinASegment      dw   1
ModeInfo_WinBSegment      dw   1
ModeInfo_WinFuncPtr      dd   1
ModeInfo_BytesPerScanLine   dw   1
ModeInfo_XResolution      dw   1
ModeInfo_YResolution      dw   1
ModeInfo_XCharSize      db   1
ModeInfo_YCharSize      db   1
ModeInfo_NumberOfPlanes      db   1
ModeInfo_BitsPerPixel      db   1
ModeInfo_NumberOfBanks      db   1
ModeInfo_MemoryModel      db   1
ModeInfo_BankSize      db   1
ModeInfo_NumberOfImagePages   db   1
ModeInfo_Reserved_page     db   1
ModeInfo_RedMaskSize     db   1
ModeInfo_RedMaskPos      db   1
ModeInfo_GreenMaskSize      db   1
ModeInfo_GreenMaskPos      db   1
ModeInfo_BlueMaskSize      db   1
ModeInfo_BlueMaskPos      db   1
ModeInfo_ReservedMaskSize   db   1
ModeInfo_ReservedMaskPos   db   1
ModeInfo_DirectColorModeInfo   db   1
; VBE 2.0 extensions
ModeInfo_PhysBasePtr      dd   1
ModeInfo_OffScreenMemOffset   dd   1
ModeInfo_OffScreenMemSize   dw   1

mov di, VesaInfos
mov ax, 4F00h
int 10h

mov ax, 4F01h
mov di, Mode_Info
mov cx, 4112h
int 10h


mov ax, 4F02h
mov bx, 4118h
int 10h

I'm not sure that the modeInfo and vesaInfo work and i don't know how can i read the framebuffer address in the mode info block but if I try to write in 0xA0000 in protected mode with this code :

Code: Select all

unsigned long *video;

	uDD pix;

	long int i = 0;

	while (i < 1024*768*4) {

		video = (unsigned long *) (0xA0000 + i);

		pix = 0x7FDD4C;

		*video = pix;

		i = i + 3;


}
I have this result :
result
result

I would like to know how I can write in all memory (with lfb? how can I activate it?) and hiw can I read the modeInfo block?

Sorry for my English :oops: , (I speak french)
Milan
Posts: 9
Joined: Sun Jan 01, 2012 7:23 am

Re: using vesa mode

Post by Milan »

Try this code:

Code: Select all

mov   edi,[ModeInfo_PhysBasePtr]
mov   ecx,640*480   
mov   al,0xff	
rep   stosb
and there is put_pixel function in c

Code: Select all

void vesa_put_pixel(uint32_t x, uint32_t y, uint32_t cl)
{
	register char *ptmp;

	if (x < 0 || x > vmi->width || y < 0 || y > vmi->height) return;
	
	x = (x * (vmi->bits_per_pixel >> 3));
	y = (y * vmi->bytes_per_scan_line);
	
	char *asd = (char *)vmi->phys_base_ptr;
	ptmp = &asd[x+y];
	ptmp[0] = cl & 0xff;
	ptmp[1] = (cl>>8) & 0xff;
	ptmp[2] = (cl>>16) & 0xff;
}

ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

Re: using vesa mode

Post by ParaDarkness »

What do the first code? :s

It puts 255 in ModeInfo_PhysBasePtr 640*480 Times?
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: using vesa mode

Post by DavidCooper »

Have you got the proper documentation on it?

http://www.jnode.org/uploads/vbe3_0.pdf

If so, the answers are in there. On page 31:-
Mandatory information for VBE 2.0 and above
PhysBaseptr dd ? ; physical address for flat memory frame buffer
It's a while since I wrote my VESA code, but I think from memory that that's where you find the linear framebuffer address. Unfortunately the offsets aren't stated, so you need to count it out to find out where this appears in the table - it looks from my code as if it's 40 bytes in (that's a decimal distance), and it's a direct 32-bit physical address.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

Re: using vesa mode

Post by ParaDarkness »

There is my problem!
I know that the adress is the 40th byte in the table but i don't know how can I get the adress of the table after switching in protected mode (in C or with "asm()" function in english?
Have you an example code that makes this thing?

Thanks for your link :)
Milan
Posts: 9
Joined: Sun Jan 01, 2012 7:23 am

Re: using vesa mode

Post by Milan »

In protected mode you can't use real mode interruprs...
Only way to do that is to use grub to get address of lfb or you can implement http://wiki.osdev.org/Virtual_Monitor and then you can use bios interrupts...
ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

Re: using vesa mode

Post by ParaDarkness »

what is the easiest way :
Implement the virtual mode or switch to graphic mode in pmode? (I don't want to use grub)

thanks again :)
Milan
Posts: 9
Joined: Sun Jan 01, 2012 7:23 am

Re: using vesa mode

Post by Milan »

Implement Virtual Monitor if you want to have bios interrupts in protected mode...
With this you can switch to graphic mode and from graphic to text mode, read disk etc.
But implementing the Virtual Monitor can be very hard...

I see you have successfully switched to graphic mode.
You must choose graphic or text mode if you don't have possibility to use interrupts im pm.
ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

Re: using vesa mode

Post by ParaDarkness »

I did'nt need bios interrupts in protected mode, I don't want to switch between graphic or text mode multiple times.

I just want to find the lfb in pm, I can't believe that it is not possible.

I use this code to change to pm after switching to graphic mode (in asm):

Code: Select all

mov di, VesaInfos
mov ax, 4F00h
int 10h

mov ax, 4F01h
mov di, Mode_Info
mov cx, 4112h
int 10h


mov ax, 4F02h
mov bx, 4118h
int 10h


; pmode
    cli
    
    mov eax, cr0
    or  ax, 1
    mov cr0, eax        

    jmp next
next:
    mov ax, 0x10        
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov es, ax
    mov ss, ax
    mov esp, 0x9F000    
    
   
    jmp dword 0x8:_next    ; reinitialise le segment de code

[BITS 32]
_next:

and the main kernel in C :

Code: Select all

int main(void)

{

	//Kernel content ...

	//and the test to put pixels

	unsigned long *video;

	uDD pix;

	long int i = 0;

	

	while (i < 1024*768*4) {

		video = (unsigned long *) (0xA0000 + i);

		pix = 0x7FDD4C;

		*video = pix;



		i = i + 3;

}
Isn't it possible to get the address with arguments in main function? or with a descriptor in gdt?



And I have another question : Even if I have activate the lfb, why I still can use 0xA0000 to put pixels to screen? isn't it different address?
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: using vesa mode

Post by Griwes »

ParaDarkness wrote:Isn't it possible to get the address with arguments in main function? or with a descriptor in gdt?
You really need to read about calling conventions.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
ParaDarkness
Posts: 7
Joined: Sun May 06, 2012 12:07 pm

Re: using vesa mode

Post by ParaDarkness »

can you explain my error? :s
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: using vesa mode

Post by bluemoon »

ParaDarkness wrote:Isn't it possible to get the address with arguments in main function?
Yes. At least two usual way:
1. Pass information block with predefined absolute address, then you access it with

Code: Select all

BOOTDATA* boot = (BOOTDATA*)(0x1234); // replace this with your choice of address, make sure it's safe to use
2. Pass on stack/registers, check your ABI reference.

On the other hand, you may query the LFB address in pm with PCI configuration space if that is an PCI card, I assume it's on BAR#0.

ParaDarkness wrote:And I have another question : Even if I have activate the lfb, why I still can use 0xA0000 to put pixels to screen? isn't it different address?
Most card support one mode at a time. when activated LFB, A000 is not used. One exception is qemu(and probably other emu) it will handle both interface at the same time.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: using vesa mode

Post by DavidCooper »

ParaDarkness wrote:I just want to find the lfb in pm, I can't believe that it is not possible.
Why not just collect it the easy way while you're still in real mode? All you need to do is add a little code after calling the Mode Info function:-
mov di, VesaInfos
mov ax, 4F00h
int 10h

mov ax, 4F01h
mov di, Mode_Info
mov cx, 4112h
int 10h

; Add some code in here to read the address in the table and store
; it somewhere where you can find it later once in protected mode.
; (or make sure you don't overwrite the table so that you can read it
; later on while in protected mode)


mov ax, 4F02h
mov bx, 4118h
int 10h
As it stands, you're calling the Mode Info function for nothing - you aren't doing anything with the table which it returns to you at ES:DI, the 40th to 43rd bytes of which you ought to be collecting as it's the linear framebuffer address. It looks as if you've just hacked code out of a tutorial without understanding it, or maybe more than one tutorial, because your next step appears to be to set a different mode from the one you just asked for information about. Your code is also dangerous as you aren't checking to see if the mode is actually available, so it could potentially blow up a monitor which doesn't support it.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: using vesa mode

Post by Combuster »

bluemoon wrote:
ParaDarkness wrote:And I have another question : Even if I have activate the lfb, why I still can use 0xA0000 to put pixels to screen? isn't it different address?
Most card support one mode at a time. when activated LFB, A000 is not used. One exception is qemu(and probably other emu) it will handle both interface at the same time.
Actually, from most of the live hardware I've seen the LFB can work simultaneously with the legacy window. Specifically, the lfb always works and the legacy addresses can be turned off - something the bios might happen to do or not.

Relying on any of that behaviour for VBE is obviously bad practice, but it's a useful thing when it comes to custom drivers :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: using vesa mode

Post by DavidCooper »

A few more hints:-
mov di, VesaInfos
mov ax, 4F00h
int 10h

; You've just asked the BIOS for a list of available modes, and by exploring the table at
; ES:DI you can find the address to read them from. Next step should be to call the
; function below for each mode in the list of available modes and to look for the one(s)
; that you want to use. Some of the modes in the list may not actually be valid, so you
; need to check carefully the results you get back from the function below.

mov ax, 4F01h
mov di, Mode_Info
mov cx, 4112h
int 10h

; CX should contain a mode number as found in the list of screen modes returned by the
; previous function - you don't need the 4 in your 4112h at this point as it's only added
; when setting a mode with the function below, its purpose being to set it to use the
; linear framebuffer.

mov ax, 4F02h
mov bx, 4118h
int 10h
Read the VESA documentation carefully and only call functions when you actually understand why you're calling them.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Post Reply