0

Earlier I was trying to add the parameter nomodeset to /etc/default/grub for a different issue related to abnormal ways my laptop used to boot. It didn't work well. So I pressed 'e' in the grub menu to remove it. After logging in I changed back the grub file and updated it.

However now when I restart, it stops at a blank screen with a blinking cursor. I rebooted it and pressed 'e' in the grub menu. Next I changed

[...]ro quiet splash $vt_handoff to [...]ro $vt_handoff quiet splash

and then pressed F10 and it loaded fine, with lesser graphics than, before using nomodeset. Problem is I have to do this everytime I boot. How do I make this last change permanent?

PS: My laptop was and is prone to crashing while playing videos on Ubuntu 18.04 and now on 19.04(its on dual boot with 18 and 19). In 18 I used to reboot and the system worked fine after that however for 19 it gets stuck right after selecting the Ubuntu 19 on grub menu(after a crash, on playing videos), and I have to reinstall it. I know this is most probably not the right way to do things and suggestions are welcome.

Edit1: As mentioned in How do I add a kernel boot parameter? I am aware how to add new parameters like nomodeset in grub file and hence change kernel commands permanently, however $vt_handoff is already present in the kernel commands, but not in the grub file hence my confusion on how to proceed in either removing it or changing its order in the parameter list?

2
  • 4
    Possible duplicate of How do I add a kernel boot parameter?
    – guiverc
    Oct 1, 2019 at 11:24
  • @guiverc I am aware that we can make a few permanent changes as given in the answer but $vt_handoff was not present in the grub file when I opened it even though I could see it after pressing 'e' in the kernel parameters. Should I edit and mention this in the question?
    – NUMBART
    Oct 1, 2019 at 12:58

1 Answer 1

0

The source code

The file which handles the aspect of generating the GRUB configuration you're interested in modifying is /etc/grub.d/10_linux and the $vt_handoff element of the kernel command line is processed twice within its code (as of the version I currently have installed, v2.04).

  1. First (and more relevant to your desired outcome, since this is where the placement of the $vt_handoff variable is handled) in the nested if block on lines 154-160:

    ...
    if [ "$vt_handoff" = 1 ]; then
      for word in $GRUB_CMDLINE_LINUX_DEFAULT; do
        if [ "$word" = splash ]; then
          GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \$vt_handoff"
        fi
      done
    fi
    ...
    
  2. Then again in the nested if block on lines 348-358, where the decision of what value to set for the $vt_handoff variable is made:

    ...
     set gfxpayload="${1}"
    EOF
    if [ "$vt_handoff" = 1 ]; then
      cat << 'EOF'
     if [ "${1}" = "keep" ]; then
             set vt_handoff=vt.handoff=7
     else
             set vt_handoff=
     fi
    EOF
    fi
    ...
    

Analysis

In the first instance shown above, we see the Dash shell interpreter concatenating the value of the $GRUB_CMDLINE_LINUX_DEFAULT sourced from the /etc/default/grub file with the $vt_handoff variable name¹. The code as written chooses to append the latter to the former, but you could make it prepend instead as easily as reversing the position of the elements in the reassigned $GRUB_CMDLINE_LINUX_DEFAULT variable on line 157. It would then look like this:

...
    if [ "$word" = splash ]; then
      GRUB_CMDLINE_LINUX_DEFAULT="\$vt_handoff $GRUB_CMDLINE_LINUX_DEFAULT"
    fi
...

That is certainly the most direct way to effect the outcome you seek, though it falls short of my own definition of a "permanent" solution, because that file will be overwritten every time your system installs an update to GRUB. In light of that, I'd consider this more accurately a "persistent" solution as it will indeed survive from one power cycle to another for the lifetime of any given GRUB package release but no further.

Potential permanent solutions

Using the value of GRUB_GFXPAYLOAD_LINUX

As it's most often advisable to "work with" systems as they are (when possible), rather than "working against" them, I see one potential means of doing so residing in the second code snippet from the /etc/grub.d/10_linux file shown above. Specifically, we see the script logic evaluating a positional parameter and only activating the $vt_handoff variable if its value is 'keep'. The parameter in question (through several levels of shell logic obfuscation) is, in fact, the value for GRUB_GFXPAYLOAD_LINUX that is supplied in /etc/default/grub, a file which is intended to be modified by end users and thus survives package updates unscathed.

Only if GRUB_GFXPAYLOAD_LINUX is set to keep does the $vt_handoff variable have a value set. According to the GNU GRUB Manual, while the most common choices for GRUB_GFXPAYLOAD_LINUX are keep (your current setting) and text (obviously not suited to your use case), it may also be set to any valid value for gfxmode. This means that you could change it to auto or, even better, to the precise width✕height default screen resolution selected by your system's BIOS/EFI (which is what keep is meant to be the equivalent of) which can be discovered with the videoinfo command within the bootloader itself (and also, in most instances, with the sudo fbset -s command in the terminal after your system has booted).

This offers the advantage of leaving your current boot process unchanged EXCEPT for removing the value assignment for $vt_handoff, and even though you'll still see it at the end of the kernel command line when pressing e at the bootloader menu entry, since it now has no value it won't in fact be passed to the kernel. You can verify this to be the case by entering cat /proc/cmdline in the terminal after changing GRUB_GFXPAYLOAD_LINUX and restarting your computer.

The final step is to restore the value that GRUB ultimately replaces $vt_handoff with to your kernel command line, this time in the location YOU want. In the second code snippet above we see that when GRUB_GFXPAYLOAD_LINUX is set to keep that $vt_handoff is given the value vt.handoff=7, and that part in bold is what you need to add in front of your other kernel command line settings assigned to GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub. Once again, you can verify that all is as expected with cat /proc/cmdline after making the change and rebooting. This is how I would approach your issue myself if confronted with it.

GRUB Customizer

An alternative to editing the /etc/default/grub file directly is to install and use GRUB Customizer, which exposes these same variables in a thoughtful GUI layout. Installing it is simple if you're using a recent release (19.10 "Eoan Ermine" or later) of Ubuntu or one of its flavors like Kubuntu with sudo apt install grub-customizer in the terminal. It has an Advanced Settings dialog (shown below) that exposes the same values you need to modify in /etc/default/grub and keeps backups of modified files in case you need to revert the changes at some later time.

GRUB Customizer screenshot


¹ It should be noted that throughout the GRUB configuration process herein examined, all references to $vt_handoff are instances of the variable name itself and not the more commonly seen parameter expansion/substitution behavior performed by *NIX shells of various and sundry flavors. The expected behavior of the Ubuntu variant of the GRUB framework is that the references to it will remain as the variable name in all instances of the kernel command line leading up to and including within the grub.cfg file which is the end result of the initial grub mkconfig process and each subsequent update-grub invocation. The value for the variable is defined within the GRUB configuration file as well and the bootloader itself performs the substitution during each boot cycle. That is why it is often seen escaped as \$vt_handoff in the code snippets above as that prevents any premature substitution of the variable name for its value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .