GOP: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
m (1 revision imported: import new edits from osdev.org wiki)
mNo edit summary
 
Line 8: Line 8:
=== Detecting GOP ===
=== Detecting GOP ===
As with other UEFI protocols, you have to locate a structure with the function pointers first using the protocol's GUID.
As with other UEFI protocols, you have to locate a structure with the function pointers first using the protocol's GUID.
<source lang="c">
<syntaxhighlight lang="c">
EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
Line 15: Line 15:
if(EFI_ERROR(status))
if(EFI_ERROR(status))
PrintLn(L"Unable to locate GOP");
PrintLn(L"Unable to locate GOP");
</syntaxhighlight>
</source>
GOP is the default protocol, so you should be able to locate it on all UEFI firmware. It can probably only fail if you're on an old EFI (pre-UEFI) machine, like an Itanium-based computer or a Mac released before 2009.
GOP is the default protocol, so you should be able to locate it on all UEFI firmware. It can probably only fail if you're on an old EFI (pre-UEFI) machine, like an Itanium-based computer or a Mac released before 2009.


If your kernel uses GRUB, you need to insert a module called "all_video" before loading the kernel to add UEFI GOP compatibility. Not doing so will display a message saying "WARNING: no console will be available to OS".
If your kernel uses GRUB, you need to insert a module called "all_video" before loading the kernel to add UEFI GOP compatibility. Not doing so will display a message saying "WARNING: no console will be available to OS".
<source lang="c">
<syntaxhighlight lang="c">
insmod all_video
insmod all_video


Line 26: Line 26:
boot
boot
}
}
</syntaxhighlight>
</source>


=== Get the Current Mode ===
=== Get the Current Mode ===
In order to get the mode code for the current video mode, you must set the mode as well to circumvent some buggy UEFI firmware. Otherwise this is done using the QueryMode function, and then gop->Mode->Mode will contain the code.
In order to get the mode code for the current video mode, you must set the mode as well to circumvent some buggy UEFI firmware. Otherwise this is done using the QueryMode function, and then gop->Mode->Mode will contain the code.
<source lang="c">
<syntaxhighlight lang="c">
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
UINTN SizeOfInfo, numModes, nativeMode;
UINTN SizeOfInfo, numModes, nativeMode;
Line 44: Line 44:
numModes = gop->Mode->MaxMode;
numModes = gop->Mode->MaxMode;
}
}
</syntaxhighlight>
</source>


=== Query Available Video Modes ===
=== Query Available Video Modes ===
Similarly to VESA, there's no standard mode codes, rather you have a function to query the available modes. Now you know how many modes there are (numModes above), and which one is currently set (nativeMode). You can iterate on the modes and query the information structure for each:
Similarly to VESA, there's no standard mode codes, rather you have a function to query the available modes. Now you know how many modes there are (numModes above), and which one is currently set (nativeMode). You can iterate on the modes and query the information structure for each:
<source lang="c">
<syntaxhighlight lang="c">
for (i = 0; i < numModes; i++) {
for (i = 0; i < numModes; i++) {
status = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo, &info);
status = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo, &info);
Line 59: Line 59:
);
);
}
}
</syntaxhighlight>
</source>


=== Set Video Mode and Get the Framebuffer ===
=== Set Video Mode and Get the Framebuffer ===
This is pretty easy. The mode argument is between 0 and numModes.
This is pretty easy. The mode argument is between 0 and numModes.
<source lang="c">
<syntaxhighlight lang="c">
status = uefi_call_wrapper(gop->SetMode, 2, gop, mode);
status = uefi_call_wrapper(gop->SetMode, 2, gop, mode);
if(EFI_ERROR(status)) {
if(EFI_ERROR(status)) {
Line 77: Line 77:
);
);
}
}
</syntaxhighlight>
</source>
To get the same value as scanline in VESA (also commonly called pitch in many graphics libraries), you have to multiply PixelsPerScanLine by the number of bytes per pixel. That can be detected by examining the gop->Mode->Info->PixelFormat field. For example with 32 bit packed pixel formats,
To get the same value as scanline in VESA (also commonly called pitch in many graphics libraries), you have to multiply PixelsPerScanLine by the number of bytes per pixel. That can be detected by examining the gop->Mode->Info->PixelFormat field. For example with 32 bit packed pixel formats,
<source lang="c">
<syntaxhighlight lang="c">
pitch = 4 * gop->Mode->Info->PixelsPerScanLine;
pitch = 4 * gop->Mode->Info->PixelsPerScanLine;
</syntaxhighlight>
</source>


=== Plotting Pixels ===
=== Plotting Pixels ===
Line 87: Line 87:
Now you can use the returned framebuffer exactly the same way as you would with VESA, there's absolutely no difference.
Now you can use the returned framebuffer exactly the same way as you would with VESA, there's absolutely no difference.
To calculate the offset for an (X,Y) coordinate on screen, do pitch*Y+pixelbytes*X. For example for 32 bit true-color (where pixelbytes is 4):
To calculate the offset for an (X,Y) coordinate on screen, do pitch*Y+pixelbytes*X. For example for 32 bit true-color (where pixelbytes is 4):
<source lang="c">
<syntaxhighlight lang="c">
static inline void PlotPixel_32bpp(int x, int y, uint32_t pixel)
static inline void PlotPixel_32bpp(int x, int y, uint32_t pixel)
{
{
*((uint32_t*)(gop->Mode->FrameBufferBase + 4 * gop->Mode->Info->PixelsPerScanLine * y + 4 * x)) = pixel;
*((uint32_t*)(gop->Mode->FrameBufferBase + 4 * gop->Mode->Info->PixelsPerScanLine * y + 4 * x)) = pixel;
}
}
</syntaxhighlight>
</source>
For drawing characters, you can use the same method described in [[VGA Fonts]].
For drawing characters, you can use the same method described in [[VGA Fonts]].