grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] efi: Set text-mode console resolution to maximum supported


From: Glenn Washburn
Subject: Re: [PATCH] efi: Set text-mode console resolution to maximum supported
Date: Fri, 6 May 2022 19:59:15 -0500

Hi Gerd,

Thanks for taking a look at the patch.

On Fri, 6 May 2022 12:39:52 +0200
Gerd Hoffmann <kraxel@redhat.com> wrote:

>   Hi,
> 
> > On some buggy EFI firmwares, GRUB is started with the console resolution
> > set to the maximum but the output console EFI object has the mode set as
> > 0, which is the minimum supported mode of 80x25 characters. This causes
> > strange behavior at the GRUB shell where output can fill the screen, but
> > the prompt is at line 80 in the middle of the screen.
> 
> This behavior might not be ideal, but it's clearly within the specs and
> not buggy.  What firmware do you talk about btw?

I have only a cursory understanding of the spec and fairly new to EFI.
Could you elaborate on which spec(s) and where this behavior is
described? 

Trying to make sense of your assertion, my inexperienced reading of
some relevant (but perhaps not all relevant) portions of the spec lead
me to conclude that this behavior may not violate the spec because the
spec isn't very clear on this. For instance, looking at the UEFI 2.9
version of the spec in section 12.4 on page 454 in table 12-4 "EFI
Cursor Location/Advance Rules" there is reference to "bottom of the
display". What is the display? Does being in a particular "mode" of
cols x rows dimensions encompass all the pixels of the physical screen?
If it doesn't, is the display all the pixels or just the ones being
used for the columns x rows character output of a particular mode?
Suppose that the display is just the pixels used by the particular
mode, then this firmware violates the spec by allowing LF characters to
advance the cursor past the end of the "display" and allow writing of
GRUB generated output there. On the other hand, if the "display" is all
pixels on the screen and the text mode may be a sub-rectangle of that,
then OutputString allows writing outside of the columns x rows of a
given mode, ie for the purposes of the cursor advance rules the firmware
is considering the whole screen as the display but SetCursorPosition()
is limited to a top-left section of the screen. So what would be the
point of having that behavior? Just to limit SetCursorPosition() to a
subset of the screen? May be you can enlighten me on the wisdom of
the spec here (are there some types of hardware displays where this is
useful?).

Another place the spec isn't clear is in section 2.4 at the end of page
450, it says "If the output device is not in a valid text mode at the
time of the EFI_BOOT_SERVICES.HandleProtocol() call, the device is to
indicate that its CurrentMode is –1". But nowhere in the spec is
"CurrentMode" defined and a search of the PDF shows that as the only
instance of that string. If I were a betting person, I'd put my money
on "CurrentMode" being the "Mode" member of the struct defined above, or
ConsoleOut->Mode->Mode. It seems to me this is a bug/ambiguity in the
spec.

Looking at the last paragraph on 450 and assuming my guess above as to
the meaning of "CurrentMode", which I could be wrong about, I considered
that the paragraph could be used to justify this behavior. However,
ConsoleOut->Mode->Mode == 0, not -1. So the console should be in 80x25
mode (which is kinda is). Its not clear to me that this is relevant
either because GRUB only ever calls EFI_BOOT_SERVICES.HandleProtocol()
on ia64 (not my architecture). So how does GRUB know whether ConsoleOut
is in a valid mode or not? Do we need to call HandleProtocol() on the
ConsoleOutHandle to trigger this? I would think not since ConOut is
support to already be a handle to this interface.

To be more verbose as to the issue I'm seeing, the computer boots to
GRUB with the display resolution at native, 1920x1080, but only uses
what appears to be the top left 800x600 pixels for the 80x25 text mode
_initially_. So running "lsmod", for instance, uses the full height of
the screen when outputing text and the screen starts scrolling at the
bottom of the screen. But when it finished the GRUB shell prompt is
about midway down from the top and typing overwrites some of lsmod
output. Then further output gets mangled with the previous output.
Going to a grub menu interface clears the screen, so I end up having to
exit the shell and re-enter it to get a non-mangled display. A video of
this would be worth million words.

If I set the mode to some other mode and then back to mode 0, which is
the mode its claims to start up in, then there appears to be a screen
resolution change to 640x480 with accompanying giant font with the
screen centered now instead of in the top left corner of the display.
I've yet to figure out a way to get the display back into the weird,
spec-compliant, mode that it starts out in. So if this is some
desirable mode, why can't I get back in to it? And why does it only
happen for default boot entries?

In my case, my firmware behavior seems like a clear bug, I have a hard
time believing that HP firmware devs would chose this behavior. Whether
it violates the spec or not is a separate issue (there can be bugs that
do not violate the spec). I've only seen this undesirable behavior only
manifest when booting a default boot entry. When I choose via the
firmware boot selection screen an EFI app to run and run the same GRUB
EFI app that exhibits the issue when run from default boot selection,
this does not manifest. I get the same behavior for the EDK2 EFI shell
app when it is used as the default boot app. Whether its called a bug
or spec-compliant mis-feature, the important point is that this is
undesirable behavior for GRUB users.

I considered that this may have to do with ConsoleOut and StandardError
being in different modes. It seems like this might be caused by
StandardError being in the maximum mode and ConsoleOut being in the
minimum mode, but it turns out that EFI_BOOT_SERVICES.StdErr is NULL.
This seems to violate the descriptions of StandardErrorHandle
and StdErr in section 4.3, page 95. Changing the mode of ConsoleOut and
not StandardError does nothing but improve the display out.

I'm also curious if anyone has seen issues with the largest area text
mode mode. Is there a problem with doing that this patch intends?
Ultimately, I think it would be nice to have a key sequence that
raises and lowers the mode so that if the largest mode is not usable
for some reason, the user has a blind way out. I've created another
patch to add a command called efitextmode, which is very similar to the
EFI Shell's "mode" command. But that doesn't solve the issue just
mentioned.

The firmware I'm looking at is from Hewlett-Packard for a Zbook G2 15.

> > +  /* Set text-mode resolution to maximum supported */
> > +  o = grub_efi_system_table->con_out;
> > +  for (i=0, columns_max=0, rows_max=0, mode_max=0; i < o->mode->max_mode; 
> > i++)
> > +    if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, o->mode->mode,
> > +                                       &columns, &rows)
> > +       && (columns_max * rows_max) < (columns * rows))
> > +      mode_max = i;
> > +
> > +  efi_call_2 (o->set_mode, o, mode_max);
> 
> This is buggy.  It find the last entry in the mode list.  Which works by
> pure luck because that happens to be the entry you want have in case the
> list is sorted.

Yep, thanks, there's a reason that coding while driving is illegal in
many localities.

Glenn



reply via email to

[Prev in Thread] Current Thread [Next in Thread]